111 lines
4.2 KiB
C
111 lines
4.2 KiB
C
#pragma once
|
|
// base_math.h - Vector, range, and color types
|
|
// Inspired by raddebugger's base_math.h
|
|
|
|
#include "base/base_core.h"
|
|
|
|
////////////////////////////////
|
|
// Axis enum
|
|
|
|
typedef enum Axis2 {
|
|
Axis2_X = 0,
|
|
Axis2_Y = 1,
|
|
Axis2_COUNT,
|
|
} Axis2;
|
|
|
|
typedef enum Side {
|
|
Side_Min = 0,
|
|
Side_Max = 1,
|
|
Side_COUNT,
|
|
} Side;
|
|
|
|
typedef enum Corner {
|
|
Corner_00 = 0, // top-left
|
|
Corner_01 = 1, // top-right
|
|
Corner_10 = 2, // bottom-left
|
|
Corner_11 = 3, // bottom-right
|
|
Corner_COUNT,
|
|
} Corner;
|
|
|
|
////////////////////////////////
|
|
// Vector types
|
|
|
|
typedef struct Vec2F32 { F32 x, y; } Vec2F32;
|
|
typedef struct Vec2S32 { S32 x, y; } Vec2S32;
|
|
typedef struct Vec3F32 { F32 x, y, z; } Vec3F32;
|
|
typedef struct Vec4F32 { F32 x, y, z, w; } Vec4F32;
|
|
|
|
////////////////////////////////
|
|
// Range types
|
|
|
|
typedef struct Rng1F32 { F32 min, max; } Rng1F32;
|
|
typedef struct Rng1S64 { S64 min, max; } Rng1S64;
|
|
typedef struct Rng2F32 { Vec2F32 p0, p1; } Rng2F32;
|
|
|
|
////////////////////////////////
|
|
// Constructors
|
|
|
|
static inline Vec2F32 v2f32(F32 x, F32 y) { Vec2F32 r = {x, y}; return r; }
|
|
static inline Vec2S32 v2s32(S32 x, S32 y) { Vec2S32 r = {x, y}; return r; }
|
|
static inline Vec3F32 v3f32(F32 x, F32 y, F32 z) { Vec3F32 r = {x, y, z}; return r; }
|
|
static inline Vec4F32 v4f32(F32 x, F32 y, F32 z, F32 w) { Vec4F32 r = {x, y, z, w}; return r; }
|
|
static inline Rng1F32 rng1f32(F32 min, F32 max) { Rng1F32 r = {min, max}; return r; }
|
|
static inline Rng1S64 rng1s64(S64 min, S64 max) { Rng1S64 r = {min, max}; return r; }
|
|
static inline Rng2F32 rng2f32(Vec2F32 p0, Vec2F32 p1) { Rng2F32 r = {p0, p1}; return r; }
|
|
static inline Rng2F32 rng2f32p(F32 x0, F32 y0, F32 x1, F32 y1) { Rng2F32 r = {{x0, y0}, {x1, y1}}; return r; }
|
|
|
|
////////////////////////////////
|
|
// Vec2F32 operations
|
|
|
|
static inline Vec2F32 add_2f32(Vec2F32 a, Vec2F32 b) { return v2f32(a.x + b.x, a.y + b.y); }
|
|
static inline Vec2F32 sub_2f32(Vec2F32 a, Vec2F32 b) { return v2f32(a.x - b.x, a.y - b.y); }
|
|
static inline Vec2F32 mul_2f32(Vec2F32 a, Vec2F32 b) { return v2f32(a.x * b.x, a.y * b.y); }
|
|
static inline Vec2F32 scale_2f32(Vec2F32 v, F32 s) { return v2f32(v.x * s, v.y * s); }
|
|
|
|
// Axis-indexed access
|
|
static inline F32 v2f32_axis(Vec2F32 v, Axis2 a) { return a == Axis2_X ? v.x : v.y; }
|
|
static inline void v2f32_set_axis(Vec2F32 *v, Axis2 a, F32 val) {
|
|
if (a == Axis2_X) v->x = val; else v->y = val;
|
|
}
|
|
|
|
////////////////////////////////
|
|
// Vec4F32 operations
|
|
|
|
static inline Vec4F32 add_4f32(Vec4F32 a, Vec4F32 b) { return v4f32(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); }
|
|
static inline Vec4F32 scale_4f32(Vec4F32 v, F32 s) { return v4f32(v.x*s, v.y*s, v.z*s, v.w*s); }
|
|
static inline Vec4F32 lerp_4f32(Vec4F32 a, Vec4F32 b, F32 t) {
|
|
return v4f32(a.x + (b.x - a.x)*t, a.y + (b.y - a.y)*t, a.z + (b.z - a.z)*t, a.w + (b.w - a.w)*t);
|
|
}
|
|
|
|
////////////////////////////////
|
|
// Rng2F32 operations
|
|
|
|
static inline F32 rng2f32_width(Rng2F32 r) { return r.p1.x - r.p0.x; }
|
|
static inline F32 rng2f32_height(Rng2F32 r) { return r.p1.y - r.p0.y; }
|
|
static inline Vec2F32 rng2f32_dim(Rng2F32 r) { return v2f32(r.p1.x - r.p0.x, r.p1.y - r.p0.y); }
|
|
static inline Vec2F32 rng2f32_center(Rng2F32 r) { return v2f32((r.p0.x + r.p1.x)*0.5f, (r.p0.y + r.p1.y)*0.5f); }
|
|
static inline B32 rng2f32_contains(Rng2F32 r, Vec2F32 p) {
|
|
return p.x >= r.p0.x && p.x <= r.p1.x && p.y >= r.p0.y && p.y <= r.p1.y;
|
|
}
|
|
static inline Rng2F32 rng2f32_pad(Rng2F32 r, F32 p) {
|
|
return rng2f32p(r.p0.x - p, r.p0.y - p, r.p1.x + p, r.p1.y + p);
|
|
}
|
|
static inline Rng2F32 rng2f32_shift(Rng2F32 r, Vec2F32 v) {
|
|
return rng2f32p(r.p0.x + v.x, r.p0.y + v.y, r.p1.x + v.x, r.p1.y + v.y);
|
|
}
|
|
static inline Rng2F32 rng2f32_intersect(Rng2F32 a, Rng2F32 b) {
|
|
return rng2f32p(Max(a.p0.x, b.p0.x), Max(a.p0.y, b.p0.y),
|
|
Min(a.p1.x, b.p1.x), Min(a.p1.y, b.p1.y));
|
|
}
|
|
|
|
// Axis-indexed range dimension
|
|
static inline F32 rng2f32_dim_axis(Rng2F32 r, Axis2 a) {
|
|
return a == Axis2_X ? (r.p1.x - r.p0.x) : (r.p1.y - r.p0.y);
|
|
}
|
|
|
|
////////////////////////////////
|
|
// F32 helpers
|
|
|
|
static inline F32 lerp_1f32(F32 a, F32 b, F32 t) { return a + (b - a) * t; }
|
|
static inline F32 abs_f32(F32 x) { return x < 0 ? -x : x; }
|