]> git.lizzy.rs Git - shadowclad.git/blob - src/engine/geometry.c
c37eb4aecaa60ad8f1df2f5b75593ef3e8d4d264
[shadowclad.git] / src / engine / geometry.c
1 #include "geometry.h"
2
3 #include <math.h>
4 #include <stddef.h>
5
6 Transform identity() {
7         return (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f,
8                              .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f,
9                              .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = 0.0f,
10                              .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f };
11 }
12
13 Transform multiply(Transform t1, Transform t2) {
14         GLfloat* a = (GLfloat*) &t1;
15         GLfloat* b = (GLfloat*) &t2;
16         Transform result;
17         GLfloat* c = (GLfloat*) &result;
18
19         for (size_t row = 0; row < 4; ++row) {
20                 for (size_t col = 0; col < 4; ++col) {
21                         c[(row * 4) + col] =
22                                 a[(row * 4) + 0] * b[(0 * 4) + col]
23                                 + a[(row * 4) + 1] * b[(1 * 4) + col]
24                                 + a[(row * 4) + 2] * b[(2 * 4) + col]
25                                 + a[(row * 4) + 3] * b[(3 * 4) + col];
26                 }
27         }
28         return result;
29 }
30
31 void translate(Transform* transform, Vector vec) {
32         *transform = multiply(
33                 (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x,
34                               .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y,
35                               .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = vec.z,
36                               .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f },
37                 *transform);
38 }
39
40 void rotate(Transform* transform, Vector axis, float angle) {
41         axis = normalized(axis);
42         float l = axis.x;
43         float m = axis.y;
44         float n = axis.z;
45         float sinA = sinf(angle);
46         float cosA = cosf(angle);
47         float omcA = 1 - cosA;
48
49         *transform = multiply(
50                 (Transform) { l*l*omcA + cosA, m*l*omcA - n*sinA, n*l*omcA + m*sinA, 0.0f,
51                               l*m*omcA + n*sinA, m*m*omcA + cosA, n*m*omcA - l*sinA, 0.0f,
52                               l*n*omcA - m*sinA, m*n*omcA + l*sinA, n*n*omcA + cosA, 0.0f,
53                               0.0f, 0.0f, 0.0f, 1.0f },
54                 *transform);
55 }
56
57 Vector addVectors(Vector v1, Vector v2){
58         return (Vector) { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
59 }
60
61 Vector subtractVectors(Vector v1, Vector v2) {
62         return (Vector) { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
63 }
64
65 Vector crossProduct(Vector v1, Vector v2) {
66         return (Vector) { .x = (v1.y * v2.z) - (v1.z * v2.y),
67                           .y = (v1.z * v2.x) - (v1.x * v2.z),
68                           .z = (v1.x * v2.y) - (v1.y * v2.x) };
69 }
70
71 float dotProduct(Vector v1, Vector v2) {
72         return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
73 }
74
75 Vector scaleVector(Vector vec, float scale) {
76         return (Vector) { vec.x * scale,
77                           vec.y * scale,
78                           vec.z * scale };
79 }
80
81 Vector growVectorNoFlip(Vector vec, float amount) {
82         float mag = magnitude(vec);
83         float factor = (mag + amount) / mag;
84         if (factor < 0.0f) {
85                 factor = 0.0f;
86         }
87         return scaleVector(vec, factor);
88 }
89
90 Vector clampMagnitude(Vector vec, float maxMagnitude) {
91         float m = magnitude(vec);
92         if (m > maxMagnitude) {
93                 vec = scaleVector(vec, maxMagnitude / m);
94         }
95         return vec;
96 }
97
98 float magnitude(Vector vec) {
99         return sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
100 }
101
102 Vector applyTransform(Transform transform, Vector vec) {
103         GLfloat* a = (GLfloat*) &transform;
104         GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
105         GLfloat c[4];
106
107         for (size_t row = 0; row < 4; ++row) {
108                 c[row] =
109                         a[(row * 4) + 0] * b[0]
110                         + a[(row * 4) + 1] * b[1]
111                         + a[(row * 4) + 2] * b[2]
112                         + a[(row * 4) + 3] * b[3];
113         }
114         return (Vector) { c[0], c[1], c[2] };
115 }
116
117 Vector translationOf(Transform transform) {
118         return (Vector) { transform.a4, transform.b4, transform.c4 };
119 }
120
121 Vector normalized(Vector vec) {
122         float m = magnitude(vec);
123         return (Vector) { vec.x / m, vec.y / m, vec.z / m };
124 }