# Convert transform from world to local space

I have a hierarchical node system. Given a world space transform, I need to obtain the transform for a specific node in local space.

My Node class has the following method.

public void worldToLocal(Matrix4 world, Matrix4 local) {
if (dirty) update();
local.set(worldInverse).mul(world);
}


worldInverse is the inverse of the node's world transformation matrix.

I'm using LibGDX, so this is equivalent to doing:

LOCAL = T^-1 * WORLD


T^-1 being the inverse of the node's world transform. However, this doesn't seem to be working correctly.

Let's say we have a node at (2, 4, 0) rotated 180 degrees along its Z axis.

    Node node = new Node();
node.setPosition(2.0f, 4.0f, 0.0f);
node.rotate(new Vector3(0.0f, 0.0f, 1.0f), 180.0f);


Now, the point (1, 7, 0) should be (2, 1, 0) in local space for that node.

    Matrix4 local = new Matrix4();
Matrix4 world = new Matrix4();
Vector3 pos = new Vector3();

world.translate(1.0f, 7.0f, 0.0f);
node.worldToLocal(world, local);
local.getTranslation(pos);


However, I get (1, -3, 0).

I'm using this operation to translate from world space Bullet body transforms to local node transforms.

It's a bit vague what you want to do and what you have. But this should help:

Vector3 pos = new Vector3();
Matrix4 nodeTransform = new Matrix4();
nodeTransform.setToTranslation(2,  4,  0).rotate(Vector3.Z, 180f);
nodeTransform.getTranslation(pos);
Gdx.app.log("Node pos", pos.toString());
Matrix4 modelTransform = new Matrix4();
modelTransform.setToTranslation(1, 7, 0);
Matrix4 worldTransform = new Matrix4();
worldTransform.set(modelTransform).mul(nodeTransform);
worldTransform.getTranslation(pos);
Gdx.app.log("World pos", pos.toString());
Matrix4 invModelTransform = new Matrix4().set(modelTransform).inv();
nodeTransform.set(invModelTransform).mul(worldTransform);
nodeTransform.getTranslation(pos);
Gdx.app.log("Recalculated node pos", pos.toString());


which prints:

Node pos: (2.0,4.0,0.0)
World pos: (3.0,11.0,0.0)
Recalculated node pos: (2.0,4.0,0.0)


The nodeTransform holds the transformation of the node and it is assumed that it is a root node (or it included the parent transform). The modelTransform holds the transformation of the model (e.g. it is ModelInstance#transform). worldTransform holds the resulting matrix (e.g. it is the resulting Renderable#worldTransform value and what is used in the shader). invModelTransform is the inverse of the modelTransform which can be used to recalculate the nodeTransform when given the worldTransform.