API

Coordinate Transformation Examples

Examples of Coordinate Transformation

Satellite

Take a box that is rotating and translating, from whose top a smaller box emerges and travels in a direction that is always perpendicular to the top face of the box.

In the local coordinate system of the box the up direction is (0, 1, 0) and so locally the position of anything travelling in that direction will be (0, y, 0).

Knowing the world matrix of the box for any frame, you can apply it to the smaller box's local position vector (0, y, 0) to determine the smaller box's world position for that frame.

Obtaining the world matrix for the box inside a registerAfterRender loop means that the world matrix has already been computed for the box, so you can get it directly.

To match the orientation of the smaller box to the larger box, whatever rotation has been applied to the box must also be applied to the smaller box. The easiest way to do this is to reuse the same rotation methods applied to the box for the smaller box.

The following code gives the animation.

import { Axis, Space } from "@babylonjs/core/Maths/math.axis";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
scene.registerAfterRender(function () {
box.rotate(Axis.Y, Math.PI / 150, Space.LOCAL);
box.rotate(Axis.X, Math.PI / 200, Space.LOCAL);
box.translate(new Vector3(-1, -1, -1).normalize(), 0.001, Space.WORLD);
small.rotationQuaternion = box.rotationQuaternion;
matrix = box.getWorldMatrix();
y += 0.001;
local_pos = new Vector3(0, y, 0);
small.position = Vector3.TransformCoordinates(local_pos, matrix);
});

Small box travels from Large Box: Small Box Travels From Large Box

Disc World

Imagine a disc flying through space with buildings on it. In fact, the following example uses a thin cylinder as the disc, since the top circular face is horizontal, whereas the face of a disc in Babylon.js is vertical. (OK, it does not make any real difference, but it is more natural to start with a horizontal ground.)

The building will be an array of boxes. Leaving the boxes as separate meshes would mean applying the TransformCoordinates function to each of them, so instead they will be merged into one mesh. As in the example above, the rotations of the disc and the boxes are matched, and the position of the boxes is transformed.

import { Axis, Space } from "@babylonjs/core/Maths/math.axis";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
var phi = 0;
scene.registerAfterRender(function () {
matrix = disc.getWorldMatrix();
disc.rotate(Axis.Y, Math.PI / 150, Space.LOCAL);
disc.rotate(Axis.Z, Math.PI / 200, Space.LOCAL);
disc.position = new Vector3(15 * Math.cos(phi), 16 * Math.sin(phi), 5);
boxes.rotationQuaternion = disc.rotationQuaternion;
boxes.position = Vector3.TransformCoordinates(boxes_position, matrix);
phi += 0.01;
});

Disc World: Disc World

One final step before considering parents and pivots as a way of changing the center of transformation of a mesh is the more drastic step of changing the vertex data describing the mesh itself by baking a transformation into the mesh.