From be504fc942fc9e0fb82f2a8abe1b221edc7072dc Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Fri, 11 Apr 2025 21:57:47 -0500 Subject: [PATCH] feat: add mat3 and several primitives to pl_math.h --- pl_math.h | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 7 deletions(-) diff --git a/pl_math.h b/pl_math.h index e4c046a..336f676 100644 --- a/pl_math.h +++ b/pl_math.h @@ -14,8 +14,8 @@ */ // library version (format XYYZZ) -#define PL_MATH_VERSION "1.1.0" -#define PL_MATH_VERSION_NUM 10100 +#define PL_MATH_VERSION "1.0.0" +#define PL_MATH_VERSION_NUM 10000 /* Index of this file: @@ -30,6 +30,7 @@ Index of this file: // [SECTION] matrix ops // [SECTION] quaternion ops // [SECTION] rect ops +// [SECTION] aabb ops // [SECTION] colors // [SECTION] implementations */ @@ -40,19 +41,28 @@ Index of this file: #ifndef PL_MATH_INC #define PL_MATH_INC -#define PL_MATH_DEFINED //----------------------------------------------------------------------------- // [SECTION] forward declarations & basic types //----------------------------------------------------------------------------- -// forward declarations +// general math typedef union _plVec2 plVec2; typedef union _plVec3 plVec3; typedef union _plVec4 plVec4; +typedef union _plMat3 plMat3; typedef union _plMat4 plMat4; -typedef struct _plRect plRect; -typedef struct _plAABB plAABB; + +// geometric primitives +typedef struct _plRect plRect; +typedef struct _plAABB plAABB; +typedef struct _plPlane plPlane; +typedef struct _plSphere plSphere; +typedef struct _plBox plBox; +typedef struct _plCone plCone; +typedef struct _plRay plRay; +typedef struct _plCylinder plCylinder; +typedef struct _plCapsule plCapsule; //----------------------------------------------------------------------------- // [SECTION] defines @@ -141,6 +151,23 @@ typedef union _plVec4 float d[4]; } plVec4; +typedef union _plMat3 +{ + plVec3 col[3]; + struct { + float x11; + float x21; + float x31; + float x12; + float x22; + float x32; + float x13; + float x23; + float x33; + }; + float d[9]; +} plMat3; + typedef union _plMat4 { plVec4 col[4]; @@ -177,6 +204,51 @@ typedef struct _plAABB plVec3 tMax; } plAABB; +typedef struct _plPlane +{ + float fOffset; // opposite of direction + plVec3 tDirection; // normal +} plPlane; + +typedef struct _plSphere +{ + float fRadius; + plVec3 tCenter; +} plSphere; + +typedef struct _plBox +{ + plMat4 tTransform; + plVec3 tHalfSize; +} plBox; + +typedef struct _plCone +{ + plVec3 tBasePos; + plVec3 tTipPos; + float fRadius; +} plCone; + +typedef struct _plCylinder +{ + plVec3 tBasePos; + plVec3 tTipPos; + float fRadius; +} plCylinder; + +typedef struct _plCapsule +{ + plVec3 tBasePos; + plVec3 tTipPos; + float fRadius; +} plCapsule; + +typedef struct _plRay +{ + plVec3 tOrigin; + plVec3 tDirection; +} plRay; + #endif // PL_MATH_INC #if defined(PL_MATH_INCLUDE_FUNCTIONS) && !defined(PL_MATH_INCLUDE_FUNCTIONS_H) @@ -203,6 +275,8 @@ typedef struct _plAABB #define pl_create_vec2(XARG, YARG) {(XARG), (YARG)} #define pl_create_vec3(XARG, YARG, ZARG) {(XARG), (YARG), (ZARG)} #define pl_create_vec4(XARG, YARG, ZARG, WARG) {(XARG), (YARG), (ZARG), (WARG)} + #define pl_create_mat3_diag(XARG, YARG, ZARG) {(XARG), 0.0, 0.0f, 0.0f, (YARG), 0.0f, 0.0f, 0.0f, (ZARG)} + #define pl_create_mat3_cols(XARG, YARG, ZARG) {(XARG).x, (XARG).y, (XARG).z, (YARG).x, (YARG).y, (YARG).z, (ZARG).x, (ZARG).y, (ZARG).z} #define pl_create_mat4_diag(XARG, YARG, ZARG, WARG) {(XARG), 0.0, 0.0f, 0.0f, 0.0f, (YARG), 0.0f, 0.0f, 0.0f, 0.0f, (ZARG), 0.0f, 0.0f, 0.0f, 0.0f, (WARG)} #define pl_create_mat4_cols(XARG, YARG, ZARG, WARG) {(XARG).x, (XARG).y, (XARG).z, (XARG).w, (YARG).x, (YARG).y, (YARG).z, (YARG).w, (ZARG).x, (ZARG).y, (ZARG).z, (ZARG).w, (WARG).x, (WARG).y, (WARG).z, (WARG).w} #define pl_create_rect_vec2(XARG, YARG) {(XARG), (YARG)} @@ -211,6 +285,8 @@ typedef struct _plAABB #define pl_create_vec2(XARG, YARG) (plVec2){(XARG), (YARG)} #define pl_create_vec3(XARG, YARG, ZARG) (plVec3){(XARG), (YARG), (ZARG)} #define pl_create_vec4(XARG, YARG, ZARG, WARG) (plVec4){(XARG), (YARG), (ZARG), (WARG)} + #define pl_create_mat3_diag(XARG, YARG, ZARG) (plMat3){.x11 = (XARG), .x22 = (YARG), .x33 = (ZARG)} + #define pl_create_mat3_cols(XARG, YARG, ZARG) (plMat3){.col[0] = (XARG), .col[1] = (YARG), .col[2] = (ZARG)} #define pl_create_mat4_diag(XARG, YARG, ZARG, WARG) (plMat4){.x11 = (XARG), .x22 = (YARG), .x33 = (ZARG), .x44 = (WARG)} #define pl_create_mat4_cols(XARG, YARG, ZARG, WARG) (plMat4){.col[0] = (XARG), .col[1] = (YARG), .col[2] = (ZARG), .col[3] = (WARG)} #define pl_create_rect_vec2(XARG, YARG) (plRect){.tMin = (XARG), .tMax = (YARG)} @@ -319,7 +395,18 @@ static inline plVec4 pl_norm_vec4(plVec4 tVec) { float fLength = pl_length_vec4( // [SECTION] matrix ops //----------------------------------------------------------------------------- -// general ops +// general ops 3x3 +static inline float pl_mat3_get (const plMat3* ptMat, int iRow, int iCol) { return ptMat->col[iCol].d[iRow];} +static inline void pl_mat3_set (plMat3* ptMat, int iRow, int iCol, float fValue) { ptMat->col[iCol].d[iRow] = fValue;} +static inline plMat3 pl_identity_mat3 (void) { return pl_create_mat3_diag(1.0f, 1.0f, 1.0f);} +static inline plMat3 pl_mat3_transpose (const plMat3* ptMat) { plMat3 tResult = {0}; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) pl_mat3_set(&tResult, i, j, pl_mat3_get(ptMat, j, i)); return tResult;} +static inline plMat3 pl_mat3_invert (const plMat3* ptMat); +static inline plMat3 pl_mul_scalarf_mat3(float fLeft, const plMat3* ptRight) { plMat3 tResult = {0}; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) pl_mat3_set(&tResult, i, j, fLeft * pl_mat3_get(ptRight, j, i)); return tResult;} +static inline plVec3 pl_mul_mat3_vec3 (const plMat3* ptLeft, plVec3 tRight); +static inline plMat3 pl_mul_mat3 (const plMat3* ptLeft, const plMat3* ptRight); +static inline plMat3 pl_add_mat3 (const plMat3* ptLeft, const plMat3* ptRight); + +// general ops 4x4 static inline float pl_mat4_get (const plMat4* ptMat, int iRow, int iCol) { return ptMat->col[iCol].d[iRow];} static inline void pl_mat4_set (plMat4* ptMat, int iRow, int iCol, float fValue) { ptMat->col[iCol].d[iRow] = fValue;} static inline plMat4 pl_identity_mat4 (void) { return pl_create_mat4_diag(1.0f, 1.0f, 1.0f, 1.0f);} @@ -329,6 +416,8 @@ static inline plMat4 pl_mul_scalarf_mat4(float fLeft, const plMat4* ptRight) static inline plVec3 pl_mul_mat4_vec3 (const plMat4* ptLeft, plVec3 tRight); static inline plVec4 pl_mul_mat4_vec4 (const plMat4* ptLeft, plVec4 tRight); static inline plMat4 pl_mul_mat4 (const plMat4* ptLeft, const plMat4* ptRight); +static inline plMat4 pl_add_mat4 (const plMat4* ptLeft, const plMat4* ptRight); +static inline plMat4 pl_mul_mat4_3 (const plMat4* ptLeft, const plMat4* ptMiddle, const plMat4* ptRight); // translation, rotation, scaling static inline plMat4 pl_mat4_translate_xyz (float fX, float fY, float fZ) { plMat4 tResult = pl_create_mat4_diag(1.0f, 1.0f, 1.0f, 1.0f); tResult.x14 = fX; tResult.x24 = fY; tResult.x34 = fZ; return tResult;} @@ -391,6 +480,14 @@ static inline plRect pl_rect_move_start (const plRect* ptRect, float fX, floa static inline plRect pl_rect_move_start_x (const plRect* ptRect, float fX) { const plRect tResult = { { fX, ptRect->tMin.y}, { fX + ptRect->tMax.x - ptRect->tMin.x, ptRect->tMax.y} }; return tResult;} static inline plRect pl_rect_move_start_y (const plRect* ptRect, float fY) { const plRect tResult = {{ ptRect->tMin.x, fY}, { ptRect->tMax.x, fY + ptRect->tMax.y - ptRect->tMin.y}}; return tResult;} +//----------------------------------------------------------------------------- +// [SECTION] aabb ops +//----------------------------------------------------------------------------- + +static inline plAABB pl_aabb_merge (const plAABB* tA, const plAABB* tB) { plAABB tResult = {pl_min_vec3(tA->tMin, tB->tMin),pl_max_vec3(tA->tMax, tB->tMax)}; return tResult; } +static inline plVec3 pl_aabb_half_width(const plAABB* tA) { return pl_create_vec3(0.5f * (tA->tMax.x - tA->tMin.x), 0.5f * (tA->tMax.y - tA->tMin.y), 0.5f * (tA->tMax.z - tA->tMin.z)); } +static inline plVec3 pl_aabb_center (const plAABB* tA) { return pl_create_vec3(0.5f * (tA->tMax.x + tA->tMin.x), 0.5f * (tA->tMax.y + tA->tMin.y), 0.5f * (tA->tMax.z + tA->tMin.z)); } + //----------------------------------------------------------------------------- // [SECTION] colors //----------------------------------------------------------------------------- @@ -417,6 +514,15 @@ static inline plRect pl_rect_move_start_y (const plRect* ptRect, float fY) // [SECTION] implementations //----------------------------------------------------------------------------- +static inline plVec3 +pl_mul_mat3_vec3(const plMat3* ptLeft, plVec3 tRight) +{ + float fX = ptLeft->col[0].d[0] * tRight.x + ptLeft->col[1].d[0] * tRight.y + ptLeft->col[2].d[0] * tRight.z; + float fY = ptLeft->col[0].d[1] * tRight.x + ptLeft->col[1].d[1] * tRight.y + ptLeft->col[2].d[1] * tRight.z; + float fZ = ptLeft->col[0].d[2] * tRight.x + ptLeft->col[1].d[2] * tRight.y + ptLeft->col[2].d[2] * tRight.z; + return pl_create_vec3(fX, fY, fZ); +} + static inline plVec3 pl_mul_mat4_vec3(const plMat4* ptLeft, plVec3 tRight) { @@ -450,6 +556,38 @@ pl_mul_mat4_vec4(const plMat4* ptLeft, plVec4 tRight) return pl_add_vec4(Add0, Add1); } +static inline plMat3 +pl_mul_mat3(const plMat3* ptLeft, const plMat3* ptRight) +{ + plMat3 tResult; + + // row 0 + tResult.x11 = ptLeft->col[0].d[0] * ptRight->col[0].d[0] + ptLeft->col[1].d[0] * ptRight->col[0].d[1] + ptLeft->col[2].d[0] * ptRight->col[0].d[2]; + tResult.x12 = ptLeft->col[0].d[0] * ptRight->col[1].d[0] + ptLeft->col[1].d[0] * ptRight->col[1].d[1] + ptLeft->col[2].d[0] * ptRight->col[1].d[2]; + tResult.x13 = ptLeft->col[0].d[0] * ptRight->col[2].d[0] + ptLeft->col[1].d[0] * ptRight->col[2].d[1] + ptLeft->col[2].d[0] * ptRight->col[2].d[2]; + + // row 1 + tResult.x21 = ptLeft->col[0].d[1] * ptRight->col[0].d[0] + ptLeft->col[1].d[1] * ptRight->col[0].d[1] + ptLeft->col[2].d[1] * ptRight->col[0].d[2]; + tResult.x22 = ptLeft->col[0].d[1] * ptRight->col[1].d[0] + ptLeft->col[1].d[1] * ptRight->col[1].d[1] + ptLeft->col[2].d[1] * ptRight->col[1].d[2]; + tResult.x23 = ptLeft->col[0].d[1] * ptRight->col[2].d[0] + ptLeft->col[1].d[1] * ptRight->col[2].d[1] + ptLeft->col[2].d[1] * ptRight->col[2].d[2]; + + // row 2 + tResult.x31 = ptLeft->col[0].d[2] * ptRight->col[0].d[0] + ptLeft->col[1].d[2] * ptRight->col[0].d[1] + ptLeft->col[2].d[2] * ptRight->col[0].d[2]; + tResult.x32 = ptLeft->col[0].d[2] * ptRight->col[1].d[0] + ptLeft->col[1].d[2] * ptRight->col[1].d[1] + ptLeft->col[2].d[2] * ptRight->col[1].d[2]; + tResult.x33 = ptLeft->col[0].d[2] * ptRight->col[2].d[0] + ptLeft->col[1].d[2] * ptRight->col[2].d[1] + ptLeft->col[2].d[2] * ptRight->col[2].d[2]; + + return tResult; +} + +static inline plMat3 +pl_add_mat3(const plMat3* ptLeft, const plMat3* ptRight) +{ + plMat3 tResult; + for(uint32_t i = 0; i < 9; i++) + tResult.d[i] = ptLeft->d[i] + ptRight->d[i]; + return tResult; +} + static inline plMat4 pl_mul_mat4(const plMat4* ptLeft, const plMat4* ptRight) { @@ -482,6 +620,22 @@ pl_mul_mat4(const plMat4* ptLeft, const plMat4* ptRight) return tResult; } +static inline plMat4 +pl_mul_mat4_3(const plMat4* ptLeft, const plMat4* ptMiddle, const plMat4* ptRight) +{ + plMat4 tIntermediateMatrix = pl_mul_mat4(ptMiddle, ptRight); + return pl_mul_mat4(ptLeft, &tIntermediateMatrix); +} + +static inline plMat4 +pl_add_mat4(const plMat4* ptLeft, const plMat4* ptRight) +{ + plMat4 tResult; + for(uint32_t i = 0; i < 16; i++) + tResult.d[i] = ptLeft->d[i] + ptRight->d[i]; + return tResult; +} + static inline plMat4 pl_mat4_rotate_vec3(float fAngle, plVec3 tVec) { @@ -514,6 +668,31 @@ pl_mat4_rotate_vec3(float fAngle, plVec3 tVec) tM.col[3]); } +static inline plMat3 +pl_mat3_invert(const plMat3* ptMat) +{ + const plVec3 tA = ptMat->col[0]; + const plVec3 tB = ptMat->col[1]; + const plVec3 tC = ptMat->col[2]; + + plVec3 tR0 = pl_cross_vec3(tB, tC); + plVec3 tR1 = pl_cross_vec3(tC, tA); + plVec3 tR2 = pl_cross_vec3(tA, tB); + float fInvDet = 1.0f / pl_dot_vec3(tR2, tC); + + plMat3 tResult; + tResult.x11 = tR0.x * fInvDet; + tResult.x21 = tR1.x * fInvDet; + tResult.x31 = tR2.x * fInvDet; + tResult.x12 = tR0.y * fInvDet; + tResult.x22 = tR1.y * fInvDet; + tResult.x32 = tR2.y * fInvDet; + tResult.x13 = tR0.z * fInvDet; + tResult.x23 = tR1.z * fInvDet; + tResult.x33 = tR2.z * fInvDet; + return tResult; +} + static inline plMat4 pl_mat4_invert(const plMat4* ptMat) {