Get global coordinates from a transform

I have the following hierarchy in my project:
Screenshot 2024-09-09 at 7.41.27 AM
In my code, I’m trying to get the global translation of both MarioSprite and Camera, get a vector that points towards the camera, and then get the angle.

MarioVector := MarioSprite.LocalToWorld(MarioSprite.Translation);
CameraVector := Camera.LocalToWorld(Camera.Translation);

DiffVector := CameraVector - MarioVector;
DiffVector := Vector3(DiffVector.X, 0, DiffVector.Z);

Percent := AngleRadBetweenVectors(Mario.Direction, DiffVector) / (Pi * 2);

However, the code will error at the AngleRadBetweenVectors call, stating that one of the vectors is zero.

After logging MarioVector and CameraVector, I discover that they are the exact same, which causes DiffVector to be zero.

In the scene, Camera and MarioSprite are not at the same translation. However, both of their parents (Mario and SwingArm) are the same. Which leads me to think LocalToWorld is actually just getting the translation of the parent.

But I thought LocalToWorld would get the global (world) translation of the transform. Is this the right procedure for this? Or is there another way I should be converting local translation to global?

Xxx.LocalToWorld are applying the transformation of Xxx and all parents of Xxx.

This means you should usually not pass Xxx.Translation as argument to Xxx.LocalToWorld, because it means you apply same translation two times – Xxx.LocalToWorld already moves the input vector by Xxx.Translation.

So

MarioVector := MarioSprite.LocalToWorld(MarioSprite.Translation);

should likely be instead

MarioVector := MarioSprite.LocalToWorld(TVector3.Zero);
// equivalent: 
// MarioVector := MarioSprite.LocalToWorld(Vector3(0, 0, 0));

And for the same reason,

CameraVector := Camera.LocalToWorld(Camera.Translation);

should likely be instead

CameraVector := Camera.LocalToWorldDirection(Vector3(0, 0, -1));

See: Castle Game Engine: CastleTransform: Class TCastleCamera (TCastleCamera.Orientation docs): "“For cameras (TCastleCamera): … This means direction is -Z (DefaultCameraDirection), up is +Y (DefaultCameraUp). “””

Note: I also changed LocalToWorld to LocalToWorldDirection, this is a better method to transform directions.

1 Like