//
// This file was autogenerated.
//



HANDMADE_MATH__USE_C11_GENERICS :: 1;

HMM_PI :: 3.14159265358979323846;
HMM_PI32 :: 3.14159265359;
HMM_DEG180 :: 180.0;
HMM_DEG18032 :: 180.0;
HMM_TURNHALF :: 0.5;
HMM_TURNHALF32 :: 0.5;

Vec2 :: union {
    struct {
        x: float;
        y: float;
    }

    struct {
        u: float;
        v: float;
    }

    struct {
        left:  float;
        right: float;
    }

    struct {
        width:  float;
        height: float;
    }

    elements: [2] float;
}

Vec3 :: union {
    struct {
        x: float;
        y: float;
        z: float;
    }

    struct {
        u: float;
        v: float;
        w: float;
    }

    struct {
        r: float;
        g: float;
        b: float;
    }

    struct {
        xy:        Vec2;
        _ignored0: float;
    }

    struct {
        _ignored1: float;
        yz:        Vec2;
    }

    struct {
        uv:        Vec2;
        _ignored2: float;
    }

    struct {
        _ignored3: float;
        vw:        Vec2;
    }

    elements: [3] float;
}

Vec4 :: union {
    struct {
        union {
            xyz: Vec3;
            struct {
                x: float;
                y: float;
                z: float;
            }
        }

        w: float;
    }

    struct {
        union {
            rgb: Vec3;
            struct {
                r: float;
                g: float;
                b: float;
            }
        }

        a: float;
    }

    struct {
        xy:        Vec2;
        _ignored0: float;
        _ignored1: float;
    }

    struct {
        _ignored2: float;
        yz:        Vec2;
        _ignored3: float;
    }

    struct {
        _ignored4: float;
        _ignored5: float;
        zw:        Vec2;
    }

    elements: [4] float;
}

Mat2 :: union {
    elements: [2] [2] float;
    columns:  [2] Vec2;
}

Mat3 :: union {
    elements: [3] [3] float;
    columns:  [3] Vec3;
}

Mat4 :: union {
    elements: [4] [4] float;
    columns:  [4] Vec4;
}

Quat :: union {
    struct {
        union {
            xyz: Vec3;
            struct {
                x: float;
                y: float;
                z: float;
            }
        }

        w: float;
    }

    elements: [4] float;
}

Bool :: s32;

/*
* Angle unit conversion functions
*/
ToRad :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_ToRad";

ToDeg :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_ToDeg";

ToTurn :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_ToTurn";

/*
* Floating-point math functions
*/
SinF :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_SinF";

CosF :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_CosF";

TanF :: (angle: float) -> float #foreign hmm_radians_nosimd "HMM_TanF";

ACosF :: (arg: float) -> float #foreign hmm_radians_nosimd "HMM_ACosF";

SqrtF :: (_float: float) -> float #foreign hmm_radians_nosimd "HMM_SqrtF";

InvSqrtF :: (_float: float) -> float #foreign hmm_radians_nosimd "HMM_InvSqrtF";

/*
* Utility functions
*/
Lerp :: (a: float, time: float, b: float) -> float #foreign hmm_radians_nosimd "HMM_Lerp";

Clamp :: (min: float, value: float, max: float) -> float #foreign hmm_radians_nosimd "HMM_Clamp";

/*
* Vector initialization
*/
V2 :: (x: float, y: float) -> Vec2 #foreign hmm_radians_nosimd "HMM_V2";

V3 :: (x: float, y: float, z: float) -> Vec3 #foreign hmm_radians_nosimd "HMM_V3";

V4 :: (x: float, y: float, z: float, w: float) -> Vec4 #foreign hmm_radians_nosimd "HMM_V4";

V4V :: (vector: Vec3, w: float) -> Vec4 #foreign hmm_radians_nosimd "HMM_V4V";

/*
* Binary vector operations
*/
AddV2 :: (left: Vec2, right: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_AddV2";

AddV3 :: (left: Vec3, right: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_AddV3";

AddV4 :: (left: Vec4, right: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_AddV4";

SubV2 :: (left: Vec2, right: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_SubV2";

SubV3 :: (left: Vec3, right: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_SubV3";

SubV4 :: (left: Vec4, right: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_SubV4";

MulV2 :: (left: Vec2, right: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_MulV2";

MulV2F :: (left: Vec2, right: float) -> Vec2 #foreign hmm_radians_nosimd "HMM_MulV2F";

MulV3 :: (left: Vec3, right: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_MulV3";

MulV3F :: (left: Vec3, right: float) -> Vec3 #foreign hmm_radians_nosimd "HMM_MulV3F";

MulV4 :: (left: Vec4, right: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_MulV4";

MulV4F :: (left: Vec4, right: float) -> Vec4 #foreign hmm_radians_nosimd "HMM_MulV4F";

DivV2 :: (left: Vec2, right: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_DivV2";

DivV2F :: (left: Vec2, right: float) -> Vec2 #foreign hmm_radians_nosimd "HMM_DivV2F";

DivV3 :: (left: Vec3, right: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_DivV3";

DivV3F :: (left: Vec3, right: float) -> Vec3 #foreign hmm_radians_nosimd "HMM_DivV3F";

DivV4 :: (left: Vec4, right: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_DivV4";

DivV4F :: (left: Vec4, right: float) -> Vec4 #foreign hmm_radians_nosimd "HMM_DivV4F";

EqV2 :: (left: Vec2, right: Vec2) -> Bool #foreign hmm_radians_nosimd "HMM_EqV2";

EqV3 :: (left: Vec3, right: Vec3) -> Bool #foreign hmm_radians_nosimd "HMM_EqV3";

EqV4 :: (left: Vec4, right: Vec4) -> Bool #foreign hmm_radians_nosimd "HMM_EqV4";

DotV2 :: (left: Vec2, right: Vec2) -> float #foreign hmm_radians_nosimd "HMM_DotV2";

DotV3 :: (left: Vec3, right: Vec3) -> float #foreign hmm_radians_nosimd "HMM_DotV3";

DotV4 :: (left: Vec4, right: Vec4) -> float #foreign hmm_radians_nosimd "HMM_DotV4";

Cross :: (left: Vec3, right: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_Cross";

/*
* Unary vector operations
*/
LenSqrV2 :: (a: Vec2) -> float #foreign hmm_radians_nosimd "HMM_LenSqrV2";

LenSqrV3 :: (a: Vec3) -> float #foreign hmm_radians_nosimd "HMM_LenSqrV3";

LenSqrV4 :: (a: Vec4) -> float #foreign hmm_radians_nosimd "HMM_LenSqrV4";

LenV2 :: (a: Vec2) -> float #foreign hmm_radians_nosimd "HMM_LenV2";

LenV3 :: (a: Vec3) -> float #foreign hmm_radians_nosimd "HMM_LenV3";

LenV4 :: (a: Vec4) -> float #foreign hmm_radians_nosimd "HMM_LenV4";

NormV2 :: (a: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_NormV2";

NormV3 :: (a: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_NormV3";

NormV4 :: (a: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_NormV4";

/*
* Utility vector functions
*/
LerpV2 :: (a: Vec2, time: float, b: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_LerpV2";

LerpV3 :: (a: Vec3, time: float, b: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_LerpV3";

LerpV4 :: (a: Vec4, time: float, b: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_LerpV4";

/*
* SSE stuff
*/
LinearCombineV4M4 :: (left: Vec4, right: Mat4) -> Vec4 #foreign hmm_radians_nosimd "HMM_LinearCombineV4M4";

/*
* 2x2 Matrices
*/
M2 :: () -> Mat2 #foreign hmm_radians_nosimd "HMM_M2";

M2D :: (diagonal: float) -> Mat2 #foreign hmm_radians_nosimd "HMM_M2D";

TransposeM2 :: (matrix: Mat2) -> Mat2 #foreign hmm_radians_nosimd "HMM_TransposeM2";

AddM2 :: (left: Mat2, right: Mat2) -> Mat2 #foreign hmm_radians_nosimd "HMM_AddM2";

SubM2 :: (left: Mat2, right: Mat2) -> Mat2 #foreign hmm_radians_nosimd "HMM_SubM2";

MulM2V2 :: (matrix: Mat2, vector: Vec2) -> Vec2 #foreign hmm_radians_nosimd "HMM_MulM2V2";

MulM2 :: (left: Mat2, right: Mat2) -> Mat2 #foreign hmm_radians_nosimd "HMM_MulM2";

MulM2F :: (matrix: Mat2, scalar: float) -> Mat2 #foreign hmm_radians_nosimd "HMM_MulM2F";

DivM2F :: (matrix: Mat2, scalar: float) -> Mat2 #foreign hmm_radians_nosimd "HMM_DivM2F";

DeterminantM2 :: (matrix: Mat2) -> float #foreign hmm_radians_nosimd "HMM_DeterminantM2";

InvGeneralM2 :: (matrix: Mat2) -> Mat2 #foreign hmm_radians_nosimd "HMM_InvGeneralM2";

/*
* 3x3 Matrices
*/
M3 :: () -> Mat3 #foreign hmm_radians_nosimd "HMM_M3";

M3D :: (diagonal: float) -> Mat3 #foreign hmm_radians_nosimd "HMM_M3D";

TransposeM3 :: (matrix: Mat3) -> Mat3 #foreign hmm_radians_nosimd "HMM_TransposeM3";

AddM3 :: (left: Mat3, right: Mat3) -> Mat3 #foreign hmm_radians_nosimd "HMM_AddM3";

SubM3 :: (left: Mat3, right: Mat3) -> Mat3 #foreign hmm_radians_nosimd "HMM_SubM3";

MulM3V3 :: (matrix: Mat3, vector: Vec3) -> Vec3 #foreign hmm_radians_nosimd "HMM_MulM3V3";

MulM3 :: (left: Mat3, right: Mat3) -> Mat3 #foreign hmm_radians_nosimd "HMM_MulM3";

MulM3F :: (matrix: Mat3, scalar: float) -> Mat3 #foreign hmm_radians_nosimd "HMM_MulM3F";

DivM3F :: (matrix: Mat3, scalar: float) -> Mat3 #foreign hmm_radians_nosimd "HMM_DivM3F";

DeterminantM3 :: (matrix: Mat3) -> float #foreign hmm_radians_nosimd "HMM_DeterminantM3";

InvGeneralM3 :: (matrix: Mat3) -> Mat3 #foreign hmm_radians_nosimd "HMM_InvGeneralM3";

/*
* 4x4 Matrices
*/
M4 :: () -> Mat4 #foreign hmm_radians_nosimd "HMM_M4";

M4D :: (diagonal: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_M4D";

TransposeM4 :: (matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_TransposeM4";

AddM4 :: (left: Mat4, right: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_AddM4";

SubM4 :: (left: Mat4, right: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_SubM4";

MulM4 :: (left: Mat4, right: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_MulM4";

MulM4F :: (matrix: Mat4, scalar: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_MulM4F";

MulM4V4 :: (matrix: Mat4, vector: Vec4) -> Vec4 #foreign hmm_radians_nosimd "HMM_MulM4V4";

DivM4F :: (matrix: Mat4, scalar: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_DivM4F";

DeterminantM4 :: (matrix: Mat4) -> float #foreign hmm_radians_nosimd "HMM_DeterminantM4";

// Returns a general-purpose inverse of an HMM_Mat4. Note that special-purpose inverses of many transformations
// are available and will be more efficient.
InvGeneralM4 :: (matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvGeneralM4";

// Produces a right-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention).
// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes.
// Near and Far specify the distances to the near and far clipping planes.
Orthographic_RH_NO :: (left: float, right: float, bottom: float, top: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Orthographic_RH_NO";

// Produces a right-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention).
// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes.
// Near and Far specify the distances to the near and far clipping planes.
Orthographic_RH_ZO :: (left: float, right: float, bottom: float, top: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Orthographic_RH_ZO";

// Produces a left-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention).
// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes.
// Near and Far specify the distances to the near and far clipping planes.
Orthographic_LH_NO :: (left: float, right: float, bottom: float, top: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Orthographic_LH_NO";

// Produces a left-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention).
// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes.
// Near and Far specify the distances to the near and far clipping planes.
Orthographic_LH_ZO :: (left: float, right: float, bottom: float, top: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Orthographic_LH_ZO";

// Returns an inverse for the given orthographic projection matrix. Works for all orthographic
// projection matrices, regardless of handedness or NDC convention.
InvOrthographic :: (ortho_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvOrthographic";

Perspective_RH_NO :: (fov: float, aspect_ratio: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Perspective_RH_NO";

Perspective_RH_ZO :: (fov: float, aspect_ratio: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Perspective_RH_ZO";

Perspective_LH_NO :: (fov: float, aspect_ratio: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Perspective_LH_NO";

Perspective_LH_ZO :: (fov: float, aspect_ratio: float, near: float, far: float) -> Mat4 #foreign hmm_radians_nosimd "HMM_Perspective_LH_ZO";

InvPerspective_RH :: (perspective_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvPerspective_RH";

InvPerspective_LH :: (perspective_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvPerspective_LH";

Translate :: (translation: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_Translate";

InvTranslate :: (translation_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvTranslate";

Rotate_RH :: (angle: float, axis: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_Rotate_RH";

Rotate_LH :: (angle: float, axis: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_Rotate_LH";

InvRotate :: (rotation_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvRotate";

Scale :: (scale: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_Scale";

InvScale :: (scale_matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvScale";

LookAt :: (f: Vec3, s: Vec3, u: Vec3, eye: Vec3) -> Mat4 #foreign hmm_radians_nosimd "_HMM_LookAt";

LookAt_RH :: (eye: Vec3, center: Vec3, up: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_LookAt_RH";

LookAt_LH :: (eye: Vec3, center: Vec3, up: Vec3) -> Mat4 #foreign hmm_radians_nosimd "HMM_LookAt_LH";

InvLookAt :: (matrix: Mat4) -> Mat4 #foreign hmm_radians_nosimd "HMM_InvLookAt";

/*
* Quaternion operations
*/
Q :: (x: float, y: float, z: float, w: float) -> Quat #foreign hmm_radians_nosimd "HMM_Q";

QV4 :: (vector: Vec4) -> Quat #foreign hmm_radians_nosimd "HMM_QV4";

AddQ :: (left: Quat, right: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_AddQ";

SubQ :: (left: Quat, right: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_SubQ";

MulQ :: (left: Quat, right: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_MulQ";

MulQF :: (left: Quat, multiplicative: float) -> Quat #foreign hmm_radians_nosimd "HMM_MulQF";

DivQF :: (left: Quat, divnd: float) -> Quat #foreign hmm_radians_nosimd "HMM_DivQF";

DotQ :: (left: Quat, right: Quat) -> float #foreign hmm_radians_nosimd "HMM_DotQ";

InvQ :: (left: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_InvQ";

NormQ :: (quat: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_NormQ";

MixQ :: (left: Quat, mix_left: float, right: Quat, mix_right: float) -> Quat #foreign hmm_radians_nosimd "_HMM_MixQ";

NLerp :: (left: Quat, time: float, right: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_NLerp";

SLerp :: (left: Quat, time: float, right: Quat) -> Quat #foreign hmm_radians_nosimd "HMM_SLerp";

QToM4 :: (left: Quat) -> Mat4 #foreign hmm_radians_nosimd "HMM_QToM4";

// This method taken from Mike Day at Insomniac Games.
// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf
//
// Note that as mentioned at the top of the paper, the paper assumes the matrix
// would be *post*-multiplied to a vector to rotate it, meaning the matrix is
// the transpose of what we're dealing with. But, because our matrices are
// stored in column-major order, the indices *appear* to match the paper.
//
// For example, m12 in the paper is row 1, column 2. We need to transpose it to
// row 2, column 1. But, because the column comes first when referencing
// elements, it looks like M.Elements[1][2].
//
// Don't be confused! Or if you must be confused, at least trust this
// comment. :)
M4ToQ_RH :: (m: Mat4) -> Quat #foreign hmm_radians_nosimd "HMM_M4ToQ_RH";

M4ToQ_LH :: (m: Mat4) -> Quat #foreign hmm_radians_nosimd "HMM_M4ToQ_LH";

QFromAxisAngle_RH :: (axis: Vec3, angle: float) -> Quat #foreign hmm_radians_nosimd "HMM_QFromAxisAngle_RH";

QFromAxisAngle_LH :: (axis: Vec3, angle: float) -> Quat #foreign hmm_radians_nosimd "HMM_QFromAxisAngle_LH";

QFromNormPair :: (left: Vec3, right: Vec3) -> Quat #foreign hmm_radians_nosimd "HMM_QFromNormPair";

QFromVecPair :: (left: Vec3, right: Vec3) -> Quat #foreign hmm_radians_nosimd "HMM_QFromVecPair";

RotateV2 :: (v: Vec2, angle: float) -> Vec2 #foreign hmm_radians_nosimd "HMM_RotateV2";

// implementation from
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
RotateV3Q :: (v: Vec3, q: Quat) -> Vec3 #foreign hmm_radians_nosimd "HMM_RotateV3Q";

RotateV3AxisAngle_LH :: (v: Vec3, axis: Vec3, angle: float) -> Vec3 #foreign hmm_radians_nosimd "HMM_RotateV3AxisAngle_LH";

RotateV3AxisAngle_RH :: (v: Vec3, axis: Vec3, angle: float) -> Vec3 #foreign hmm_radians_nosimd "HMM_RotateV3AxisAngle_RH";

#scope_file

#import "Basic"; // For assert


#run {
    {
        info := type_info(Vec2);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Vec2.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 8, "Vec2.elements has unexpected size % instead of 8", it.type.runtime_size);
            }
        }
        assert(size_of(Vec2) == 8, "Vec2 has size % instead of 8", size_of(Vec2));
    }

    {
        info := type_info(Vec3);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Vec3.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 12, "Vec3.elements has unexpected size % instead of 12", it.type.runtime_size);
            }
        }
        assert(size_of(Vec3) == 12, "Vec3 has size % instead of 12", size_of(Vec3));
    }

    {
        info := type_info(Vec4);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Vec4.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 16, "Vec4.elements has unexpected size % instead of 16", it.type.runtime_size);
            }
        }
        assert(size_of(Vec4) == 16, "Vec4 has size % instead of 16", size_of(Vec4));
    }

    {
        info := type_info(Mat2);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Mat2.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 16, "Mat2.elements has unexpected size % instead of 16", it.type.runtime_size);
                case "columns";
                    assert(it.offset_in_bytes == 0, "Mat2.columns has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 16, "Mat2.columns has unexpected size % instead of 16", it.type.runtime_size);
            }
        }
        assert(size_of(Mat2) == 16, "Mat2 has size % instead of 16", size_of(Mat2));
    }

    {
        info := type_info(Mat3);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Mat3.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 36, "Mat3.elements has unexpected size % instead of 36", it.type.runtime_size);
                case "columns";
                    assert(it.offset_in_bytes == 0, "Mat3.columns has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 36, "Mat3.columns has unexpected size % instead of 36", it.type.runtime_size);
            }
        }
        assert(size_of(Mat3) == 36, "Mat3 has size % instead of 36", size_of(Mat3));
    }

    {
        info := type_info(Mat4);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Mat4.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 64, "Mat4.elements has unexpected size % instead of 64", it.type.runtime_size);
                case "columns";
                    assert(it.offset_in_bytes == 0, "Mat4.columns has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 64, "Mat4.columns has unexpected size % instead of 64", it.type.runtime_size);
            }
        }
        assert(size_of(Mat4) == 64, "Mat4 has size % instead of 64", size_of(Mat4));
    }

    {
        info := type_info(Quat);
        for info.members {
            if it.name == {
                case "elements";
                    assert(it.offset_in_bytes == 0, "Quat.elements has unexpected offset % instead of 0", it.offset_in_bytes);
                    assert(it.type.runtime_size == 16, "Quat.elements has unexpected size % instead of 16", it.type.runtime_size);
            }
        }
        assert(size_of(Quat) == 16, "Quat has size % instead of 16", size_of(Quat));
    }
}

