Skip to content

Petrichor.Math#

Petrichor.Math is a Luau math library with Vec2/Vec3, quaternions, matrices, and axis-aligned boxes. It is preloaded in the Luau VM.

Loading#

local Math = require("Petrichor.Math")
import * as Math from "Petrichor.Math"

Scalars#

Name / function Description
Math.pi, Math.tau, Math.epsilon Constants
Math.clamp(v, lo, hi) Clamp scalar
Math.lerp(a, b, t) Linear interpolation
Math.remap(v, a, b, c, d) Map v from [a,b] to [c,d]
Math.rad(deg), Math.deg(rad) Degree / radian
Math.sign(v) -1, 0, or 1
Math.approx(a, b) Approximate equality using epsilon
Math.wrap_angle(a) Wrap radians to (-π, π]

Vec2 / Vec3#

Math.vec2(x, y) and Math.vec3(x, y, z).

Operators: +, -, unary -, * by scalar, ==. Methods include length, normalize, dot, cross (Vec3), clone, lerp, distance.

local a = Math.vec3(1, 0, 0)
local b = Math.vec3(0, 1, 0)
local c = a:cross(b)  -- Vec3(0, 0, 1)
const a = Math.vec3(1, 0, 0)
const b = Math.vec3(0, 1, 0)
const c = a.cross(b)  // Vec3(0, 0, 1)

Quat#

Math.quat(x, y, z, w) plus factory helpers:

Function Description
Math.quat_identity() Identity rotation
Math.quat_from_axis_angle(axis, angle) Axis-angle rotation
Math.quat_from_euler_zyx(z, y, x) Euler angles in ZYX order (radians)
Math.quat_look_at(from, to, up?) Look-at rotation

Quat methods include slerp, rotate_vec3, to_euler_zyx, to_mat4, dot, normalize, conjugate, inverse, and clone. See math.luau in the Petrichor repo for the rest.


Mat4#

Column-major 4×4 matrices. There is no generic mat4() constructor; use the helpers below.

Function Description
Math.mat4_identity() Identity matrix
Math.mat4_zero() Zero matrix
Math.mat4_translation(tx, ty, tz) Translation
Math.mat4_scale(sx, sy, sz) Scale
Math.mat4_rotation_x/y/z(a) Axis rotations (radians)
Math.mat4_from_quat(q) Rotation from quaternion
Math.mat4_trs(translation, rotation, scale) Combined TRS

Mat4 methods include mul, mul_vec3, transpose, inverse, and clone.


AABB#

Math.aabb(min_vec3, max_vec3) with :center(), :contains(point), :intersects(other), :expand(point), and more.


Example#

local Math = require("Petrichor.Math")

local pos = Math.vec3(10, 0, 5)
local dir = Math.vec3(0, 0, 1):normalize()
local next = pos + dir * 2.5
import * as Math from "Petrichor.Math"

const pos = Math.vec3(10, 0, 5)
const dir = Math.vec3(0, 0, 1).normalize()
const next = pos.add(dir.mul(2.5))

Hook callbacks often give you game struct views (like cXyz). Use Petrichor.Math when the numbers live in plain Luau tables.