0
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .