Skip to content

Latest commit

 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jay Math

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, Euler, 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.

Coordinate System

Jay_Math uses a Z-up, left-handed world:

  • +X is forward.
  • +Y is right.
  • +Z is up.
  • Matrices multiply column vectors (matrix * vector).
  • Affine translation is stored in column 4.
  • Transform basis vectors are stored in columns: forward in column 1, right in column 2, and up in column 3.
  • Positive gameplay yaw turns forward toward right. Positive pitch looks up. Positive roll banks right.

Rendering may convert world forward to -Z in view space. That conversion belongs in the view matrix; it does not change the world-space convention.

Quick Start

#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});
}

Core Types

Vectors

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: dot length length_sqr normalize
  • Utility: lerp

Float vector math is SIMD-accelerated where possible. Integer types use scalar fallbacks.

Matrices

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). Matrix(COL, ROW, T) uses column count first and row count second. Multiplication supports compatible rectangular matrices and returns Matrix(right.COL, left.ROW, T).

Transform-related operations include:

  • translate for world-space displacement
  • local_translate for displacement through the matrix's local basis
  • rotate (2D angle or 3D axis-angle)
  • scale
  • shear
  • face
  • inverse

Inversion uses closed-form paths for 2x2, 3x3, and 4x4, with Gauss-Jordan fallback for larger sizes.

Rotations

There are three interchangeable rotation representations:

  • Quat: unit quaternion
  • Euler: roll, pitch, yaw in degrees
  • Radians: same layout as Euler, but in radians

Convert between them with:

  • to_matrix to_matrix4
  • to_quat
  • to_rotator
  • to_radians

Quaternion and axis-angle conversions require normalized inputs.

Round-tripping between representations is supported. Matrix decomposition preserves reflected matrices by assigning odd reflection sign to the X scale. Individual negative-scale signs are not uniquely recoverable from a matrix.

Transform

Transform stores TRS components:

  • translation: Vec3
  • rotation: Quat
  • scale: Vec3

Convert between Transform and Mat4 using to_matrix and to_transform.

Scalar Math

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.

Performance Notes

  • X64 with AVX2 and FMA is the minimum supported CPU target. There is no runtime fallback.
  • SIMD paths are chosen at compile time, not through runtime dispatch.
  • Code generation uses Jai metaprogramming (#insert) and type-based instruction tables.
  • Square float matrix multiplication keeps its vectorized broadcast and fused multiply-add path. Rectangular multiplication uses generated scalar loops.

In short: write high-level math code, and let the module generate low-level SIMD-friendly instructions for you.

Full Example

#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)
}

About

Math module for jai (The Language™)

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages