tiramisu/transform

Transform module - position, rotation, and scale for 3D objects.

Transforms define where objects are in 3D space, how they’re rotated, and their size. All transforms are immutable - functions return new transforms instead of modifying existing ones.

Quick Example

import tiramisu/transform
import vec/vec3

let player_transform = transform.identity
  |> transform.set_position(vec3.Vec3(0.0, 1.0, 0.0))
  |> transform.set_rotation(vec3.Vec3(0.0, 1.57, 0.0))  // 90 degrees in radians
  |> transform.set_scale(vec3.Vec3(1.0, 2.0, 1.0))  // Tall player

Types

Transform represents the position, rotation, and scale of an object in 3D space.

  • position: World-space coordinates (x, y, z)
  • rotation: Euler angles in radians (pitch, yaw, roll / x, y, z)
  • scale: Size multiplier per axis (1.0 = original size)
pub type Transform {
  Transform(
    position: vec3.Vec3(Float),
    rotation: vec3.Vec3(Float),
    scale: vec3.Vec3(Float),
  )
}

Constructors

Values

pub fn at(position position: vec3.Vec3(Float)) -> Transform

Create a transform at a specific position with default rotation and scale.

Example

let t = transform.at(position: vec3.Vec3(5.0, 0.0, -3.0))
// Object positioned at (5, 0, -3)
pub fn compose(first: Transform, second: Transform) -> Transform

Compose two transforms (apply second transform after first).

Useful for relative transformations. Note: This is a simplified composition that adds positions/rotations and multiplies scales. For proper hierarchical transforms, use scene Group nodes instead.

Example

let base = transform.at(vec3.Vec3(5.0, 0.0, 0.0))
let offset = transform.at(vec3.Vec3(0.0, 2.0, 0.0))
let combined = transform.compose(base, offset)
// position: (5.0, 2.0, 0.0)
pub const identity: Transform

Create an identity transform (position at origin, no rotation, scale 1).

Example

let t = transform.identity
// position: (0, 0, 0), rotation: (0, 0, 0), scale: (1, 1, 1)
pub fn lerp(
  from: Transform,
  to to: Transform,
  with t: Float,
) -> Transform

Linearly interpolate between two transforms.

Useful for smooth animations and transitions. Parameter t should be between 0.0 and 1.0:

  • t = 0.0 returns from
  • t = 1.0 returns to
  • t = 0.5 returns halfway between

Example

let start = transform.at(vec3.Vec3(0.0, 0.0, 0.0))
let end = transform.at(vec3.Vec3(10.0, 0.0, 0.0))
let halfway = transform.lerp(start, to: end, with: 0.5)
// position: (5.0, 0.0, 0.0)
pub fn look_at(
  from from: vec3.Vec3(Float),
  to to: vec3.Vec3(Float),
) -> Transform

Create a transform that looks at a target position from a source position.

Calculates the rotation needed to point from from towards to. Uses proper Euler angle conversion with atan2 for stable results.

Returns rotation in radians (pitch, yaw, roll) where:

  • Pitch (X): rotation around X axis (looking up/down)
  • Yaw (Y): rotation around Y axis (turning left/right)
  • Roll (Z): rotation around Z axis (typically 0 for look-at)

Example

let camera_pos = vec3.Vec3(0.0, 5.0, 10.0)
let target_pos = vec3.Vec3(0.0, 0.0, 0.0)
let look_transform = transform.look_at(from: camera_pos, to: target_pos)
// Camera now faces the origin
pub fn rotate_by(
  transform: Transform,
  rotation: vec3.Vec3(Float),
) -> Transform

Rotate a transform by adding to its current rotation (relative rotation).

Example

let t = transform.identity
  |> transform.rotate_by(vec3.Vec3(0.0, 1.57, 0.0))  // Turn 90° right
  |> transform.rotate_by(vec3.Vec3(0.0, 1.57, 0.0))  // Turn another 90° right
// rotation: (0.0, 3.14, 0.0) - now facing backward
pub fn rotate_x(transform: Transform, angle: Float) -> Transform

Rotate around the X axis (pitch/look up-down).

Example

let t = transform.identity
  |> transform.rotate_x(0.5)  // Look up slightly
pub fn rotate_y(transform: Transform, angle: Float) -> Transform

Rotate around the Y axis (yaw/turn left-right).

Example

let t = transform.identity
  |> transform.rotate_y(1.57)  // Turn 90° right
pub fn rotate_z(transform: Transform, angle: Float) -> Transform

Rotate around the Z axis (roll/tilt left-right).

Example

let t = transform.identity
  |> transform.rotate_z(0.3)  // Tilt right
pub fn scale_by(
  transform: Transform,
  scale_factor: vec3.Vec3(Float),
) -> Transform

Scale a transform by multiplying its current scale (relative scaling).

Example

let t = transform.identity
  |> transform.scale_by(vec3.Vec3(2.0, 1.0, 2.0))
  |> transform.scale_by(vec3.Vec3(2.0, 1.0, 1.0))
// scale: (4.0, 1.0, 2.0)
pub fn scale_uniform(
  transform: Transform,
  scale: Float,
) -> Transform

Set uniform scale on all axes (width = height = depth).

Example

let t = transform.identity
  |> transform.scale_uniform(2.0)
// scale: (2.0, 2.0, 2.0) - twice as big in all dimensions
pub fn translate(
  transform: Transform,
  by offset: vec3.Vec3(Float),
) -> Transform

Move a transform by adding to its current position (relative movement).

Example

let t = transform.at(vec3.Vec3(5.0, 0.0, 0.0))
  |> transform.translate_by(vec3.Vec3(2.0, 1.0, 0.0))
// position: (7.0, 1.0, 0.0)
pub fn with_position(
  transform: Transform,
  position: vec3.Vec3(Float),
) -> Transform

Update the position of a transform.

Example

let moved = transform.identity
  |> transform.set_position(vec3.Vec3(1.0, 2.0, 3.0))
pub fn with_rotation(
  transform: Transform,
  rotation: vec3.Vec3(Float),
) -> Transform

Update the rotation of a transform (Euler angles in radians).

Example

let rotated = transform.identity
  |> transform.set_rotation(vec3.Vec3(0.0, 1.57, 0.0))  // 90° turn around Y axis
pub fn with_scale(
  transform: Transform,
  scale: vec3.Vec3(Float),
) -> Transform

Update the scale of a transform.

Example

let scaled = transform.identity
  |> transform.set_scale(vec3.Vec3(2.0, 1.0, 2.0))  // Wide and deep, normal height
Search Document