6 const float TAU = 6.28318530718f;
10 Transform identity() {
11 return (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f,
12 .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f,
13 .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = 0.0f,
14 .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f };
17 Transform multiply(Transform t1, Transform t2) {
18 GLfloat* a = (GLfloat*) &t1;
19 GLfloat* b = (GLfloat*) &t2;
21 GLfloat* c = (GLfloat*) &result;
23 for (size_t row = 0; row < 4; ++row) {
24 for (size_t col = 0; col < 4; ++col) {
26 a[(row * 4) + 0] * b[(0 * 4) + col]
27 + a[(row * 4) + 1] * b[(1 * 4) + col]
28 + a[(row * 4) + 2] * b[(2 * 4) + col]
29 + a[(row * 4) + 3] * b[(3 * 4) + col];
35 void translate(Transform* transform, Vector3D vec) {
36 *transform = multiply(
37 (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x,
38 .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y,
39 .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = vec.z,
40 .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f },
44 void rotate(Transform* transform, Vector3D axis, float angle) {
45 axis = normalized(axis);
49 float sinA = sinf(angle);
50 float cosA = cosf(angle);
51 float omcA = 1 - cosA;
53 *transform = multiply(
54 (Transform) { l*l*omcA + cosA, m*l*omcA - n*sinA, n*l*omcA + m*sinA, 0.0f,
55 l*m*omcA + n*sinA, m*m*omcA + cosA, n*m*omcA - l*sinA, 0.0f,
56 l*n*omcA - m*sinA, m*n*omcA + l*sinA, n*n*omcA + cosA, 0.0f,
57 0.0f, 0.0f, 0.0f, 1.0f },
61 Vector3D applyTransform(Transform transform, Vector3D vec) {
62 GLfloat* a = (GLfloat*) &transform;
63 GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
66 for (size_t row = 0; row < 4; ++row) {
68 a[(row * 4) + 0] * b[0]
69 + a[(row * 4) + 1] * b[1]
70 + a[(row * 4) + 2] * b[2]
71 + a[(row * 4) + 3] * b[3];
73 return (Vector3D) { c[0], c[1], c[2] };
76 Vector3D translationOf(Transform transform) {
77 return (Vector3D) { transform.a4, transform.b4, transform.c4 };
80 Vector3D normalized(Vector3D vec) {
81 float magnitude = sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
82 return (Vector3D) {vec.x / magnitude, vec.y / magnitude, vec.z / magnitude};