+/**
+ * Copyright 2018-2020 Iwo 'Outfrost' Bujkiewicz
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
#include "geometry.h"
#include <math.h>
#include <stddef.h>
-const float TAU = 6.28318530718f;
-
-
-
Transform identity() {
return (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f,
.b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f,
Transform multiply(Transform t1, Transform t2) {
GLfloat* a = (GLfloat*) &t1;
GLfloat* b = (GLfloat*) &t2;
+ Transform result;
+ GLfloat* c = (GLfloat*) &result;
for (size_t row = 0; row < 4; ++row) {
for (size_t col = 0; col < 4; ++col) {
- b[(row * 4) + col] =
+ c[(row * 4) + col] =
a[(row * 4) + 0] * b[(0 * 4) + col]
+ a[(row * 4) + 1] * b[(1 * 4) + col]
+ a[(row * 4) + 2] * b[(2 * 4) + col]
+ a[(row * 4) + 3] * b[(3 * 4) + col];
}
}
- return t2;
+ return result;
}
-void translate(Transform* transform, Vector3D vec) {
+void translate(Transform* transform, Vector vec) {
*transform = multiply(
(Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x,
.b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y,
*transform);
}
-void rotate(Transform* transform, Vector3D axis, float angle) {
+void rotate(Transform* transform, Vector axis, float angle) {
axis = normalized(axis);
float l = axis.x;
float m = axis.y;
float sinA = sinf(angle);
float cosA = cosf(angle);
float omcA = 1 - cosA;
+
*transform = multiply(
(Transform) { l*l*omcA + cosA, m*l*omcA - n*sinA, n*l*omcA + m*sinA, 0.0f,
l*m*omcA + n*sinA, m*m*omcA + cosA, n*m*omcA - l*sinA, 0.0f,
*transform);
}
-Vector3D applyTransform(Transform* transform, Vector3D vec) {
+Vector zeroVector() {
+ return (Vector) { 0.0f, 0.0f, 0.0f };
+}
+
+Vector addVectors(Vector v1, Vector v2) {
+ return (Vector) { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+}
+
+Vector subtractVectors(Vector v1, Vector v2) {
+ return (Vector) { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+}
+
+Vector crossProduct(Vector v1, Vector v2) {
+ return (Vector) { .x = (v1.y * v2.z) - (v1.z * v2.y),
+ .y = (v1.z * v2.x) - (v1.x * v2.z),
+ .z = (v1.x * v2.y) - (v1.y * v2.x) };
+}
+
+float dotProduct(Vector v1, Vector v2) {
+ return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
+}
+
+Vector scaleVector(Vector vec, float scale) {
+ return (Vector) { vec.x * scale,
+ vec.y * scale,
+ vec.z * scale };
+}
+
+Vector growVectorNoFlip(Vector vec, float amount) {
+ float mag = magnitude(vec);
+ float factor = (mag + amount) / mag;
+ if (factor < 0.0f) {
+ factor = 0.0f;
+ }
+ return scaleVector(vec, factor);
+}
+
+Vector clampMagnitude(Vector vec, float maxMagnitude) {
+ float m = magnitude(vec);
+ if (m > maxMagnitude) {
+ vec = scaleVector(vec, maxMagnitude / m);
+ }
+ return vec;
+}
+
+float magnitude(Vector vec) {
+ return sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
+}
+
+Vector applyTransform(Transform transform, Vector vec) {
GLfloat* a = (GLfloat*) &transform;
GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
GLfloat c[4];
+ a[(row * 4) + 2] * b[2]
+ a[(row * 4) + 3] * b[3];
}
- return (Vector3D) { c[0], c[1], c[2] };
+ return (Vector) { c[0], c[1], c[2] };
+}
+
+Vector translationOf(Transform transform) {
+ return (Vector) { transform.a4, transform.b4, transform.c4 };
}
-Vector3D translationOf(Transform transform) {
- return (Vector3D) { transform.a4, transform.b4, transform.c4 };
+Vector normalized(Vector vec) {
+ float m = magnitude(vec);
+ return (Vector) { vec.x / m, vec.y / m, vec.z / m };
}
-Vector3D normalized(Vector3D vec) {
- float magnitude = sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
- return (Vector3D) {vec.x / magnitude, vec.y / magnitude, vec.z / magnitude};
+float clamp(float x, float lower, float upper) {
+ return fmax(lower, fmin(upper, x));
}