Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl.Vector/llms.txt

Use this file to discover all available pages before exploring further.

Prowl.Vector ships six matrix types, covering both double and float precision at three sizes. 4×4 matrices (Double4x4, Float4x4) are the workhorses of 3D rendering and physics — they represent the full affine and projective transforms needed to place objects in a scene and project them onto a screen. 3×3 matrices (Double3x3, Float3x3) are used for pure rotation and scale without a translation component, and for transforming normal vectors. 2×2 matrices (Double2x2, Float2x2) handle 2D transformations. All six types are serializable column-major value structs in the Prowl.Vector namespace.

Type Overview

TypePrecisionPrimary Use Case
Double4x4doubleFull 3D TRS, view/projection, high-precision physics
Float4x4floatReal-time rendering TRS, GPU-ready transforms
Double3x3doubleRotation-only, normal transforms, 2D homogeneous
Float3x3floatRotation-only, normal transforms, 2D homogeneous
Double2x2double2D linear transforms
Float2x2float2D linear transforms

Creating Transformation Matrices

Translation

// Double4x4
Double4x4 t = Double4x4.CreateTranslation(new Double3(10.0, 5.0, -3.0));

// Float4x4
Float4x4 tf = Float4x4.CreateTranslation(new Float3(10f, 5f, -3f));

Scale

// Uniform scale
Double4x4 su = Double4x4.CreateScale(2.0);

// Non-uniform scale from individual values
Double4x4 sn = Double4x4.CreateScale(1.0, 2.0, 3.0);

// Non-uniform scale from a vector
Double4x4 sv = Double4x4.CreateScale(new Double3(1.0, 2.0, 3.0));

Axis-Aligned Rotation

double angle = Maths.PI / 4.0; // 45° in radians

Double4x4 rx = Double4x4.RotateX(angle);
Double4x4 ry = Double4x4.RotateY(angle);
Double4x4 rz = Double4x4.RotateZ(angle);

// Arbitrary axis-angle rotation
Double4x4 ra = Double4x4.FromAxisAngle(Double3.UnitY, angle);

TRS (Translation–Rotation–Scale)

CreateTRS composes all three into a single matrix, applying scale first, then rotation, then translation — the standard object-to-world convention.
// Double4x4 TRS
Double4x4 trs = Double4x4.CreateTRS(
    translation: new Double3(5.0, 0.0, 0.0),
    rotation:    Quaternion.FromEuler(new Float3(0f, 45f, 0f)),
    scale:       new Double3(1.0, 1.0, 1.0)
);

// Float4x4 TRS (same API)
Float4x4 trsf = Float4x4.CreateTRS(
    new Float3(5f, 0f, 0f),
    Quaternion.FromEuler(new Float3(0f, 45f, 0f)),
    new Float3(1f, 1f, 1f)
);

From Quaternion

Quaternion q = Quaternion.FromEuler(new Float3(30f, 60f, 0f));

Double4x4 rotMat  = Double4x4.CreateFromQuaternion(q);
Float4x4  rotMatF = Float4x4.CreateFromQuaternion(q);

View and Projection Matrices

All view and projection helpers produce left-handed matrices with a depth range of [0, 1], matching the DirectX / Vulkan / Metal convention used by Prowl Engine’s renderer.

LookAt (View Matrix)

Double3 eye    = new Double3(0.0, 5.0, -10.0);
Double3 target = new Double3(0.0, 0.0,   0.0);
Double3 up     = Double3.UnitY;

Double4x4 view = Double4x4.CreateLookAt(eye, target, up);

// Alternatively, supply a forward direction instead of a target point
Double4x4 viewTo = Double4x4.CreateLookTo(eye, forwardVector: Double3.UnitZ, up);

Perspective Projection

double fovY        = Maths.PI / 3.0; // 60° vertical FoV
double aspectRatio = 16.0 / 9.0;
double nearPlane   = 0.1;
double farPlane    = 1000.0;

Double4x4 proj = Double4x4.CreatePerspectiveFov(fovY, aspectRatio, nearPlane, farPlane);
Pass double.PositiveInfinity as farPlane to get a reversed-infinite projection, which improves depth-buffer precision at large distances.

Orthographic Projection

// Centered orthographic projection
Double4x4 ortho = Double4x4.CreateOrtho(
    width:     20.0,
    height:    11.25,
    nearPlane: -100.0,
    farPlane:  100.0
);

// Off-center orthographic projection (UI, shadow maps, etc.)
Double4x4 orthoOC = Double4x4.CreateOrthoOffCenter(
    left:      0.0,
    right:     1920.0,
    bottom:    0.0,
    top:       1080.0,
    nearPlane: -1.0,
    farPlane:  1.0
);

Matrix Arithmetic

Multiplication

Matrix multiplication combines transforms. The result A * B applies B first, then A (column-vector convention).
Double4x4 T = Double4x4.CreateTranslation(new Double3(1, 2, 3));
Double4x4 R = Double4x4.RotateY(Maths.PI / 4.0);
Double4x4 S = Double4x4.CreateScale(2.0);

// Apply scale → rotate → translate
Double4x4 trs = T * (R * S);

// Matrix-vector multiplication
Double4 col = new Double4(1.0, 0.0, 0.0, 1.0);
Double4 result = trs * col;

Transpose

Double4x4 transposed = Double4x4.Transpose(trs);
Double3x3 transposed3 = Double3x3.Transpose(new Double3x3(trs));

Determinant

double det = Double4x4.Determinant(trs);

Invert / Inverse

// Instance method — returns inverted matrix; fills with NaN if not invertible
Double4x4 inv = trs.Invert();

// Static out-param version — also returns a success bool
if (Double4x4.Invert(trs, out Double4x4 safe))
{
    // Use safe
}

// Same API on Double3x3
Double3x3 m3 = new Double3x3(trs);
Double3x3 inv3 = m3.Invert();
When Invert fails (zero determinant), the resulting matrix has NaN in all elements. Always check the bool return value of the static Invert overload in production code.

Transforming Points and Normals

TransformPoint

Transforms a 3D point as homogeneous coordinates (x, y, z, 1) and performs a perspective divide — correct for rendering and full projective transforms.
Double3 worldPoint = new Double3(1.0, 2.0, 3.0);
Double3 clipPoint  = Double4x4.TransformPoint(worldPoint, projMatrix);

// 4D version — no perspective divide
Double4 homogeneous = new Double4(1.0, 2.0, 3.0, 1.0);
Double4 transformed = Double4x4.TransformPoint(homogeneous, projMatrix);

TransformNormal

Surface normals must be transformed by the inverse transpose to remain perpendicular to the surface after non-uniform scaling. TransformNormal handles this automatically, normalizing the result.
Double3 worldNormal     = Double3.UnitY;
Double3 transformedNorm = Double4x4.TransformNormal(worldNormal, modelMatrix);

Identity and Zero

// Pre-built static readonly fields
Double4x4 id   = Double4x4.Identity;  // diagonal = 1
Double4x4 zero = Double4x4.Zero;      // all = 0

Float4x4 fId   = Float4x4.Identity;

Double3x3 id3  = Double3x3.Identity;
Double3x3 z3   = Double3x3.Zero;

Column Layout and Indexer Access

All matrices are stored in column-major order. The public fields c0, c1, c2, c3 are the column vectors.
Double4x4 m = Double4x4.Identity;

// Column access — returns a reference
ref Double4 col0 = ref m[0]; // same as m.c0

// Element access — [row, column]
double val = m[1, 2];   // row 1, column 2
m[0, 3] = 5.0;          // set translation X

// Row accessors (returned by value, not by reference)
Double4 row0 = m.GetRow0();
m.SetRow0(new Double4(1, 0, 0, 0));

// Translation shortcut property
m.Translation = new Double4(1.0, 2.0, 3.0, 1.0);
Because matrices are column-major, iterating over c0, c1, c2, c3 is cache-friendly. Avoid calling GetRow in tight loops — read from the column vectors directly instead.

Constructing from Double3x3 + Translation

Double4x4 and Float4x4 have constructors that accept a rotation matrix and a translation vector directly, making it convenient to build a transform from separately-computed parts:
Double3x3 rot   = Double3x3.FromQuaternion(Quaternion.Identity);
Double3   trans = new Double3(1.0, 2.0, 3.0);

Double4x4 combined = new Double4x4(rot, trans);

Serialization and Array Conversion

double[] flat = trs.ToArray(); // 16-element row-major array

Build docs developers (and LLMs) love