What is the correct math to mirror bones

Hi everybody,
I’m trying to write a method for bones transformations reflection along the X-axis.
What I currently have looks approximately like that:

		// X-mirror matrix
		const reflPlane = new Plane(1, 0, 0, 0);
		const mirrorMatrix = Matrix.Reflection(reflPlane);

		// FROM NODE
		const fromGlobalMat = fromBone.getWorldMatrix();
		const fromAbsInv = fromBone.getInvertedAbsoluteTransform();
		const fromGlobalDiff = fromGlobalMat.multiply(fromAbsInv);

		// TO NODE
		const toAbs = toBone.getAbsoluteTransform();
		const toGlobalDiffMat = mirrorMatrix.multiply(fromGlobalDiff);
		const toParent = toTnode.parent;
		const parentMat = toParent instanceof TransformNode ? toParent.getWorldMatrix() : Matrix.Identity();
		const toParentInv = parentMat.invert();

		const newGlobalMat = toGlobalDiffMat.multiply(toAbs);
		const newLocalMat = newGlobalMat.multiply(toParentInv);

The resulting matrix will be right-handed which needs to be fixed, but the position should be ok.
Unfortunately, that’s not the case. The position is messed up as well. I’d appreciate if someone could give me an idea of where I might be wrong.

1 Like

I would decompose the matrix to TRS, then I woudl mirror position and orientation quaternion.
mirrored position is simple : (-x,y,z)
mirrored quaternion is (-x, y, z, -w) IIRC
Then recompose the matrix. This will be fine for a world matrix. For parented matrix, compute in world space then multiply by parent world inverse matrix.

3 Likes

I see what you mean. That’s a bit different from what I’m trying to achieve I think.
The way you propose to do it, the mirrored bone will get the exact mirrored transform in skeleton space.
I need it to be in parent bone space.
A bit hard to describe it but the mirrored bone should get the same mirrored transformation as the original bone relative to its parent.

I’ll actually try to combine your mirroring approach with what I do.

3 Likes