I am trying to match the pose of a PhysicalBone3D to its corresponding bone from another identical skeleton that plays animation using physics forces. It seemed to me that the logical way to do this would be to use the AngularSpringEquilibriumPoint parameters in the physics_process of a custom Generic6DofJoint3D script, but I just simply can’t figure out exactly what coordinate space this parameter is in as there’s little to no documentation on it.
What i’m doing currently is taking the difference of the skeletal bone’s rest and its current pose:
I’ve been poking at this for months and honestly just haven’t been able to figure out what the equilibrium point is supposed to be relative to or what i’m missing here in my math. This works as you would expect when the animation pose is exactly at rest (the joint motors keep the ragdoll in its reference pose), but when the bones rotate they rotate on the wrong axis, or sometimes flipped in the wrong direction. I’ve tried looking at jolts source code but everything’s so abstracted and muddied by having to interface with the engine.
Did you ever figure this out? I’m in the same boat. I can’t find any interpretation of values to feed in that seem to create a target rotation.
Assuming we have a target rotation (basis); if we decompose it to euler angles, I would naively expect that feeding the euler angles into each axes spring equilibrium would cause the joint to converge on that basis, but that’s not what happens. I can’t find any rhyme or reason to what does happen. I’ve tried every decomposition of euler angles available, and also negating all combinations of components for good measure and none of them match what the springs move the joint into.
They work fine kinda individaully. If I set an equilibrium on only one axis of some nice neat value like 90’, the bodies rotate correctly. As soon as I started working in 2 or 3 axes at once, it just all goes out the window.
func _cheese_spring_equilibrium(joint:Generic6DOFJoint3D ,target_transform:Transform3D):
# only works if the joint is not parented to anything with a transform
var _node_b_path = joint.node_b
var _node_b = get_node(_node_b_path)
joint.node_b = ""
#remove the parent here if it has one that is not static.
#parent.remove_child(joint)
# move dist_rb to their target transform
var original_transform = _node_b.global_transform
_node_b.global_transform = target_transform
# reactivate the spring
joint.node_b = _node_b_path
#parent.add_child(anchor_joint)
# set their transform back to wehre they were to set the fake equilibrium
_node_b.global_transform = original_transform
pass
I honestly fear that i have to come back to this once again, as i just can not get my head wrapped around those equilibriums, they just keep breaking when i want to set all the values, they behave nothing like eulers or quaternions