Skip to content

Math Library

MichaelFisher1997 edited this page Jan 5, 2026 · 1 revision

Math Library

Core mathematical primitives for 3D graphics and physics.


Overview

The math library (libs/zig-math/) provides essential types:

  • Vec3 - 3D vector
  • Mat4 - 4x4 transformation matrix
  • AABB - Axis-aligned bounding box
  • Frustum - View frustum for culling
  • Ray - Ray casting and voxel traversal

Vec3

3D vector for positions, directions, and velocities.

Structure

pub const Vec3 = struct {
    x: f32,
    y: f32,
    z: f32,
};

Constants

Constant Value Description
zero (0, 0, 0) Origin
one (1, 1, 1) Unit scale
up (0, 1, 0) +Y direction
down (0, -1, 0) -Y direction
forward (0, 0, -1) -Z (into screen)
back (0, 0, 1) +Z direction
right (1, 0, 0) +X direction
left (-1, 0, 0) -X direction

Operations

Method Description
add(other) Component-wise addition
sub(other) Component-wise subtraction
scale(scalar) Uniform scaling
dot(other) Dot product (scalar)
cross(other) Cross product (perpendicular Vec3)
length() Euclidean magnitude
lengthSquared() Squared magnitude (faster)
normalize() Unit vector
negate() Flip all components
lerp(other, t) Linear interpolation
distance(other) Distance between points
toArray() Convert to [3]f32

Mat4

4x4 transformation matrix for view, projection, and model transforms.

Structure

pub const Mat4 = extern struct {
    data: [4][4]f32,  // Column-major order
};

Note: Uses extern struct for GPU compatibility.

Constants

Constant Description
identity Identity matrix (no transform)
zero Zero matrix

Projection Methods

Method Description
perspective(fov, aspect, near, far) Standard perspective
perspectiveReverseZ(fov, aspect, near, far) Reverse-Z (better precision)
orthographic(l, r, b, t, near, far) Orthographic for UI

View Methods

Method Description
lookAt(eye, target, worldUp) View matrix from camera position

Transform Methods

Method Description
translate(offset) Translation matrix
scale(s) Non-uniform scale
rotateX(angle) X-axis rotation
rotateY(angle) Y-axis rotation
rotateZ(angle) Z-axis rotation

Utility Methods

Method Description
multiply(a, b) Matrix multiplication
inverse() Compute inverse (cofactor method)
transformPoint(v) Apply to point (with perspective divide)
transformDirection(v) Apply to direction (ignores translation)
ptr() Raw pointer for GPU upload

AABB

Axis-Aligned Bounding Box for collision and culling.

Structure

pub const AABB = struct {
    min: Vec3,  // Minimum corner
    max: Vec3,  // Maximum corner
};

Construction

Method Description
init(min, max) From corner points
fromCenterSize(center, size) From center and dimensions

Query Methods

Method Description
center() Get center point
size() Get dimensions
contains(point) Point containment test
intersects(other) AABB-AABB intersection

Manipulation

Method Description
expand(amount) Grow in all directions
translate(offset) Move box

Frustum

View frustum for visibility culling.

Plane Structure

pub const Plane = struct {
    normal: Vec3,    // Plane normal
    distance: f32,   // Distance from origin
};
Method Description
signedDistance(point) Positive = front, negative = behind
normalize() Normalize plane equation

Frustum Structure

pub const Frustum = struct {
    planes: [6]Plane,  // left, right, bottom, top, near, far
};

Extraction

Frustum extracted from View-Projection matrix using Gribb/Hartmann method:

// Left plane: row4 + row1
planes[0] = Plane.init(
    Vec3.init(m[0][3] + m[0][0], m[1][3] + m[1][0], m[2][3] + m[2][0]),
    m[3][3] + m[3][0],
).normalize();

Culling Methods

Method Description
containsPoint(point) Point inside all 6 planes
intersectsSphere(center, radius) Sphere-frustum test
intersectsAABB(aabb) Primary culling method
intersectsChunk(cx, cz) Specialized chunk test
intersectsChunkRelative(...) Camera-relative chunk test

AABB-Frustum Algorithm

For each plane:

  1. Find AABB's "positive vertex" (furthest in normal direction)
  2. If positive vertex is behind plane, AABB is outside

Ray

Ray casting and voxel traversal.

Structures

pub const Ray = struct {
    origin: Vec3,
    direction: Vec3,  // Normalized
};

pub const RayHit = struct {
    t: f32,           // Distance to hit
    normal: Vec3,     // Surface normal
};

pub const VoxelHit = struct {
    x: i32, y: i32, z: i32,  // Block coordinates
    face: Face,              // Which face was hit
    distance: f32,
};

Ray-AABB Intersection (Slab Method)

pub fn intersectAABB(ray, aabb) ?RayHit {
    // For each axis, compute entry (t1) and exit (t2)
    // Track max_entry and min_exit
    // If max_entry > min_exit, ray misses
    // Returns hit distance and surface normal
}

DDA Voxel Traversal

The castThroughVoxels function implements Digital Differential Analyzer (DDA):

Algorithm:
1. Start at origin voxel
2. For each axis, calculate:
   - step: direction (+1 or -1)
   - tDelta: distance between boundaries
   - tMax: distance to next boundary
3. Loop until max_distance:
   - Check current voxel for solid block
   - Step along axis with smallest tMax
   - Update tMax for that axis
   - Track which face was crossed

This is the standard algorithm for Minecraft-style block targeting.


Usage Examples

View-Projection Matrix

const view = Mat4.lookAt(camera_pos, target, Vec3.up);
const proj = Mat4.perspectiveReverseZ(fov, aspect, near, far);
const view_proj = Mat4.multiply(proj, view);

Frustum Culling

const frustum = Frustum.fromViewProjection(view_proj);

for (chunks) |chunk| {
    const aabb = AABB.fromCenterSize(chunk.center, chunk.size);
    if (frustum.intersectsAABB(aabb)) {
        chunk.render();
    }
}

Block Targeting

const ray = Ray{
    .origin = camera.position,
    .direction = camera.forward,
};

if (ray.castThroughVoxels(world, 5.0)) |hit| {
    highlight_block(hit.x, hit.y, hit.z);
    target_face = hit.face;
}

See Also


Source: libs/zig-math/, src/engine/math/ | Last updated: January 2026

Clone this wiki locally