1
0

feat: add mat3 and several primitives to pl_math.h

This commit is contained in:
Jonathan Hoffstadt 2025-04-11 21:57:47 -05:00
parent 10ea3a7ce8
commit be504fc942

189
pl_math.h
View File

@ -14,8 +14,8 @@
*/ */
// library version (format XYYZZ) // library version (format XYYZZ)
#define PL_MATH_VERSION "1.1.0" #define PL_MATH_VERSION "1.0.0"
#define PL_MATH_VERSION_NUM 10100 #define PL_MATH_VERSION_NUM 10000
/* /*
Index of this file: Index of this file:
@ -30,6 +30,7 @@ Index of this file:
// [SECTION] matrix ops // [SECTION] matrix ops
// [SECTION] quaternion ops // [SECTION] quaternion ops
// [SECTION] rect ops // [SECTION] rect ops
// [SECTION] aabb ops
// [SECTION] colors // [SECTION] colors
// [SECTION] implementations // [SECTION] implementations
*/ */
@ -40,19 +41,28 @@ Index of this file:
#ifndef PL_MATH_INC #ifndef PL_MATH_INC
#define PL_MATH_INC #define PL_MATH_INC
#define PL_MATH_DEFINED
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] forward declarations & basic types // [SECTION] forward declarations & basic types
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// forward declarations // general math
typedef union _plVec2 plVec2; typedef union _plVec2 plVec2;
typedef union _plVec3 plVec3; typedef union _plVec3 plVec3;
typedef union _plVec4 plVec4; typedef union _plVec4 plVec4;
typedef union _plMat3 plMat3;
typedef union _plMat4 plMat4; typedef union _plMat4 plMat4;
// geometric primitives
typedef struct _plRect plRect; typedef struct _plRect plRect;
typedef struct _plAABB plAABB; 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 // [SECTION] defines
@ -141,6 +151,23 @@ typedef union _plVec4
float d[4]; float d[4];
} plVec4; } 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 typedef union _plMat4
{ {
plVec4 col[4]; plVec4 col[4];
@ -177,6 +204,51 @@ typedef struct _plAABB
plVec3 tMax; plVec3 tMax;
} plAABB; } 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 #endif // PL_MATH_INC
#if defined(PL_MATH_INCLUDE_FUNCTIONS) && !defined(PL_MATH_INCLUDE_FUNCTIONS_H) #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_vec2(XARG, YARG) {(XARG), (YARG)}
#define pl_create_vec3(XARG, YARG, ZARG) {(XARG), (YARG), (ZARG)} #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_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_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_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)} #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_vec2(XARG, YARG) (plVec2){(XARG), (YARG)}
#define pl_create_vec3(XARG, YARG, ZARG) (plVec3){(XARG), (YARG), (ZARG)} #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_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_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_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)} #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 // [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 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 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);} 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 plVec3 pl_mul_mat4_vec3 (const plMat4* ptLeft, plVec3 tRight);
static inline plVec4 pl_mul_mat4_vec4 (const plMat4* ptLeft, plVec4 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_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 // 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;} 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_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;} 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 // [SECTION] colors
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -417,6 +514,15 @@ static inline plRect pl_rect_move_start_y (const plRect* ptRect, float fY)
// [SECTION] implementations // [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 static inline plVec3
pl_mul_mat4_vec3(const plMat4* ptLeft, plVec3 tRight) 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); 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 static inline plMat4
pl_mul_mat4(const plMat4* ptLeft, const plMat4* ptRight) pl_mul_mat4(const plMat4* ptLeft, const plMat4* ptRight)
{ {
@ -482,6 +620,22 @@ pl_mul_mat4(const plMat4* ptLeft, const plMat4* ptRight)
return tResult; 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 static inline plMat4
pl_mat4_rotate_vec3(float fAngle, plVec3 tVec) pl_mat4_rotate_vec3(float fAngle, plVec3 tVec)
{ {
@ -514,6 +668,31 @@ pl_mat4_rotate_vec3(float fAngle, plVec3 tVec)
tM.col[3]); 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 static inline plMat4
pl_mat4_invert(const plMat4* ptMat) pl_mat4_invert(const plMat4* ptMat)
{ {