summaryrefslogtreecommitdiff
path: root/Podium/p_math.c
diff options
context:
space:
mode:
Diffstat (limited to 'Podium/p_math.c')
-rw-r--r--Podium/p_math.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/Podium/p_math.c b/Podium/p_math.c
new file mode 100644
index 0000000..928738b
--- /dev/null
+++ b/Podium/p_math.c
@@ -0,0 +1,255 @@
+PODEF
+int p_ceil(float x)
+{
+ int base = (int) x;
+ return (x > base) ? base + 1 : base;
+}
+
+PODEF float
+p_cosf(float x)
+{
+ x += 1.57079632679f;
+
+ while (x > P_PI) x -= P_PI2;
+ while (x < -P_PI) x += P_PI2;
+
+ const float B = 4.0f / P_PI;
+ const float C = -4.0f / P_PI_POW2;
+
+ float y = B * x + C * x * (x < 0 ? -x : x);
+
+ const float P = 0.225f;
+ y = P * (y * (y < 0 ? -y : y) - y) + y;
+
+ return y;
+}
+
+PODEF float
+p_sinf(float x)
+{
+ while (x > P_PI) x -= P_PI2;
+ while (x < -P_PI) x += P_PI2;
+
+ const float B = 4.0f / P_PI;
+ const float C = -4.0f / (P_PI_POW2);
+
+ float y = B * x + C * x * (x < 0 ? -x : x);
+
+ const float P = 0.225f;
+ y = P * (y * (y < 0 ? -y : y) - y) + y;
+
+ return y;
+}
+
+PODEF Vec2f
+p_vec2f(float x, float y)
+{
+ return (Vec2f) { .x = x, .y = y };
+}
+
+PODEF Vec2f
+p_vec2f_add(Vec2f a, Vec2f b)
+{
+ return (Vec2f) {
+ .x = a.x + b.x,
+ .y = a.y + b.y,
+ };
+}
+
+PODEF float
+p_vec2f_cross(Vec2f a, Vec2f b)
+{
+ // axby − aybx
+ return a.x * b.y - a.y * b.x;
+}
+
+PODEF float
+p_vec2f_dot(Vec2f a, Vec2f b)
+{
+ // a · b = ax × bx + ay × by
+ return a.x * b.x + a.y * b.y;
+}
+
+PODEF Vec2f
+p_vec2f_mult(Vec2f a, float b)
+{
+ return (Vec2f) {
+ .x = a.x * b,
+ .y = a.y * b,
+ };
+}
+
+PODEF Vec2f
+p_vec2f_sub(Vec2f a, Vec2f b)
+{
+ return (Vec2f) {
+ .x = a.x - b.x,
+ .y = a.y - b.y,
+ };
+}
+
+PODEF Vec2i
+p_vec2i(float x, float y)
+{
+ return (Vec2i) { .x = x, .y = y };
+}
+
+PODEF Vec2i
+p_vec2i_add(Vec2i a, Vec2i b)
+{
+ return (Vec2i) {
+ .x = a.x + b.x,
+ .y = a.y + b.y,
+ };
+}
+
+PODEF float
+p_vec2i_cross(Vec2i a, Vec2i b)
+{
+ // axby − aybx
+ return a.x * b.y - a.y * b.x;
+}
+
+PODEF float
+p_vec2i_dot(Vec2i a, Vec2i b)
+{
+ // a · b = ax × bx + ay × by
+ return a.x * b.x + a.y * b.y;
+}
+
+PODEF Vec2i
+p_vec2i_mult(Vec2i a, float b)
+{
+ return (Vec2i) {
+ .x = a.x * b,
+ .y = a.y * b,
+ };
+}
+
+PODEF Vec2i
+p_vec2i_sub(Vec2i a, Vec2i b)
+{
+ return (Vec2i) {
+ .x = a.x - b.x,
+ .y = a.y - b.y,
+ };
+}
+
+PODEF Vec3f
+p_vec3f(float x, float y, float z)
+{
+ return (Vec3f) { .x = x, .y = y, .z = z };
+}
+
+PODEF P_Mat4
+p_mat4_identity(void)
+{
+ P_Mat4 res = {0};
+ res.m[0] = 1.0f;
+ res.m[5] = 1.0f;
+ res.m[10] = 1.0f;
+ res.m[15] = 1.0f;
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_mul(P_Mat4 a, P_Mat4 b)
+{
+ P_Mat4 res = {0};
+ for (int col = 0; col < 4; ++col) {
+ for (int row = 0; row < 4; ++row) {
+ float sum = 0.0f;
+ for (int k = 0; k < 4; ++k) {
+ sum += a.m[k * 4 + row] * b.m[col * 4 + k];
+ }
+ res.m[col * 4 + row] = sum;
+ }
+ }
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_translate(Vec3f v)
+{
+ P_Mat4 res = p_mat4_identity();
+ res.m[12] = v.x;
+ res.m[13] = v.y;
+ res.m[14] = v.z;
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_translate_by(P_Mat4 m, Vec3f v)
+{
+ P_Mat4 res = m;
+ res.m[12] = m.m[0] * v.x + m.m[4] * v.y + m.m[8] * v.z + m.m[12];
+ res.m[13] = m.m[1] * v.x + m.m[5] * v.y + m.m[9] * v.z + m.m[13];
+ res.m[14] = m.m[2] * v.x + m.m[6] * v.y + m.m[10] * v.z + m.m[14];
+ res.m[15] = m.m[3] * v.x + m.m[7] * v.y + m.m[11] * v.z + m.m[15];
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_rotate_x(float rad)
+{
+ P_Mat4 res = p_mat4_identity();
+ float c = p_cosf(rad);
+ float s = p_sinf(rad);
+ res.m[5] = c;
+ res.m[6] = s;
+ res.m[9] = -s;
+ res.m[10] = c;
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_rotate_x_by(P_Mat4 m, float rad)
+{
+ return p_mat4_mul(m, p_mat4_rotate_x(rad));
+}
+
+PODEF P_Mat4
+p_mat4_rotate_y(float rad)
+{
+ P_Mat4 res = p_mat4_identity();
+ float c = p_cosf(rad);
+ float s = p_sinf(rad);
+ res.m[0] = c;
+ res.m[2] = -s;
+ res.m[8] = s;
+ res.m[10] = c;
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_rotate_y_by(P_Mat4 m, float rad)
+{
+ return p_mat4_mul(m, p_mat4_rotate_y(rad));
+}
+
+PODEF P_Mat4
+p_mat4_rotate_z(float rad)
+{
+ P_Mat4 res = p_mat4_identity();
+ float c = p_cosf(rad);
+ float s = p_sinf(rad);
+ res.m[0] = c;
+ res.m[1] = s;
+ res.m[4] = -s;
+ res.m[5] = c;
+ return res;
+}
+
+PODEF P_Mat4
+p_mat4_perspective(float fov_rad, float aspect, float near_z, float far_z)
+{
+ P_Mat4 res = {0};
+ float tan_half_fov = p_sinf(fov_rad * 0.5f) / p_cosf(fov_rad * 0.5f);
+
+ res.m[0] = 1.0f / (aspect * tan_half_fov);
+ res.m[5] = 1.0f / tan_half_fov;
+ res.m[10] = far_z / (near_z - far_z);
+ res.m[11] = -1.0f;
+ res.m[14] = (near_z * far_z) / (near_z - far_z);
+ return res;
+}