Finish internal math library;

This commit is contained in:
bjorn 2017-01-18 00:51:09 -08:00
parent fdb363df4b
commit e8e2a99e5b
18 changed files with 520 additions and 340 deletions

View File

@ -1,5 +1,6 @@
#include "graphics/graphics.h"
#include "loaders/texture.h"
#include "math/quat.h"
#include "util.h"
#include "glfw.h"
#define _USE_MATH_DEFINES
@ -39,7 +40,7 @@ void lovrGraphicsDestroy() {
lovrGraphicsSetShader(NULL);
glUseProgram(0);
for (int i = 0; i < MAX_TRANSFORMS; i++) {
mat4_deinit(state.transforms[i]);
free(state.transforms[i]);
}
for (int i = 0; i < MAX_CANVASES; i++) {
free(state.canvases[i]);
@ -203,7 +204,7 @@ mat4 lovrGraphicsGetProjection() {
void lovrGraphicsSetProjection(float near, float far, float fov) {
int width, height;
glfwGetWindowSize(window, &width, &height);
mat4_setPerspective(state.canvases[state.canvas]->projection, near, far, fov, (float) width / height);
mat4_perspective(state.canvases[state.canvas]->projection, near, far, fov, (float) width / height);
}
void lovrGraphicsSetProjectionRaw(mat4 projection) {
@ -333,7 +334,7 @@ int lovrGraphicsPop() {
}
void lovrGraphicsOrigin() {
mat4_setIdentity(state.transforms[state.transform]);
mat4_identity(state.transforms[state.transform]);
}
void lovrGraphicsTranslate(float x, float y, float z) {
@ -341,7 +342,10 @@ void lovrGraphicsTranslate(float x, float y, float z) {
}
void lovrGraphicsRotate(float angle, float ax, float ay, float az) {
mat4_rotate(state.transforms[state.transform], angle, ax, ay, az);
float rotation[4];
float axis[3] = { ax, ay, az };
quat_fromAngleAxis(rotation, angle, axis);
mat4_rotate(state.transforms[state.transform], rotation);
}
void lovrGraphicsScale(float x, float y, float z) {
@ -349,12 +353,16 @@ void lovrGraphicsScale(float x, float y, float z) {
}
void lovrGraphicsTransform(float tx, float ty, float tz, float sx, float sy, float sz, float angle, float ax, float ay, float az) {
float rotation[4];
float axis[3] = { ax, ay, az };
quat_fromAngleAxis(rotation, angle, axis);
// M *= T * S * R
float transform[16];
mat4_setTranslation(transform, tx, ty, tz);
mat4_identity(transform);
mat4_translate(transform, tx, ty, tz);
mat4_scale(transform, sx, sy, sz);
mat4_rotate(transform, angle, ax, ay, az);
mat4_rotate(transform, rotation);
lovrGraphicsMatrixTransform(transform);
}

View File

@ -3,7 +3,7 @@
#include "graphics/shader.h"
#include "graphics/skybox.h"
#include "graphics/texture.h"
#include "matrix.h"
#include "math/mat4.h"
#ifndef LOVR_GRAPHICS_TYPES
#define LOVR_GRAPHICS_TYPES

View File

@ -3,12 +3,10 @@
#include <stdlib.h>
static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec_float_t* vertices, vec_uint_t* indices) {
mat4 newTransform;
mat4 newTransform = mat4_init();
if (!transform) {
newTransform = mat4_init();
} else {
newTransform = mat4_copy(transform);
if (transform) {
mat4_set(newTransform, transform);
}
mat4_multiply(newTransform, node->transform);
@ -23,15 +21,14 @@ static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec
for (int v = 0; v < mesh->vertices.length; v++) {
ModelVertex vertex = mesh->vertices.data[v];
float transformedVertex[4] = {
float vec[3] = {
vertex.x,
vertex.y,
vertex.z,
1.f
vertex.z
};
mat4_multiplyVector(newTransform, transformedVertex);
vec_pusharr(vertices, transformedVertex, 3);
vec3_transform(vec, newTransform);
vec_pusharr(vertices, vec, 3);
if (modelData->hasNormals) {
ModelVertex normal = mesh->normals.data[v];
@ -60,7 +57,7 @@ static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec
visitNode(modelData, node->children.data[c], newTransform, vertices, indices);
}
mat4_deinit(newTransform);
free(newTransform);
}
Model* lovrModelCreate(ModelData* modelData) {
@ -136,7 +133,7 @@ void lovrModelDataDestroy(ModelData* modelData) {
while (nodes.length > 0) {
ModelNode* node = vec_first(&nodes);
vec_extend(&nodes, &node->children);
mat4_deinit(node->transform);
free(node->transform);
vec_deinit(&node->meshes);
vec_deinit(&node->children);
vec_splice(&nodes, 0, 1);

View File

@ -1,6 +1,7 @@
#include "graphics/buffer.h"
#include "graphics/texture.h"
#include "matrix.h"
#include "math/mat4.h"
#include "math/vec3.h"
#include "glfw.h"
#include "util.h"
#include "vendor/vec/vec.h"

View File

@ -175,8 +175,8 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
void lovrShaderDestroy(const Ref* ref) {
Shader* shader = containerof(ref, Shader);
glDeleteProgram(shader->id);
mat4_deinit(shader->transform);
mat4_deinit(shader->projection);
free(shader->transform);
free(shader->projection);
map_deinit(&shader->uniforms);
free(shader);
}

View File

@ -1,5 +1,5 @@
#include "glfw.h"
#include "matrix.h"
#include "math/mat4.h"
#include "vendor/map/map.h"
#include "util.h"

View File

@ -109,7 +109,7 @@ void lovrTextureBindFramebuffer(Texture* texture) {
if (texture->projection == PROJECTION_ORTHOGRAPHIC) {
float projection[16];
mat4_setOrthographic(projection, 0, w, 0, h, -1, 1);
mat4_orthographic(projection, 0, w, 0, h, -1, 1);
lovrGraphicsSetProjectionRaw(projection);
} else if (texture->projection == PROJECTION_PERSPECTIVE) {
mat4 projection = lovrGraphicsGetProjection();
@ -122,7 +122,7 @@ void lovrTextureBindFramebuffer(Texture* texture) {
float far = k * near;
float fov = 2.f * atan(1.f / b);
float newProjection[16];
mat4_setPerspective(newProjection, near, far, fov, aspect);
mat4_perspective(newProjection, near, far, fov, aspect);
lovrGraphicsSetProjectionRaw(newProjection);
}
}

View File

@ -2,6 +2,8 @@
#include "event/event.h"
#include "graphics/graphics.h"
#include "loaders/texture.h"
#include "math/mat4.h"
#include "math/quat.h"
#include "util.h"
#include <stdlib.h>
#include <stdint.h>
@ -265,7 +267,9 @@ void viveGetOrientation(void* headset, float* w, float* x, float* y, float *z) {
}
float matrix[16];
mat4_getRotation(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), w, x, y, z);
float rotation[4];
mat4_toQuat(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), rotation);
quat_toAngleAxis(rotation, w, x, y, z);
}
void viveGetVelocity(void* headset, float* x, float* y, float* z) {
@ -349,7 +353,9 @@ void viveControllerGetOrientation(void* headset, Controller* controller, float*
}
float matrix[16];
mat4_getRotation(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), w, x, y, z);
float rotation[4];
mat4_toQuat(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), rotation);
quat_toAngleAxis(rotation, w, x, y, z);
}
float viveControllerGetAxis(void* headset, Controller* controller, ControllerAxis axis) {

View File

@ -9,7 +9,7 @@ static void assimpNodeTraversal(ModelNode* node, struct aiNode* assimpNode) {
// Transform
struct aiMatrix4x4 m = assimpNode->mTransformation;
aiTransposeMatrix4(&m);
node->transform = mat4_copy((float*) &m);
node->transform = mat4_set(mat4_init(), (float*) &m);
// Meshes
vec_init(&node->meshes);

257
src/math/mat4.c Normal file
View File

@ -0,0 +1,257 @@
#include "math/mat4.h"
#include "util.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
// m0 m4 m8 m12
// m1 m5 m9 m13
// m2 m6 m10 m14
// m3 m7 m11 m15
mat4 mat4_init() {
mat4 m = malloc(16 * sizeof(float));
return mat4_identity(m);
}
mat4 mat4_fromMat34(mat4 m, float (*n)[4]) {
m[0] = n[0][0];
m[1] = n[1][0];
m[2] = n[2][0];
m[3] = 0.f;
m[4] = n[0][1];
m[5] = n[1][1];
m[6] = n[2][1];
m[7] = 0.f;
m[8] = n[0][2];
m[9] = n[1][2];
m[10] = n[2][2];
m[11] = 0.f;
m[12] = n[0][3];
m[13] = n[1][3];
m[14] = n[2][3];
m[15] = 1.f;
return m;
}
mat4 mat4_fromMat44(mat4 m, float (*n)[4]) {
m[0] = n[0][0];
m[1] = n[1][0];
m[2] = n[2][0];
m[3] = n[3][0];
m[4] = n[0][1];
m[5] = n[1][1];
m[6] = n[2][1];
m[7] = n[3][1];
m[8] = n[0][2];
m[9] = n[1][2];
m[10] = n[2][2];
m[11] = n[3][2];
m[12] = n[0][3];
m[13] = n[1][3];
m[14] = n[2][3];
m[15] = n[3][3];
return m;
}
mat4 mat4_set(mat4 m, mat4 n) {
return memcpy(m, n, 16 * sizeof(float));
}
mat4 mat4_identity(mat4 m) {
memset(m, 0, 16 * sizeof(float));
m[0] = m[5] = m[10] = m[15] = 1.f;
return m;
}
mat4 mat4_transpose(mat4 m) {
float m1 = m[1];
float m2 = m[2];
float m3 = m[3];
float m6 = m[6];
float m7 = m[7];
float m11 = m[11];
m[1] = m[4];
m[2] = m[8];
m[3] = m[12];
m[4] = m1;
m[6] = m[9];
m[7] = m[13];
m[8] = m2;
m[9] = m6;
m[11] = m[14];
m[12] = m3;
m[13] = m7;
m[14] = m11;
return m;
}
// Modified from gl-matrix.c
mat4 mat4_invert(mat4 m) {
float a00 = m[0], a01 = m[1], a02 = m[2], a03 = m[3],
a10 = m[4], a11 = m[5], a12 = m[6], a13 = m[7],
a20 = m[8], a21 = m[9], a22 = m[10], a23 = m[11],
a30 = m[12], a31 = m[13], a32 = m[14], a33 = m[15],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,
d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06),
invDet;
if (!d) { return NULL; }
invDet = 1 / d;
m[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
m[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
m[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
m[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
m[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
m[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
m[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
m[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
m[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
m[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
m[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
m[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
m[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
m[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
m[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
m[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
return m;
}
// Modified from gl-matrix.c
mat4 mat4_multiply(mat4 m, mat4 n) {
float m00 = m[0], m01 = m[1], m02 = m[2], m03 = m[3],
m10 = m[4], m11 = m[5], m12 = m[6], m13 = m[7],
m20 = m[8], m21 = m[9], m22 = m[10], m23 = m[11],
m30 = m[12], m31 = m[13], m32 = m[14], m33 = m[15],
n00 = n[0], n01 = n[1], n02 = n[2], n03 = n[3],
n10 = n[4], n11 = n[5], n12 = n[6], n13 = n[7],
n20 = n[8], n21 = n[9], n22 = n[10], n23 = n[11],
n30 = n[12], n31 = n[13], n32 = n[14], n33 = n[15];
m[0] = n00 * m00 + n01 * m10 + n02 * m20 + n03 * m30;
m[1] = n00 * m01 + n01 * m11 + n02 * m21 + n03 * m31;
m[2] = n00 * m02 + n01 * m12 + n02 * m22 + n03 * m32;
m[3] = n00 * m03 + n01 * m13 + n02 * m23 + n03 * m33;
m[4] = n10 * m00 + n11 * m10 + n12 * m20 + n13 * m30;
m[5] = n10 * m01 + n11 * m11 + n12 * m21 + n13 * m31;
m[6] = n10 * m02 + n11 * m12 + n12 * m22 + n13 * m32;
m[7] = n10 * m03 + n11 * m13 + n12 * m23 + n13 * m33;
m[8] = n20 * m00 + n21 * m10 + n22 * m20 + n23 * m30;
m[9] = n20 * m01 + n21 * m11 + n22 * m21 + n23 * m31;
m[10] = n20 * m02 + n21 * m12 + n22 * m22 + n23 * m32;
m[11] = n20 * m03 + n21 * m13 + n22 * m23 + n23 * m33;
m[12] = n30 * m00 + n31 * m10 + n32 * m20 + n33 * m30;
m[13] = n30 * m01 + n31 * m11 + n32 * m21 + n33 * m31;
m[14] = n30 * m02 + n31 * m12 + n32 * m22 + n33 * m32;
m[15] = n30 * m03 + n31 * m13 + n32 * m23 + n33 * m33;
return m;
}
mat4 mat4_translate(mat4 m, float x, float y, float z) {
m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
return m;
}
mat4 mat4_scale(mat4 m, float x, float y, float z) {
m[0] *= x;
m[1] *= x;
m[2] *= x;
m[3] *= x;
m[4] *= y;
m[5] *= y;
m[6] *= y;
m[7] *= y;
m[8] *= z;
m[9] *= z;
m[10] *= z;
m[11] *= z;
return m;
}
mat4 mat4_rotate(mat4 m, quat q) {
float x = q[0];
float y = q[1];
float z = q[2];
float w = q[3];
float rotation[16];
mat4_identity(rotation);
rotation[0] = 1 - 2 * y * y - 2 * z * z;
rotation[1] = 2 * x * y + 2 * w * z;
rotation[2] = 2 * x * z - 2 * w * y;
rotation[4] = 2 * x * y - 2 * w * z;
rotation[5] = 1 - 2 * x * x - 2 * z * z;
rotation[6] = 2 * y * z + 2 * w * x;
rotation[8] = 2 * x * z + 2 * w * y;
rotation[9] = 2 * y * z - 2 * w * x;
rotation[10] = 1 - 2 * x * x - 2 * y * y;
return mat4_multiply(m, rotation);
}
mat4 mat4_orthographic(mat4 m, float left, float right, float top, float bottom, float near, float far) {
float rl = right - left;
float tb = top - bottom;
float fn = far - near;
mat4_identity(m);
m[0] = 2 / rl;
m[5] = 2 / tb;
m[10] = -2 / fn;
m[12] = -(left + right) / rl;
m[13] = -(top + bottom) / tb;
m[14] = -(far + near) / fn;
m[15] = 1;
return m;
}
mat4 mat4_perspective(mat4 m, float near, float far, float fovy, float aspect) {
float range = tan(fovy * .5f) * near;
float sx = (2.0f * near) / (range * aspect + range * aspect);
float sy = near / range;
float sz = -(far + near) / (far - near);
float pz = (-2.0f * far * near) / (far - near);
mat4_identity(m);
m[0] = sx;
m[5] = sy;
m[10] = sz;
m[11] = -1.0f;
m[14] = pz;
m[15] = 0.0f;
return m;
}
quat mat4_toQuat(mat4 m, quat q) {
float x = sqrt(MAX(0, 1 + m[0] - m[5] - m[10])) / 2;
float y = sqrt(MAX(0, 1 - m[0] + m[5] - m[10])) / 2;
float z = sqrt(MAX(0, 1 - m[0] - m[5] + m[10])) / 2;
float w = sqrt(MAX(0, 1 + m[0] + m[5] + m[10])) / 2;
x = (m[9] - m[6]) > 0 ? -x : x;
y = (m[2] - m[8]) > 0 ? -y : y;
z = (m[4] - m[1]) > 0 ? -z : z;
q[0] = x;
q[1] = y;
q[2] = z;
q[3] = w;
return q;
}

16
src/math/mat4.h Normal file
View File

@ -0,0 +1,16 @@
#include "math/math.h"
mat4 mat4_init();
mat4 mat4_fromMat34(mat4 m, float (*n)[4]);
mat4 mat4_fromMat44(mat4 m, float (*n)[4]);
mat4 mat4_set(mat4 m, mat4 n);
mat4 mat4_identity(mat4 m);
mat4 mat4_transpose(mat4 m);
mat4 mat4_invert(mat4 m);
mat4 mat4_multiply(mat4 m, mat4 n);
mat4 mat4_translate(mat4 m, float x, float y, float z);
mat4 mat4_scale(mat4 m, float x, float y, float z);
mat4 mat4_rotate(mat4 m, quat q);
mat4 mat4_orthographic(mat4 m, float left, float right, float top, float bottom, float near, float far);
mat4 mat4_perspective(mat4 m, float near, float far, float fov, float aspect);
quat mat4_toQuat(mat4 m, quat q);

9
src/math/math.h Normal file
View File

@ -0,0 +1,9 @@
#include "vendor/vec/vec.h"
#ifndef LOVR_MATH_TYPES
#define LOVR_MATH_TYPES
typedef float* vec3;
typedef float* quat;
typedef float* mat4;
typedef vec_t(mat4) vec_mat4_t;
#endif

144
src/math/quat.c Normal file
View File

@ -0,0 +1,144 @@
#include "math/quat.h"
#include "math/vec3.h"
#include <math.h>
#include <stdlib.h>
quat quat_init(float x, float y, float z, float w) {
quat q = malloc(4 * sizeof(float));
q[0] = x;
q[1] = y;
q[2] = z;
q[3] = w;
return q;
}
quat quat_fromAngleAxis(quat q, float angle, vec3 axis) {
vec3_normalize(axis);
float s = sin(angle * .5f);
float c = cos(angle * .5f);
q[0] = s * axis[0];
q[1] = s * axis[1];
q[2] = s * axis[2];
q[3] = c;
return q;
}
quat quat_fromDirection(quat q, vec3 forward, vec3 up) {
vec3 qq = (vec3) q;
vec3_set(qq, forward);
vec3_normalize(qq);
vec3_normalize(up);
q[3] = 1 + vec3_dot(qq, up);
vec3_cross(qq, up);
return q;
}
quat quat_set(quat q, quat r) {
q[0] = r[0];
q[1] = r[1];
q[2] = r[2];
q[3] = r[3];
return q;
}
quat quat_multiply(quat q, quat r) {
float qx = q[0];
float qy = q[1];
float qz = q[2];
float qw = q[3];
float rx = r[0];
float ry = r[1];
float rz = r[2];
float rw = r[3];
q[0] = qx * rw + qw * rx - qy * rz - qz * ry;
q[1] = qy * rw + qw * ry - qz * rx - qx * rz;
q[2] = qz * rw + qw * rz - qx * ry - qy * rx;
q[3] = qw * rw - qx * rx - qy * ry - qz * rz;
return q;
}
quat quat_normalize(quat q) {
float len = quat_length(q);
if (len == 0) {
return q;
}
len = 1 / len;
q[0] *= len;
q[1] *= len;
q[2] *= len;
q[3] *= len;
return q;
}
float quat_length(quat q) {
return sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
}
// From gl-matrix
quat quat_slerp(quat q, quat r, float t) {
float dot = q[0] * r[0] + q[1] * r[1] + q[2] * r[2] + q[3] * r[3];
if (fabs(dot) >= 1.f) {
return q;
}
float halfTheta = acos(dot);
float sinHalfTheta = sqrt(1.f - dot * dot);
if (fabs(sinHalfTheta) < .001) {
q[0] = q[0] * .5 + r[0] * .5;
q[1] = q[1] * .5 + r[1] * .5;
q[2] = q[2] * .5 + r[2] * .5;
q[3] = q[3] * .5 + r[3] * .5;
return q;
}
float a = sin((1 - t) * halfTheta) / sinHalfTheta;
float b = sin(t * halfTheta) / sinHalfTheta;
q[0] = q[0] * a + r[0] * b;
q[1] = q[1] * a + r[1] * b;
q[2] = q[2] * a + r[2] * b;
q[3] = q[3] * a + r[3] * b;
return q;
}
quat quat_between(quat q, vec3 u, vec3 v) {
float dot = vec3_dot(u, v);
if (dot > .99999) {
q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f;
return q;
} else if (dot < -.99999) {
float axis[3] = { 1, 0, 0 };
vec3_cross(axis, u);
if (vec3_length(axis) < .00001) {
axis[0] = 0;
axis[1] = 1;
axis[2] = 0;
vec3_cross(axis, u);
}
vec3_normalize(axis);
quat_fromAngleAxis(q, M_PI, axis);
return q;
}
vec3_cross(vec3_set(q, u), v);
q[3] = 1 + dot;
return quat_normalize(q);
}
void quat_toAngleAxis(quat q, float* angle, float* x, float* y, float* z) {
if (q[3] > 1 || q[3] < -1) {
quat_normalize(q);
}
float qw = q[3];
float s = sqrt(1 - qw * qw);
s = s < .0001 ? 1 : 1 / s;
*angle = 2 * acos(qw);
*x = q[0] * s;
*y = q[1] * s;
*z = q[2] * s;
}

12
src/math/quat.h Normal file
View File

@ -0,0 +1,12 @@
#include "math/math.h"
quat quat_init(float x, float y, float z, float w);
quat quat_fromAngleAxis(quat q, float angle, vec3 axis);
quat quat_fromDirection(quat q, vec3 forward, vec3 up);
quat quat_set(quat q, quat r);
quat quat_multiply(quat q, quat r);
quat quat_normalize(quat q);
float quat_length(quat q);
quat quat_slerp(quat q, quat r, float t);
quat quat_between(quat q, vec3 u, vec3 v);
void quat_toAngleAxis(quat q, float* angle, float* x, float* y, float* z);

View File

@ -1,4 +1,5 @@
#include "math/vec3.h"
#include "math/quat.h"
#include <math.h>
#include <stdlib.h>
@ -45,8 +46,15 @@ vec3 vec3_div(vec3 v, vec3 u) {
return v;
}
vec3 vec3_scale(vec3 v, float s) {
v[0] *= s;
v[1] *= s;
v[2] *= s;
return v;
}
vec3 vec3_normalize(vec3 v) {
float len = vec3_len(v);
float len = vec3_length(v);
if (len == 0) {
return v;
}
@ -58,11 +66,11 @@ vec3 vec3_normalize(vec3 v) {
return v;
}
float vec3_len(vec3 v) {
float vec3_length(vec3 v) {
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
float vec3_dist(vec3 v, vec3 u) {
float vec3_distance(vec3 v, vec3 u) {
float dx = v[0] - u[0];
float dy = v[1] - u[1];
float dz = v[2] - u[2];
@ -70,7 +78,7 @@ float vec3_dist(vec3 v, vec3 u) {
}
float vec3_angle(vec3 v, vec3 u) {
return acos(vec3_dot(v, u) / (vec3_len(v) * vec3_len(u)));
return acos(vec3_dot(v, u) / (vec3_length(v) * vec3_length(u)));
}
float vec3_dot(vec3 v, vec3 u) {
@ -87,6 +95,30 @@ vec3 vec3_cross(vec3 v, vec3 u) {
return v;
}
vec3 vec3_rotate(vec3 v, quat q) {
float s = q[3];
float u[3];
float c[3];
vec3_set(u, q);
vec3_cross(vec3_set(c, u), v);
float uu = vec3_dot(u, u);
float uv = vec3_dot(u, v);
vec3_scale(u, 2 * uv);
vec3_scale(v, s * s - uu);
vec3_scale(c, 2 * s);
return vec3_add(v, vec3_add(u, c));
}
vec3 vec3_transform(vec3 v, mat4 m) {
float v0 = v[0];
float v1 = v[1];
float v2 = v[2];
v[0] = v0 * m[0] + v1 * m[4] + v2 * m[8] + m[12];
v[1] = v0 * m[1] + v1 * m[5] + v2 * m[9] + m[13];
v[2] = v0 * m[2] + v1 * m[6] + v2 * m[10] + m[14];
return v;
}
vec3 vec3_lerp(vec3 v, vec3 u, float t) {
v[0] += (u[0] - v[0]) * t;
v[1] += (u[1] - v[1]) * t;

View File

@ -1,7 +1,4 @@
#ifndef LOVR_VECTOR_TYPES
#define LOVR_VECTOR_TYPES
typedef float* vec3;
#endif
#include "math/math.h"
vec3 vec3_init(float x, float y, float z);
vec3 vec3_set(vec3 v, vec3 u);
@ -9,10 +6,13 @@ vec3 vec3_add(vec3 v, vec3 u);
vec3 vec3_sub(vec3 v, vec3 u);
vec3 vec3_mul(vec3 v, vec3 u);
vec3 vec3_div(vec3 v, vec3 u);
vec3 vec3_scale(vec3 v, float s);
vec3 vec3_normalize(vec3 v);
float vec3_len(vec3 v);
float vec3_dist(vec3 v, vec3 u);
float vec3_length(vec3 v);
float vec3_distance(vec3 v, vec3 u);
float vec3_angle(vec3 v, vec3 u);
float vec3_dot(vec3 v, vec3 u);
vec3 vec3_cross(vec3 v, vec3 u);
vec3 vec3_rotate(vec3 v, quat q);
vec3 vec3_transform(vec3 v, mat4 m);
vec3 vec3_lerp(vec3 v, vec3 u, float t);

View File

@ -1,276 +0,0 @@
#include "matrix.h"
#include "util.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
/*
m0 m4 m8 m12
m1 m5 m9 m13
m2 m6 m10 m14
m3 m7 m11 m15
*/
mat4 mat4_init() {
mat4 matrix = malloc(16 * sizeof(float));
return mat4_setIdentity(matrix);
}
void mat4_deinit(mat4 matrix) {
free(matrix);
}
mat4 mat4_copy(mat4 source) {
mat4 matrix = mat4_init();
memcpy(matrix, source, 16 * sizeof(float));
return matrix;
}
mat4 mat4_fromMat34(mat4 matrix, float (*source)[4]) {
matrix[0] = source[0][0];
matrix[1] = source[1][0];
matrix[2] = source[2][0];
matrix[3] = 0.f;
matrix[4] = source[0][1];
matrix[5] = source[1][1];
matrix[6] = source[2][1];
matrix[7] = 0.f;
matrix[8] = source[0][2];
matrix[9] = source[1][2];
matrix[10] = source[2][2];
matrix[11] = 0.f;
matrix[12] = source[0][3];
matrix[13] = source[1][3];
matrix[14] = source[2][3];
matrix[15] = 1.f;
return matrix;
}
mat4 mat4_fromMat44(mat4 matrix, float (*source)[4]) {
matrix[0] = source[0][0];
matrix[1] = source[1][0];
matrix[2] = source[2][0];
matrix[3] = source[3][0];
matrix[4] = source[0][1];
matrix[5] = source[1][1];
matrix[6] = source[2][1];
matrix[7] = source[3][1];
matrix[8] = source[0][2];
matrix[9] = source[1][2];
matrix[10] = source[2][2];
matrix[11] = source[3][2];
matrix[12] = source[0][3];
matrix[13] = source[1][3];
matrix[14] = source[2][3];
matrix[15] = source[3][3];
return matrix;
}
mat4 mat4_setIdentity(mat4 matrix) {
memset(matrix, 0, 16 * sizeof(float));
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
return matrix;
}
mat4 mat4_setTranslation(mat4 matrix, float x, float y, float z) {
mat4_setIdentity(matrix);
matrix[12] = x;
matrix[13] = y;
matrix[14] = z;
return matrix;
}
mat4 mat4_setRotation(mat4 matrix, float angle, float ax, float ay, float az) {
// Normalize rotation vector
float len = sqrtf(ax * ax + ay * ay + az * az);
if (len != 1 && len != 0) {
len = 1 / len;
ax *= len;
ay *= len;
az *= len;
}
// Convert angle-axis to quaternion
float cos2 = cos(angle / 2.f);
float sin2 = sin(angle / 2.f);
float w = cos2;
float x = sin2 * ax;
float y = sin2 * ay;
float z = sin2 * az;
mat4_setIdentity(matrix);
matrix[0] = 1 - 2 * y * y - 2 * z * z;
matrix[1] = 2 * x * y + 2 * w * z;
matrix[2] = 2 * x * z - 2 * w * y;
matrix[4] = 2 * x * y - 2 * w * z;
matrix[5] = 1 - 2 * x * x - 2 * z * z;
matrix[6] = 2 * y * z + 2 * w * x;
matrix[8] = 2 * x * z + 2 * w * y;
matrix[9] = 2 * y * z - 2 * w * x;
matrix[10] = 1 - 2 * x * x - 2 * y * y;
return matrix;
}
mat4 mat4_setScale(mat4 matrix, float x, float y, float z) {
mat4_setIdentity(matrix);
matrix[0] = x;
matrix[5] = y;
matrix[10] = z;
return matrix;
}
mat4 mat4_setOrthographic(mat4 matrix, float left, float right, float top, float bottom, float near, float far) {
float rl = right - left;
float tb = top - bottom;
float fn = far - near;
mat4_setIdentity(matrix);
matrix[0] = 2 / rl;
matrix[5] = 2 / tb;
matrix[10] = -2 / fn;
matrix[12] = -(left + right) / rl;
matrix[13] = -(top + bottom) / tb;
matrix[14] = -(far + near) / fn;
matrix[15] = 1;
return matrix;
}
mat4 mat4_setPerspective(mat4 matrix, float near, float far, float fov, float aspect) {
float range = tan(fov * .5f) * near;
float sx = (2.0f * near) / (range * aspect + range * aspect);
float sy = near / range;
float sz = -(far + near) / (far - near);
float pz = (-2.0f * far * near) / (far - near);
mat4_setIdentity(matrix);
matrix[0] = sx;
matrix[5] = sy;
matrix[10] = sz;
matrix[11] = -1.0f;
matrix[14] = pz;
matrix[15] = 0.0f;
return matrix;
}
void mat4_getRotation(mat4 matrix, float* w, float* x, float* y, float* z) {
float qw = sqrt(MAX(0, 1 + matrix[0] + matrix[5] + matrix[10])) / 2;
float qx = sqrt(MAX(0, 1 + matrix[0] - matrix[5] - matrix[10])) / 2;
float qy = sqrt(MAX(0, 1 - matrix[0] + matrix[5] - matrix[10])) / 2;
float qz = sqrt(MAX(0, 1 - matrix[0] - matrix[5] + matrix[10])) / 2;
qx = (matrix[9] - matrix[6]) > 0 ? -qx : qx;
qy = (matrix[2] - matrix[8]) > 0 ? -qy : qy;
qz = (matrix[4] - matrix[1]) > 0 ? -qz : qz;
float s = sqrt(1 - qw * qw);
s = s < .001 ? 1 : s;
*w = 2 * acos(qw);
*x = qx / s;
*y = qy / s;
*z = qz / s;
}
mat4 mat4_translate(mat4 matrix, float x, float y, float z) {
float translation[16];
mat4_setTranslation(translation, x, y, z);
return mat4_multiply(matrix, translation);
}
mat4 mat4_rotate(mat4 matrix, float angle, float ax, float ay, float az) {
float rotation[16];
mat4_setRotation(rotation, angle, ax, ay, az);
return mat4_multiply(matrix, rotation);
}
mat4 mat4_scale(mat4 matrix, float x, float y, float z) {
float scale[16];
mat4_setScale(scale, x, y, z);
return mat4_multiply(matrix, scale);
}
// Modified from gl-matrix.c
mat4 mat4_multiply(mat4 a, mat4 b) {
float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
b00 = b[0], b01 = b[1], b02 = b[2], b03 = b[3],
b10 = b[4], b11 = b[5], b12 = b[6], b13 = b[7],
b20 = b[8], b21 = b[9], b22 = b[10], b23 = b[11],
b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15];
a[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
a[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
a[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
a[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
a[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
a[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
a[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
a[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
a[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
a[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
a[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
a[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
a[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
a[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
a[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
a[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
return a;
}
void mat4_multiplyVector(mat4 m, float* v) {
float v0 = v[0];
float v1 = v[1];
float v2 = v[2];
float v3 = v[3];
v[0] = v0 * m[0] + v1 * m[4] + v2 * m[8] + v3 * m[12];
v[1] = v0 * m[1] + v1 * m[5] + v2 * m[9] + v3 * m[13];
v[2] = v0 * m[2] + v1 * m[6] + v2 * m[10] + v3 * m[14];
v[3] = v0 * m[3] + v1 * m[7] + v2 * m[11] + v3 * m[15];
}
// Modified from gl-matrix.c
mat4 mat4_invert(mat4 m) {
float a00 = m[0], a01 = m[1], a02 = m[2], a03 = m[3],
a10 = m[4], a11 = m[5], a12 = m[6], a13 = m[7],
a20 = m[8], a21 = m[9], a22 = m[10], a23 = m[11],
a30 = m[12], a31 = m[13], a32 = m[14], a33 = m[15],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,
d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06),
invDet;
if (!d) { return NULL; }
invDet = 1 / d;
m[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
m[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
m[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
m[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
m[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
m[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
m[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
m[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
m[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
m[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
m[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
m[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
m[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
m[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
m[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
m[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
return m;
}

View File

@ -1,26 +0,0 @@
#include "vendor/vec/vec.h"
#ifndef LOVR_MATRIX_TYPES
#define LOVR_MATRIX_TYPES
typedef float* mat4;
typedef vec_t(mat4) vec_mat4_t;
#endif
mat4 mat4_init();
void mat4_deinit(mat4 matrix);
mat4 mat4_copy(mat4 source);
mat4 mat4_fromMat34(mat4 matrix, float (*source)[4]);
mat4 mat4_fromMat44(mat4 matrix, float (*source)[4]);
mat4 mat4_setIdentity(mat4 matrix);
mat4 mat4_setTranslation(mat4 matrix, float x, float y, float z);
mat4 mat4_setRotation(mat4 matrix, float angle, float ax, float ay, float az);
mat4 mat4_setScale(mat4 matrix, float x, float y, float z);
mat4 mat4_setOrthographic(mat4 matrix, float left, float right, float top, float bottom, float near, float far);
mat4 mat4_setPerspective(mat4 matrix, float near, float far, float fov, float aspect);
void mat4_getRotation(mat4 matrix, float* w, float* x, float* y, float* z);
mat4 mat4_translate(mat4 matrix, float x, float y, float z);
mat4 mat4_rotate(mat4 matrix, float angle, float ax, float ay, float az);
mat4 mat4_scale(mat4 matrix, float x, float y, float z);
mat4 mat4_multiply(mat4 a, mat4 b);
void mat4_multiplyVector(mat4 m, float* v);
mat4 mat4_invert(mat4 m);