Develop

Transforms & 3D Math

Updated: Sep 4, 2026
IWSDK uses Three.js’s right-handed coordinate system and meter-scale world units. A transform combines position, orientation, and scale relative to an object’s parent.

Coordinate conventions

       +Y up
        |
        |
        +---- +X right
       /
     +Z toward the viewer

-Z points forward from an unrotated camera
Use one world unit as one meter for scene scale, reach, movement, and spatial UI placement.

Update position

entity.object3D!.position.set(2, 1.7, -5);
entity.object3D!.position.x += speed * deltaTime;
The Object3D position is a synchronized view over Transform.position. ECS code can access the same storage.
const position = entity.getVectorView(Transform, 'position');
position[0] += speed * deltaTime;
Use setValue() instead when a query predicate depends on the changed field.

Update orientation

Use quaternions for stored orientation and composition.
const yaw = new Quaternion().setFromAxisAngle(
  new Vector3(0, 1, 0),
  Math.PI / 4,
);

entity.object3D!.quaternion.copy(yaw);
Convert Euler input when an authoring or control surface provides pitch, yaw, and roll.
const euler = new Euler(pitch, yaw, roll, 'YXZ');
entity.object3D!.quaternion.setFromEuler(euler);

Update scale

entity.object3D!.scale.setScalar(0.5);
entity.object3D!.scale.set(2, 1, 0.5);
Uniform scale preserves proportions. Non-uniform scale changes each local axis independently.

Move along local forward

const forward = new Vector3(0, 0, -1)
  .applyQuaternion(entity.object3D!.quaternion)
  .multiplyScalar(speed * deltaTime);

entity.object3D!.position.add(forward);
Reuse the temporary vector inside a per-frame system to avoid repeated allocations.

Convert between local and world space

Use Object3D helpers instead of treating a method as a matrix.
const localPoint = new Vector3(0, 0, -1);
const worldPoint = entity.object3D!.localToWorld(localPoint.clone());

const anotherWorldPoint = new Vector3(5, 2, 0);
const convertedLocalPoint = entity.object3D!.worldToLocal(
  anotherWorldPoint.clone(),
);
Three.js updates the relevant matrices as part of these conversion helpers.

Compare world-space positions

Object positions are local to their parents. Resolve both operands to world space before calculating a scene distance.
const objectWorld = entity.object3D!.getWorldPosition(new Vector3());
const viewerWorld = world.camera.getWorldPosition(new Vector3());
const distance = objectWorld.distanceTo(viewerWorld);
world.camera.position is local to world.player, so it is not a substitute for the viewer’s world position.

Create an entity hierarchy

const car = world.createTransformEntity(carBody);
const wheel = world.createTransformEntity(wheelMesh, { parent: car });

wheel.object3D!.position.set(-1, -0.5, 1.2);
car.object3D!.position.x += speed * deltaTime;
The child position remains local to its parent. TransformSystem keeps the ECS parent reference and Three.js hierarchy aligned.
See ECS and Three.js interop for synchronization details.