Exposejoint of gltf animation

Hi,

Im trying to get the absolute transforms of a gltf animation using exposejoint, to apply them to a ragdoll in pybullet.
The ragdoll is basically a copy of my original model, however in the ragdoll, all rotations are the identity quaternion [0.0, 0.0, 0.0, 1.0] (in my coordinate system up) by default in tpose, whereas if i look at the original gltf in blender, i see that the bones actually follow the character model in tpose.
I figured i would apply the inverse of the rest pose quats to nullify their impact on the animation.

Ive been bashing my head into finding the correct conversion formula for about 2 days, to get the absolute quaternions from gltf into pybullet, and i still have not succeeded. The truth is, i have no idea how to actually get the gltfs rest pose quats.
I tried so far to simply get exposeJoints quats before calling a actor.pose and getJointTransform(“modelRoot”, joint.name).
Where do i find the rest pose bone rotations in order to apply its inverse to the animations rotations?
Or broader, how do i get the models animation relative to my own rest pose?

(Also, has the gltf issue with rotated axes been fixed…? I saw it last mentioned in 2023. It seems the number of possible formulas is increasing exponentially the more “possible” fixes and variables are found or required. I just really need a reality check to stop my head from exploding.)

Hmm… After calling “actor.pose”, have you tried calling “actor.update(force = True)” in order to, well, force it to update before getting the joint quaternions?

Yes of course

Okay, in that case…

What sort of values do you get if you simply call “getQuat()” on the joints that you expose…? (When the Actor is un-posed, simply as initially loaded.)

(Also, by the way, I just noticed that you’re new here! Welcome! I hope that you find your time on the forums to be positive! :slight_smile: )

Oh thanks, im familiar with the forums. Im just a bit hesitant to sign up for places :slight_smile:

The value i get using:

dummy = model.expose_joint(None, "modelRoot", "RightForeArm")
print(np.array(dummy.getQuat())[[1, 2, 3, 0]])) # I need xyzw

before setting an animation frame is: [ 0.02865839 -0.68641067 0.09499028 0.72041368]

The value when i load pose at frame 0 using:

model.pose(anim_name, i)
model.update(force=True)

is [ 0.46237352 -0.454389 0.43160587 0.62726209].

They are close, but not the same.
Using

np.array(model.getJointTransform("modelRoot", "RightForeArm"))[:3, :3]

and converting that to a quaternion results in: [ 0.03357696 -0.04598601 -0.00154647 0.99837642]

(The armature in blender seems to be rotated forwards by 90 degrees btw. In case that solves some confusion. Im using a mixamo model so it came like this.)

That’s fair! :slight_smile:

I would guess that these would be the values to use, as they should represent the values before any changes have been made to the model, and thus the “resting” values.

Do you mean that you want the axis and angle of rotation? If so, then I don’t think that that’s what you get by default from a Quat–by default, it outputs as (a), i, j, and k, I believe.

To get axis-and-angle, look to the “getAxis” and “getAngle”/“getAngleRad” methods.

oh yeah dont worry about the xyzw. alternatively i could say i need ijkr*

Thanks! That will narrow it down some.
Any idea what np.array(model.getJointTransform("modelRoot", "RightForeArm"))[:3, :3] actually returns then?

It seems to resolve into joint.getDefaultValue(), but i cannot find documentation as to what that is meant to be.

That I’m afraid that I don’t know, offhand. The manual doesn’t seem to detail it, and I don’t think that it’s something that I’ve worked with. :/

Perhaps another forum-member might know better!

Ahh unfortunate, but i might not need to know. Thanks for your help! Should i leave the question as unresolved for now, in case someone wants to have a crack at it?

1 Like

I’d say so! Indeed, it’s not solved yet, after all!