summaryrefslogtreecommitdiff
path: root/prb_math.h
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-06-15 15:28:45 +0500
committerpryazha <pryadeiniv@mail.ru>2025-06-15 15:28:45 +0500
commite7f67b450d8034b532101445035d3b199e702621 (patch)
treed1193a6044d75800266cec11776358be7270cf8b /prb_math.h
parent92850237f42cecfeba519bc15f7f5bb7a76cde5f (diff)
windows?
Diffstat (limited to 'prb_math.h')
-rw-r--r--prb_math.h515
1 files changed, 444 insertions, 71 deletions
diff --git a/prb_math.h b/prb_math.h
index 52c6289..8f188f4 100644
--- a/prb_math.h
+++ b/prb_math.h
@@ -1,71 +1,444 @@
-#ifndef PRB_MATH_H
-#define PRB_MATH_H
-
-/* NOTE(pryazha): Numeric */
-#define F32PI 3.14159265359f
-
-#define DEG2RAD F32PI/180.0f
-#define RAD2DEG 182.0f/F32PI
-
-F32 f32sin(F32 a);
-F32 f32cos(F32 a);
-F32 f32tan(F32 a);
-F32 f32sqrt(F32 a);
-
-/* NOTE(pryazha): Vectors */
-V2 v2(F32 x, F32 y);
-V2 v2a(F32 x);
-V2 invv2(V2 a);
-V2 addv2(V2 a, V2 b);
-V2 subv2(V2 a, V2 b);
-V2 scalefv2(V2 a, F32 s);
-V2 scalev2(V2 a, V2 s);
-F32 dotv2(V2 a, V2 b);
-F32 len2v2(V2 a);
-F32 lenv2(V2 a);
-V2 normv2(V2 a);
-void printv2(V2 a);
-
-V3 v3(F32 x, F32 y, F32 z);
-V3 v3a(F32 x);
-V3 v3fromv2(V2 a);
-V3 v3fromv4(V4 a);
-V3 invv3(V3 a);
-V3 addv3(V3 a, V3 b);
-V3 subv3(V3 a, V3 b);
-V3 scalefv3(V3 a, F32 s);
-V3 scalev3(V3 a, V3 s);
-F32 dotv3(V3 a, V3 b);
-V3 crossv3(V3 l, V3 r);
-F32 len2v3(V3 a);
-F32 lenv3(V3 a);
-V3 normv3(V3 a);
-void printv3(V3 a);
-
-V4 v4(F32 x, F32 y, F32 z, F32 w);
-V4 v4a(F32 x);
-V4 v4fromv3(V3 a);
-V4 invv4(V4 a);
-V4 addv4(V4 a, V4 b);
-V4 subv4(V4 a, V4 b);
-V4 scalefv4(V4 a, F32 s);
-V4 scalev4(V4 a, V4 s);
-F32 dotv4(V4 a, V4 b);
-F32 len2v4(V4 a);
-F32 lenv4(V4 a);
-V4 normv4(V4 a);
-void printv4(V4 a);
-
-/* NOTE(pryazha): Matrices */
-F32 detmat4(MAT4 m);
-MAT4 transpmat4(MAT4 m);
-MAT4 mulmat4(MAT4 left, MAT4 right);
-MAT4 translmat4(MAT4 m, V3 v);
-MAT4 scalemat4(MAT4 m, V3 v);
-MAT4 rotateaxismat4(V3 x, V3 y, V3 z);
-/* NOTE(pryazha): Angles in degrees */
-MAT4 rotatemat4(MAT4 m, V3 angles);
-V4 mulmat4v4(MAT4 m, V4 v);
-void printmat4(MAT4 m);
-
-#endif /* PRB_MATH_H */
+#define V2_ZERO (v2){ 0.0f, 0.0f}
+#define V2_ONE (v2){ 1.0f, 1.0f}
+#define V2_RIGHT (v2){ 1.0f, 0.0f}
+#define V2_UP (v2){ 0.0f, 1.0f}
+#define V2_LEFT (v2){-1.0f, 0.0f}
+#define V2_DOWN (v2){ 0.0f, -1.0f }
+
+#define V3_ZERO (v3){ 0.0f, 0.0f, 0.0f}
+#define V3_ONE (v3){ 1.0f, 1.0f, 1.0f}
+#define V3_RIGHT (v3){ 1.0f, 0.0f, 0.0f}
+#define V3_UP (v3){ 0.0f, 1.0f, 0.0f}
+#define V3_LEFT (v3){-1.0f, 0.0f, 0.0f}
+#define V3_DOWN (v3){ 0.0f, -1.0f, 0.0f}
+#define V3_FORWARD (v3){ 0.0f, 0.0f, 1.0f}
+#define V3_BACKWARD (v3){ 0.0f, 0.0f, -1.0f}
+
+#define V4_ZERO (v4){0.0f, 0.0f, 0.0f, 0.0f}
+#define V4_ONE (v4){1.0f, 1.0f, 1.0f, 1.0f}
+
+#define MAT4_IDENTITY (mat4){ \
+ {1.0f, 0.0f, 0.0f, 0.0f}, \
+ {0.0f, 1.0f, 0.0f, 0.0f}, \
+ {0.0f, 0.0f, 1.0f, 0.0f}, \
+ {0.0f, 0.0f, 0.0f, 1.0f}}
+
+#define F_PI 3.14159265359f
+
+#define deg2rad(angle) (F_PI/180.0f*(angle))
+
+#define QUAT_IDENTITY (v4){0.0f, 0.0f, 0.0f, 1.0f}
+
+/* TODO(pryazha): Implement trigonometry functions */
+f32 fsin(f32 a)
+{
+ f32 result = sinf(a);
+ return result;
+}
+
+f32 fcos(f32 a)
+{
+ f32 result = cosf(a);
+ return result;
+}
+
+f32 ftan(f32 a)
+{
+ f32 result = tanf(a);
+ return result;
+}
+
+f32 fsqrt(f32 a)
+{
+ f32 result = sqrtf(a);
+ return result;
+}
+
+// vectors
+v2 v2_fill(f32 x)
+{
+ v2 v = {x, x};
+ return v;
+}
+
+v2 v2_inv(v2 a)
+{
+ v2 v = {-a.x, -a.y};
+ return v;
+}
+
+v2 v2_add(v2 a, v2 b)
+{
+ v2 v = {a.x+b.x, a.y+b.y};
+ return v;
+}
+
+v2 v2_sub(v2 a, v2 b)
+{
+ v2 v = {a.x-b.x, a.y-b.y};
+ return v;
+}
+
+v2 v2_scalef(v2 a, f32 s)
+{
+ v2 v = {a.x*s, a.y*s};
+ return v;
+}
+
+v2 v2_scale(v2 a, v2 s)
+{
+ v2 v = {a.x*s.x, a.y*s.y};
+ return v;
+}
+
+f32 v2_dot(v2 a, v2 b)
+{
+ f32 v = a.x*b.x+a.y*b.y;
+ return v;
+}
+
+f32 v2_len2(v2 a)
+{
+ f32 v = v2_dot(a, a);
+ return v;
+}
+
+f32 v2_len(v2 a)
+{
+ f32 v = fsqrt(v2_len2(a));
+ return v;
+}
+
+v2 v2_norm(v2 a)
+{
+ v2 v = {0};
+ f32 len = v2_len(a);
+ if (len)
+ v = (v2){a.x/len, a.y/len};
+ return v;
+}
+
+v3 v3_fill(f32 x)
+{
+ v3 v = {x, x, x};
+ return v;
+}
+
+v3 v3_from_v2(v2 a)
+{
+ v3 v = {a.x, a.y, 0.0f};
+ return v;
+}
+
+v3 v3_from_v4(v4 a)
+{
+ v3 v = {a.x, a.y, a.z};
+ return v;
+}
+
+v3 v3_inv(v3 a)
+{
+ v3 v = {-a.x, -a.y, -a.z};
+ return v;
+}
+
+v3 v3_add(v3 a, v3 b)
+{
+ v3 v = {a.x+b.x, a.y+b.y, a.z+b.z};
+ return v;
+}
+
+v3 v3_sub(v3 a, v3 b)
+{
+ v3 v = {a.x-b.x, a.y-b.y, a.z-b.z};
+ return v;
+}
+
+v3 v3_scalef(v3 a, f32 s)
+{
+ v3 v = {a.x*s, a.y*s, a.z*s};
+ return v;
+}
+
+v3 v3_scale(v3 a, v3 s)
+{
+ v3 v = {a.x*s.x, a.y*s.y, a.z*s.z};
+ return v;
+}
+
+f32 v3_dot(v3 a, v3 b)
+{
+ f32 v = a.x*b.x+a.y*b.y+a.z*b.z;
+ return v;
+}
+
+v3 v3_cross(v3 l, v3 r)
+{
+ v3 v = {(l.y*r.z - r.y*l.z), (r.x*l.z - l.x*r.z), (l.x*r.y - r.x*l.y)};
+ return v;
+}
+
+f32 v3_len2(v3 a)
+{
+ f32 v = v3_dot(a, a);
+ return v;
+}
+
+f32 v3_len(v3 a)
+{
+ f32 v = fsqrt(v3_len2(a));
+ return v;
+}
+
+v3 v3_norm(v3 a)
+{
+ v3 v = V3_ZERO;
+ f32 len = v3_len(a);
+ if (len)
+ v = (v3){a.x/len, a.y/len, a.z/len};
+ return v;
+}
+
+v4 v4_fill(f32 x)
+{
+ v4 v = {x, x, x, x};
+ return v;
+}
+
+v4 v4_from_v3(v3 a)
+{
+ v4 v = {a.x, a.y, a.z, 0.0f};
+ return v;
+}
+
+v4 v4_inv(v4 a)
+{
+ v4 v = {-a.x, -a.y, -a.z, -a.w};
+ return v;
+}
+
+v4 v4_add(v4 a, v4 b)
+{
+ v4 v = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
+ return v;
+}
+
+v4 v4_sub(v4 a, v4 b)
+{
+ v4 v = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w};
+ return v;
+}
+
+v4 v4_scalef(v4 a, f32 s)
+{
+ v4 v = {a.x*s, a.y*s, a.z*s, a.w*s};
+ return v;
+}
+
+v4 v4_scale(v4 a, v4 s)
+{
+ v4 v = {a.x*s.x, a.y*s.y, a.z*s.z, a.w*s.w};
+ return v;
+}
+
+f32 v4_dot(v4 a, v4 b)
+{
+ f32 v = a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w;
+ return v;
+}
+
+f32 v4_len2(v4 a)
+{
+ f32 v = v4_dot(a, a);
+ return v;
+}
+
+f32 v4_len(v4 a)
+{
+ f32 v = fsqrt(v4_len2(a));
+ return v;
+}
+
+v4 v4_norm(v4 a)
+{
+ v4 v = V4_ZERO;
+ f32 len = v4_len(a);
+ if (len)
+ v = (v4){a.x/len, a.y/len, a.z/len, a.w/len};
+ return v;
+}
+
+// matrices
+f32 mat4_det(mat4 m)
+{
+ f32 m00 = m.c0.x, m10 = m.c0.y, m20 = m.c0.z, m30 = m.c0.w;
+ f32 m01 = m.c1.x, m11 = m.c1.y, m21 = m.c1.z, m31 = m.c1.w;
+ f32 m02 = m.c2.x, m12 = m.c2.y, m22 = m.c2.z, m32 = m.c2.w;
+ f32 m03 = m.c3.x, m13 = m.c3.y, m23 = m.c3.z, m33 = m.c3.w;
+
+ f32 m00minor = ((m11*m22*m33)+(m12*m23*m31)+(m21*m32*m13)-
+ (m31*m22*m13)-(m21*m12*m33)-(m11*m32*m23));
+
+ f32 m01minor = ((m10*m22*m33)+(m12*m23*m30)+(m20*m32*m13)-
+ (m13*m22*m30)-(m23*m32*m10)-(m12*m20*m33));
+
+ f32 m02minor = ((m10*m21*m33)+(m20*m31*m13)+(m11*m23*m31)-
+ (m13*m21*m30)-(m23*m31*m10)-(m11*m20*m33));
+
+ f32 m03minor = ((m10*m21*m32)+(m20*m31*m12)+(m11*m22*m30)-
+ (m12*m21*m30)-(m11*m20*m32)-(m22*m31*m10));
+
+ f32 result = m00*m00minor+m01*m01minor-m02*m02minor+m03*m03minor;
+
+ return result;
+}
+
+mat4 mat4_transp(mat4 m)
+{
+ swap(f32, m.c0.y, m.c1.x);
+ swap(f32, m.c0.z, m.c2.x);
+ swap(f32, m.c0.w, m.c3.x);
+
+ swap(f32, m.c1.z, m.c2.y);
+ swap(f32, m.c1.w, m.c3.y);
+
+ swap(f32, m.c2.w, m.c3.z);
+
+ return m;
+}
+
+mat4 mat4_mul(mat4 left, mat4 right)
+{
+ f32 l00 = left.c0.x, l01 = left.c0.y, l02 = left.c0.z, l03 = left.c0.w;
+ f32 l10 = left.c1.x, l11 = left.c1.y, l12 = left.c1.z, l13 = left.c1.w;
+ f32 l20 = left.c2.x, l21 = left.c2.y, l22 = left.c2.z, l23 = left.c2.w;
+ f32 l30 = left.c3.x, l31 = left.c3.y, l32 = left.c3.z, l33 = left.c3.w;
+
+ f32 r00 = right.c0.x, r01 = right.c0.y, r02 = right.c0.z, r03 = right.c0.w;
+ f32 r10 = right.c1.x, r11 = right.c1.y, r12 = right.c1.z, r13 = right.c1.w;
+ f32 r20 = right.c2.x, r21 = right.c2.y, r22 = right.c2.z, r23 = right.c2.w;
+ f32 r30 = right.c3.x, r31 = right.c3.y, r32 = right.c3.z, r33 = right.c3.w;
+
+ mat4 result = {
+ {
+ l00*r00+l10*r01+l20*r02+l30*r03,
+ l01*r00+l11*r01+l21*r02+l31*r03,
+ l02*r00+l12*r01+l22*r02+l32*r03,
+ l03*r00+l13*r01+l23*r02+l33*r03
+ },
+ {
+ l00*r10+l10*r11+l20*r12+l30*r13,
+ l01*r10+l11*r11+l21*r12+l31*r13,
+ l02*r10+l12*r11+l22*r12+l32*r13,
+ l03*r10+l13*r11+l23*r12+l33*r13
+ },
+ {
+ l00*r20+l10*r21+l20*r22+l30*r23,
+ l01*r20+l11*r21+l21*r22+l31*r23,
+ l02*r20+l12*r21+l22*r22+l32*r23,
+ l03*r20+l13*r21+l23*r22+l33*r23
+ },
+ {
+ l00*r30+l10*r31+l20*r32+l30*r33,
+ l01*r30+l11*r31+l21*r32+l31*r33,
+ l02*r30+l12*r31+l22*r32+l32*r33,
+ l03*r30+l13*r31+l23*r32+l33*r33
+ }
+ };
+
+ return result;
+}
+
+mat4 mat4_make_transl(v3 v)
+{
+ mat4 translate = {
+ {1.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f, 0.0f},
+ {v.x, v.y, v.z, 1.0f}
+ };
+ return translate;
+}
+
+mat4 mat4_make_scale(v3 v)
+{
+ mat4 scale = {
+ {v.x, 0.0f, 0.0f, 0.0f},
+ {0.0f, v.y, 0.0f, 0.0f},
+ {0.0f, 0.0f, v.z, 0.0f},
+ {0.0f, 0.0f, 0.0f, 1.0f}
+ };
+ return scale;
+}
+
+mat4 mat4_make_rotate(v3 x, v3 y, v3 z)
+{
+ mat4 rotate = {
+ {x.x, x.y, x.z, 0.0f},
+ {y.x, y.y, y.z, 0.0f},
+ {z.x, z.y, z.z, 0.0f},
+ {0.0f, 0.0f, 0.0f, 1.0f}
+ };
+ return rotate;
+}
+
+mat4 mat4_transl(mat4 m, v3 v)
+{
+ mat4 translate = mat4_make_transl(v);
+ mat4 result = mat4_mul(translate, m);
+ return result;
+}
+
+mat4 mat4_scale(mat4 m, v3 v)
+{
+ mat4 scale = mat4_make_scale(v);
+ mat4 result = mat4_mul(scale, m);
+ return result;
+}
+
+/*
+ * NOTE(pryazha): Angles in degrees
+ * | 1 0 0 | | cy 0 sy | | cz -sz 0 | | cy*cz -cy*sz sy |
+ * | 0 cx -sx |*| 0 1 0 |*| sz cz 0 |=| sx*sy*cz+cx*sz -sx*sy*sz+cx*cz -sx*cy |
+ * | 0 sx cx | | -sy 0 cy | | 0 0 1 | | -cx*sy*cz+sx*sz cx*sy*sz+sx*cz cx*cy |
+ */
+mat4 mat4_rotate(mat4 mat, v3 angles)
+{
+ f32 angle = deg2rad(angles.x);
+ f32 cx = fcos(angle);
+ f32 sx = fsin(angle);
+ angle = deg2rad(angles.y);
+ f32 cy = fcos(angle);
+ f32 sy = fsin(angle);
+ angle = deg2rad(angles.z);
+ f32 cz = fcos(angle);
+ f32 sz = fsin(angle);
+
+ v3 x = {cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz};
+ v3 y = {-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz};
+ v3 z = {sy, -sx*cy, cx*cy};
+ mat4 rotate = mat4_make_rotate(x, y, z);
+
+ mat4 result = mat4_mul(rotate, mat);
+
+ return result;
+}
+
+v4 mat4_v4_mul(mat4 m, v4 v)
+{
+ v4 result = {
+ m.c0.x*v.x+m.c1.x*v.y+m.c2.x*v.z+m.c3.x*v.w,
+ m.c0.y*v.x+m.c1.y*v.y+m.c2.y*v.z+m.c3.y*v.w,
+ m.c0.z*v.x+m.c1.z*v.y+m.c2.z*v.z+m.c3.z*v.w,
+ m.c0.w*v.x+m.c1.w*v.y+m.c2.w*v.z+m.c3.w*v.w
+ };
+ return result;
+}
+
+i32 in_rect(v2 pos, rect_t rect)
+{
+ i32 result = (pos.x > rect.start.x) && (pos.x < rect.end.x) &&
+ (pos.y > rect.start.y) && (pos.y < rect.end.y);
+ return result;
+}
+