Jay_Math is the engine's math module. It gives you the core building blocks used in gameplay and rendering code:
- Vectors (
Vec2,Vec3,Vec4, and variants) - Matrices (
Mat2,Mat3,Mat4, and variants) - Rotations (
Quat,Rotator,Radians) - Transforms (
Transform) - Scalar math (
sin,sqrt,pow, etc.)
The API is designed to feel straightforward in game code, while still generating SIMD-optimized instructions at compile time.
#import "Jay_Math";
main :: () {
a := Vec3.{1, 2, 3};
b := Vec3.{4, 5, 6};
d := dot(a, b);
len := length(a);
mid := lerp(a, b, 0.5);
world := Mat4.identity();
translate(*world, Vec3.{10, 0, 2});
rotate(*world, PI/4, Vec3.{0, 1, 0});
local_translate(*world, Vec3.{0, 0, -5});
}Vectors come from a parametric Vector(N, T, AXES) type, with friendly aliases for common cases.
| float32 | float64 | s32 | s64 |
|---|---|---|---|
Vec2 Vec3 Vec4 |
Vec2d Vec3d Vec4d |
Point2 Point3 Point4 |
Point2d Point3d Point4d |
Common operations:
- Arithmetic:
+-*/ - Geometry:
dotlengthlength_sqrnormalize - Utility:
lerp
Float vector math is SIMD-accelerated where possible. Integer types use scalar fallbacks.
Matrices use Matrix(COL, ROW, T) with aliases for common sizes:
| float32 | float64 |
|---|---|
Mat2 Mat3 Mat4 Mat4x3 |
Mat2d Mat3d Mat4d Mat4x3d |
Each matrix supports multiple access styles (named fields, flat array, and 2D cell view).
Transform-related operations include:
translate/local_translaterotate(2D angle or 3D axis-angle)scaleshearfaceinverse
Inversion uses closed-form paths for 2x2, 3x3, and 4x4, with Gauss-Jordan fallback for larger sizes.
There are three interchangeable rotation representations:
Quat: unit quaternionRotator(orEuler): roll, pitch, yaw in degreesRadians: same layout asRotator, but in radians
Convert between them with:
to_matrixto_matrix4to_quatto_rotatorto_radians
Round-tripping between representations is supported.
Transform stores TRS components:
translation: Vec3rotation: Quatscale: Vec3
Convert between Transform and Mat4 using to_matrix and to_transform.
Jay_Math also provides scalar math functions and constants. Many functions are implemented with Cephes-based approximations and hardware/SIMD instructions when available.
Examples of available functions:
sin cos tan asin acos atan atan2 sqrt exp log log2 pow floor ceil mod frac abs lerp grid_snap inv_sqrt is_nan is_inf is_finite signbit epsilon inf nan
Common constants include:
PI TAU DEG_TO_RAD RAD_TO_DEG EPSILON
Plus min/max/infinity/NaN values for supported float and integer sizes.
- SIMD paths are chosen at compile time (not runtime dispatch).
- Code generation uses Jai metaprogramming (
#insert) and type-based instruction tables. - Matrix multiplication uses vectorized broadcast + fused multiply-add patterns where available.
In short: write high-level math code, and let the module generate low-level SIMD-friendly instructions for you.
#import "Jay_Math";
main :: () {
a := Vec3.{1, 2, 3};
b := Vec3.{4, 5, 6};
d := dot(a, b);
len := length(a);
mid := lerp(a, b, 0.5);
rot := Quat.{1, 0, 0, 0}; // identity
m := to_matrix(rot); // -> Mat3
world := Mat4.identity();
translate(*world, Vec3.{10, 0, 2}); // global-space translation
rotate(*world, PI/4, Vec3.{0, 1, 0});
local_translate(*world, Vec3.{0, 0, -5}); // local-space (along matrix's own axes)
t := Transform.{translation = .{1, 2, 3}};
t_mat := to_matrix(t); // -> Mat4 (TRS composition)
}