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.
+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.
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.
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);
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.
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.