IK (inverse kinematics) on GLB mesh - x is negated

I’m trying out IK on GLB meshes. It seems to work ok except for one problem. The movement in the x-axis seems to be negated. I’ve checked the mesh in Blender and both mesh and armature are at 0.
Here is my playground https://playground.babylonjs.com/#K0F0FR#1

Does anyone know how to fix the motion in the x-axis?

1 Like

The implementation is all based on this thread BABYLON.BoneIKController With GLTF Mesh

I wonder if @mrlooi or @MackeyK24 could spot it here : Add IK support for linked transform nodes by sebavan · Pull Request #11017 · BabylonJS/Babylon.js · GitHub

I they have no idea, I ll take a deeper look

it sounds related to the scale -1 and right handed system @bghgary let me know if you have a clue looking into the previous PR.

Also maybe it needs some constraints ? I am so n00b with IK it is scary…

@adam maybe you have a quick idea ?

@ozRocker as a workaround it seems to be ok with scene.useRightHandedSystem = true;

1 Like

I’m guessing (since I don’t know this IK code at all) that the absolute transform for the transform nodes should stop at the glTF root. When constructing the bones for the skeleton in the glTF loader, this is what happens for the bones as well. Otherwise the root node transform (right-hand to left-hand conversion, -X) will be applied twice. This is only a guess.

yes this does work, unfortunately I cannot use that when incorporating the IK avatar into an existing scene that relies on the left handed system.

I guess I could do something like this as a workaround https://playground.babylonjs.com/#K0F0FR#5 Basically having a “negated” target mesh which follows the target mesh but with negated X position and get IK bone to follow that instead, just need to update the negated target every time the original target moves

1 Like

Fix incoming in the next nightly :wink: the only change on the playground you shared would be to pass the correct avatar into the IK basically skeleton.meshOverride https://playground.babylonjs.com/#K0F0FR#6

(will work in an hour, once deployed)

I noticed something else strange. It looks like the whole arm is moving up and down slightly, which it shouldn’t 'cos the target has the same Y position the whole time. So something is not quite right there.

It does not on the latest ??? or at least I am not seeing it :slight_smile:

Um, I do not think this is a problem with the IK, yet. You need to add a poleTargetBone option. I use my own custom skeleton, not one of MH’s. The bone I pick for pole target is always the parent of the control bone. You can also specify a poleTargetMesh as an alternative, but I abandoned that. There is already a parent bone, so nothing to create or pose.

The next problem is you need to initially place the targetMesh at the end of 2nd IK bone in the pair. If you then add a PointerDragBehavior, see https://www.babylonjs-playground.com/#VSURBJ#2, then you can actually pose the thing much easier. As soon as the mesh is too far away for the end of the arm to reach, it gets much more difficult to work with.

To really get full control, you also should be able to edit these properties on the controller:

  • IK Pole Angle (± PI). This adjusts the location of the elbow / knee joint, and fixes weird shoulders.
  • The Yaw, Pitch & Roll adjusts (± PI). These rotate the bone down from the 2nd IK bone (wrist / ankle). I had been using a look bone controller to control those.

Actually these 3 adjusts are far superior to a look controller, anyway. You can have your wrist looking at something, but not be rotated as desired in other respects. I have very tight requirements for the wrist, so I added these, and that’s when I figured out that the look controller could be ditched, but have not done that yet.

Here is my editor. I use sliders for the adjustments. You might use a gizmo for all but the pole angle instead, but I am modeling in meters for XR, and gizmos are not ideal. I do use a gizmo for my custom IK root bone controller, though. Its gizmo only shows when the root bone target mesh is the currently selected target mesh. The Selected mesh is the one with the orange highlight layer (left arm target mesh in pic). Ignore the red squares. They are look control target meshes which have not been deleted yet.

Finally, coming from blender, I also had to add the option bendAxis: BABYLON.Vector3.Left(). Cannot remember what that fixed. Do not have the time to undo to find out. You may not need this.


Its all good @sebavan fixed it. It works perfectly now https://playground.babylonjs.com/#K0F0FR#7 I know I should be adding pole targets, but I assume IK should also work without it but with the possibility the joint bends the wrong way.

@JCPalmer do you know what’s going on here? https://playground.babylonjs.com/#K0F0FR#8 The left arm has a twisted shoulder. If I change pole angle to untwist then the elbow goes the wrong way. It should work using the clavicle as the pole target right?

It works in my setup. You will see a Flip Library button on my scene print. I have one character where they have over 30 mirror poses. It made sense to figure out how to only make the 30, and just make the library of poses for the other arm in code. It allowed me to not fear doing stuff over, since only one side needed to be done. With the getting rid of the look controller, things will need need to once again be re-done, so I have gotten a lot of use out of it.

For my setup, I have a class IK_Pose. There is a method called FlipPose, which creates an equivalent pose for the other limb:

public flipPose(library : SkeletonPoseLibrary) : IK_Pose {
    const targetPosFlipped = this.targetPosition.clone();
    targetPosFlipped.x *= -1;

    const ikPoleAngleFlipped = Math.PI - this.ikPoleAngle;

    const yawPitchRollFlipped = this.lookAtYawPitchRoll.clone();
    yawPitchRollFlipped.x *= -1;
    yawPitchRollFlipped.z *= -1;

    return new IK_Pose(this.name, library, targetPosFlipped, ikPoleAngleFlipped, yawPitchRollFlipped);

If Math.PI - this.ikPoleAngle does not work, use your sliders to find out the right angle and back into your relationship for your case. That’s how I figured this stuff out.

Also, I have just looked at my code, and found that the adjusts are to the look controller, so I WILL NOT be getting rid of those. My code base is getting pretty big, and I have been working in audio for months now. Will get around to editing that earlier post.

I’m struggling to understand how to incorporate this. Are you changing the properties of the BoneIKController? I can’t see where I can change yaw, pitch and roll. The only property like this I can change for BoneIKController is “_adjustRoll”.

@adam built the IK controller, he might have some good advices ?

Those are actually for the Look controller, sorry, which I thought I did not need anymore, but I do. If you also need to position the wrist, those are to fine tune it.

As you know you can point to something and have your wrist in a number of different rotations, if you are actually doing something with the hand, making these adjustments are almost always needed.