Now that skeleton.overrideMesh is deprecated, what is the relation between the restPose + baseMatrix + parent?

I noticed that in lots of GLTF imported meshes (like this PG), the baseMatrix of the root bone is scaled differently from the restPose, and seems to be scaled similarly to the parent reference tnode (i.e. previously the overrideMesh)
While all the non-root bones are scaled normally

Any pointers on how to interpret this data? i.e. what is the relation between the ‘overrideMesh’ and the root bone base matrix + rest pose?
My goal is to be able to adjust the baseMatrix (via bone.updateMatrix(M, true, true)) i.e. move and adjust the underlying bones without breaking the bones

I’m having lots of trouble around the root bone because its matrix is so different

@Deltakosh @Evgeni_Popov @sebavan :grimacing:

Adding to the confusion is that in the bone.ts source code, the only exposed function to update the basematrix is ‘updateMatrix’, yet it also has an option to update the _localMatrix to be exactly the same.
But isn’t the _localMatrix different?
In the PG above, the rootbone linkedTransformNode’s _localMatrix is very very different from the baseMatrix

I’m guessing it has to do with bone.getAbsoluteTransform()

cc @bghgary

overrideMesh is not exactly related. What overrideMesh did (before it was removed) was change the associated mesh (which is by default the mesh associated with the skeleton) to the one specified by overrideMesh.

Ok, so what’s the relation between the matrices (based on the original question)? Really need help on this xD
I want to update the baseMatrix i.e. bindMatrix properly based on the linkedTransformNode matrix, and to do that I must learn how it works : )

Perhaps this question is best asked when an example usecase

Let’s say I want to reparent the hips/root bone into a new bone
How do I do that without affecting the mesh scale?

Here is the PG
Before reparenting

After reparenting, it blows up in size

How do I update the basematrix so that it keeps the mesh in the same place after reparenting?

@bghgary @Deltakosh

I’m not sure. Changing the skeleton at runtime is tricky. Do you have the source for the glb? Maybe you can add the extra bone in the source tool and compare the result to see what the tool did.

1 Like

well the thing is I’m trying to make a tool in BJS for rigging, so ideally I can get it to work in BJS

Could you help point me to the person who wrote the source code for the bones? Would love to get his input on this : )

There are a few contributors. The main ones are already here. :slight_smile:

I get that. I’m saying use the source tool to help figure out what needs to happen.

1 Like

Hello @mrlooi just checking in, was your question answered?

Hi @carolhmj , in this thread sort of but at the end I figured it out on my own!

Could you document your findings? :slight_smile: I’ve also been confused by what those matrices actually are. In my case, the local matrix behaved as if it was the rest pose matrix and the latter didn’t do what I expected it to.

I managed to somehow make it work by trial and error, but since reading the source code didn’t help it’s probably only a question of time until the next person faces the same issues, only to find there’s no documentation that would explain what’s going on.

1 Like

Agree with rdw, documenting your findings would be hugely useful for the next person who ends up stumbling upon the same problem!

Everything changed when I figured this out :slight_smile:

function copyBone(bone: Bone) {
	const tnode = bone.getTransformNode()!
	const skeleton = bone.getSkeleton()

	const parent = tnode.parent;

	const rootNode = skeleton.bones[0].getTransformNode()?.parent
	const mat = tnode.getLocalMatrix(); 
	let baseMatrix = mat.clone();
	if (rootNode && parent == rootNode) {
		const parentAbsT = rootNode.getWorldMatrix();
		// base = local * parent (BJS is column major)
		baseMatrix = mat.multiply(parentAbsT);

	// basically a copy of the bone
	return new Bone(, skeleton, parent, mat.clone(), mat.clone(), baseMatrix);