power_play/src/base/base_math.h
2025-09-22 20:30:46 -05:00

397 lines
8.7 KiB
C

/* Math functions are default 32 bit (f32, i32, etc) unless specified */
#define Pi ((f32)3.14159265358979323846)
#define Tau ((f32)6.28318530717958647693)
#define GoldenRatio ((f32)1.61803398874989484820)
////////////////////////////////
//~ Vector types
#define VEC2(x, y) (Vec2) { (x), (y) }
#define VEC3(x, y, z) (Vec3) { (x), (y), (z) }
#define VEC4(x, y, z, w) (Vec4) { (x), (y), (z), (w) }
#define VEC2I32(x, y) (Vec2I32) { (x), (y) }
#define VEC3I32(x, y, z) (Vec3I32) { (x), (y), (z) }
#define VEC4I32(x, y, z, w) (Vec4I32) { (x), (y), (z), (w) }
#define VEC2U32(x, y) (Vec2U32) { (x), (y) }
#define VEC3U32(x, y, z) (Vec3U32) { (x), (y), (z) }
#define VEC4U32(x, y, z, w) (Vec4U32) { (x), (y), (z), (w) }
Struct(Vec2) { f32 x, y; };
Struct(Vec3) { f32 x, y, z; };
Struct(Vec4) { f32 x, y, z, w; };
Struct(Vec2I32) { i32 x, y; };
Struct(Vec3I32) { i32 x, y, z; };
Struct(Vec4I32) { i32 x, y, z, w; };
Struct(Vec2U32) { u32 x, y; };
Struct(Vec3U32) { u32 x, y, z; };
Struct(Vec4U32) { u32 x, y, z, w; };
Struct(Vec2Array)
{
Vec2 *points;
u64 count;
};
Struct(Vec3Array)
{
Vec3 *points;
u64 count;
};
Struct(Vec4Array)
{
Vec4 *points;
u64 count;
};
////////////////////////////////
//~ Xform types
Struct(Xform)
{
Vec2 bx; /* X basis vector (x axis) */
Vec2 by; /* Y basis vector (y axis)*/
Vec2 og; /* Translation vector (origin) */
};
/* (T)ranslation, (R)otation, (S)cale */
Struct(Trs)
{
Vec2 t;
Vec2 s;
f32 r;
};
////////////////////////////////
//~ Rect types
Struct(Rect) {
union
{
struct { f32 x, y, width, height; };
struct { Vec2 pos, size; };
};
};
/* Values expected to be normalized 0.0 -> 1.0 */
Struct(ClipRect)
{
Vec2 p0, p1;
};
////////////////////////////////
//~ Axis aligned bounding box types
Struct(Aabb) {
Vec2 p0, p1;
};
////////////////////////////////
//~ Quad types
Struct(Quad) {
union
{
struct { Vec2 p0, p1, p2, p3; };
struct { Vec2 e[4]; };
};
};
////////////////////////////////
//~ Spring types
Struct(SoftSpring)
{
f32 bias_rate;
f32 mass_scale;
f32 impulse_scale;
};
////////////////////////////////
//~ Mat4x4 types
Struct(Mat4x4)
{
union
{
struct { Vec4 bx, by, bz, bw; };
f32 e[4][4];
};
};
////////////////////////////////
//~ Min / max
//- Min
u8 MinU8(u8 a, u8 b);
i8 MinI8(i8 a, i8 b);
u32 MinU32(u32 a, u32 b);
i32 MinI32(i32 a, i32 b);
f32 MinF32(f32 a, f32 b);
u64 MinU64(u64 a, u64 b);
i64 MinI64(i64 a, i64 b);
f64 MinF64(f64 a, f64 b);
//- Max
u8 MaxU8(u8 a, u8 b);
i8 MaxI8(i8 a, i8 b);
u32 MaxU32(u32 a, u32 b);
i32 MaxI32(i32 a, i32 b);
f32 MaxF32(f32 a, f32 b);
u64 MaxU64(u64 a, u64 b);
i64 MaxI64(i64 a, i64 b);
f64 MaxF64(f64 a, f64 b);
//- Clamp
u32 ClampU32(u32 v, u32 min, u32 max);
i32 ClampI32(i32 v, i32 min, i32 max);
f32 ClampF32(f32 v, f32 min, f32 max);
u64 ClampU64(u64 v, u64 min, u64 max);
i64 ClampI64(i64 v, i64 min, i64 max);
f64 ClampF64(f64 v, f64 min, f64 max);
////////////////////////////////
//~ Rounding ops
//- Round
f32 RoundF32(f32 f);
f64 RoundF64(f64 f);
i32 RoundF32ToI32(f32 f);
i64 RoundF64ToI64(f64 f);
//- Floor
f32 FloorF32(f32 f);
f64 FloorF64(f64 f);
i32 FloorF32ToI32(f32 f);
i64 FloorF64ToI64(f64 f);
//- Ceil
f32 CeilF32(f32 f);
f64 CeilF64(f64 f);
i32 CeilF32ToI32(f32 f);
i64 CeilF64ToI64(f64 f);
//- Trunc
f32 TruncF32(f32 f);
f64 TruncF64(f64 f);
////////////////////////////////
//~ Fmod
f32 ModF32(f32 x, f32 m);
f64 ModF64(f64 x, f64 m);
////////////////////////////////
//~ Abs
f32 AbsF32(f32 f);
f64 AbsF64(f64 f);
u32 AbsI32(i32 v);
u64 AbsI64(i64 v);
i32 SignF32(f32 f);
i64 SignF64(f64 f);
////////////////////////////////
//~ Exponential ops
u64 PowU64(u64 base, u8 exp);
u64 AlignU64Pow2(u64 x);
f32 LnF32(f32 x);
f32 ExpF32(f32 x);
f32 PowF32(f32 a, f32 b);
f32 SqrtF32(f32 x);
f64 SqrtF64(f64 x);
f32 RSqrtF32(f32 x);
////////////////////////////////
//~ Trig
f32 ReduceToPio4(f32 x, i32 *octant_out);
f32 SinApproxF32(f32 x);
f32 CosApproxF32(f32 x);
f32 SinF32(f32 x);
f32 CosF32(f32 x);
f32 ArcTanF32(f32 x);
f32 ArcTan2F32(f32 y, f32 x);
f32 ArcSinF32(f32 x);
f32 ArcCosF32(f32 x);
////////////////////////////////
//~ Angle unwind
/* Returns angle in range [-Pi, Pi] */
f32 UnwindAngleF32(f32 a);
////////////////////////////////
//~ Float lerp
f32 LerpF32(f32 val0, f32 val1, f32 t);
f64 LerpF64(f64 val0, f64 val1, f64 t);
f32 LerpAngleF32(f32 a, f32 b, f32 t);
////////////////////////////////
//~ Int lerp
i32 LerpI32(i32 val0, i32 val1, f32 t);
i64 LerpI64(i64 val0, i64 val1, f64 t);
////////////////////////////////
//~ Vec2 operations
#define Vec2FromVec2I32(v) VEC2((v).x, (v).y)
b32 IsVec2Zero(Vec2 a);
b32 EqVec2(Vec2 a, Vec2 b);
//- Mul
Vec2 MulVec2(Vec2 a, f32 s);
Vec2 MulVec2Vec2(Vec2 a, Vec2 b);
Vec2 NegVec2(Vec2 a);
//- Div
Vec2 DivVec2(Vec2 a, f32 s);
Vec2 DivVec2Vec2(Vec2 a, Vec2 b);
//- Add
Vec2 AddVec2(Vec2 a, Vec2 b);
Vec2 SubVec2(Vec2 a, Vec2 b);
//- Len
f32 Vec2Len(Vec2 a);
f32 Vec2LenSq(Vec2 a);
Vec2 Vec2WithLen(Vec2 a, f32 len);
Vec2 ClampVec2Len(Vec2 a, f32 max);
f32 Vec2Distance(Vec2 a, Vec2 b);
Vec2 NormVec2(Vec2 a);
//- Dot
f32 DotVec2(Vec2 a, Vec2 b);
f32 WedgeVec2(Vec2 a, Vec2 b);
Vec2 PerpVec2(Vec2 a);
Vec2 MulPerpVec2(Vec2 a, f32 s);
Vec2 PerpVec2TowardsDir(Vec2 v, Vec2 dir);
//- Round / floor / ceil
Vec2 RoundVec2(Vec2 a);
Vec2I32 RoundVec2ToVec2I32(Vec2 a);
Vec2 FloorVec2(Vec2 a);
Vec2 CeilVec2(Vec2 a);
//- Angle
i32 WindingFromVec2(Vec2 a, Vec2 b);
Vec2 RotateVec2(Vec2 v, f32 a);
Vec2 Vec2FromAngle(f32 a);
f32 AngleFromVec2(Vec2 v);
f32 AngleFromVec2Dirs(Vec2 dir1, Vec2 dir2);
f32 AngleFromVec2Points(Vec2 pt1, Vec2 pt2);
//- Closest point
Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p);
//- Lerp
Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t);
Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t);
////////////////////////////////
//~ Vec2I32 Operations
b32 EqVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 NegVec2I32(Vec2I32 a);
Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b);
////////////////////////////////
//~ Xform operations
b32 EqXform(Xform xf1, Xform xf2);
//- Initialization
#define XformIdentity (Xform) { .bx = VEC2(1, 0), .by = VEC2(0, 1) }
#define XformIdentityNoCast { .bx = VEC2(1, 0), .by = VEC2(0, 1) }
Xform XformFromPos(Vec2 v);
Xform XformFromRot(f32 r);
Xform XformFromScale(Vec2 scale);
Xform XformFromTrs(Trs trs);
Xform XformFromRect(Rect rect);
//- Translation
Xform TranslateXform(Xform xf, Vec2 v);
Xform WorldTranslateXform(Xform xf, Vec2 v);
//- Rotation
Xform RotateXform(Xform xf, f32 r);
Xform WorldRotateXform(Xform xf, f32 r);
Xform WorldRotateXformBasis(Xform xf, f32 r);
Xform XformWIthWorldRotation(Xform xf, f32 r);
//- Scale
Xform ScaleXform(Xform xf, Vec2 scale);
Xform WorldScaleXform(Xform xf, Vec2 scale);
//- Lerp
Xform LerpXform(Xform a, Xform b, f32 t);
//- Invert
Xform InvertXform(Xform xf);
//- Mul
Vec2 MulXformV2(Xform xf, Vec2 v);
Xform MulXform(Xform a, Xform b);
Quad MulXformQuad(Xform xf, Quad quad);
Vec2 MulXformBasisV2(Xform xf, Vec2 v);
Vec2 InvertXformMulV2(Xform xf, Vec2 v);
Vec2 InvertXformBasisMulV2(Xform xf, Vec2 v);
//- Helpers
Xform BasisFromXform(Xform xf);
f32 DeterminantFromXform(Xform xf);
Vec2 RightFromXform(Xform xf);
Vec2 LeftFromXform(Xform xf);
Vec2 UpFromXform(Xform xf);
Vec2 DownFromXform(Xform xf);
f32 RotationFromXform(Xform xf);
Vec2 ScaleFromXform(Xform xf);
//- Trs
#define TRS(...) ((Trs) { .t = VEC2(0,0), .s = VEC2(1, 1), .r = 0, __VA_ARGS__ })
////////////////////////////////
//~ Rect operations
#define RectFromScalar(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) }
#define RectFromVec2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) }
#define AllClipped ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
////////////////////////////////
//~ Quad operations
#define UnitSquareQuad (Quad) { .p0 = VEC2(0, 0), .p1 = VEC2(0, 1), .p2 = VEC2(1, 1), .p3 = VEC2(1, 0) }
#define CenteredUnitSquareQuad (Quad) { .p0 = VEC2(-0.5f, -0.5f), .p1 = VEC2(0.5f, -0.5f), .p2 = VEC2(0.5f, 0.5f), .p3 = VEC2(-0.5f, 0.5f) }
Quad QuadFromRect(Rect rect);
Quad QuadFromAabb(Aabb aabb);
Quad QuadFromLine(Vec2 start, Vec2 end, f32 thickness);
Quad QuadFromRay(Vec2 pos, Vec2 rel, f32 thickness);
Quad ScaleQuad(Quad q, f32 s);
Quad RoundQuad(Quad quad);
Quad FloorQuad(Quad quad);
////////////////////////////////
//~ Spring operations
SoftSpring MakeSpring(f32 hertz, f32 damping_ratio, f32 dt);
////////////////////////////////
//~ Mat4x4 operations
Mat4x4 Mat4x4FromXform(Xform xf);
Mat4x4 Mat4x4FromOrtho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z);
Mat4x4 MulMat4x4(Mat4x4 m1, Mat4x4 m2);
Mat4x4 ProjectMat4x4View(Xform view, f32 viewport_width, f32 viewport_height);