From 8518e32ae283a9f4072521f8296dbe693b2fec23 Mon Sep 17 00:00:00 2001 From: bjorn Date: Tue, 17 Jan 2017 16:58:11 -0800 Subject: [PATCH 01/17] vec3; --- src/math/vec3.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ src/math/vec3.h | 18 ++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/math/vec3.c create mode 100644 src/math/vec3.h diff --git a/src/math/vec3.c b/src/math/vec3.c new file mode 100644 index 00000000..40f8e91e --- /dev/null +++ b/src/math/vec3.c @@ -0,0 +1,95 @@ +#include "math/vec3.h" +#include +#include + +vec3 vec3_init(float x, float y, float z) { + vec3 v = malloc(3 * sizeof(float)); + v[0] = x; + v[1] = y; + v[2] = z; + return v; +} + +vec3 vec3_set(vec3 v, vec3 u) { + v[0] = u[0]; + v[1] = u[1]; + v[2] = u[2]; + return v; +} + +vec3 vec3_add(vec3 v, vec3 u) { + v[0] += u[0]; + v[1] += u[1]; + v[2] += u[2]; + return v; +} + +vec3 vec3_sub(vec3 v, vec3 u) { + v[0] -= u[0]; + v[1] -= u[1]; + v[2] -= u[2]; + return v; +} + +vec3 vec3_mul(vec3 v, vec3 u) { + v[0] *= u[0]; + v[1] *= u[1]; + v[2] *= u[2]; + return v; +} + +vec3 vec3_div(vec3 v, vec3 u) { + v[0] /= u[0]; + v[1] /= u[1]; + v[2] /= u[2]; + return v; +} + +vec3 vec3_normalize(vec3 v) { + float len = vec3_len(v); + if (len == 0) { + return v; + } + + len = 1 / len; + v[0] *= len; + v[1] *= len; + v[2] *= len; + return v; +} + +float vec3_len(vec3 v) { + return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +float vec3_dist(vec3 v, vec3 u) { + float dx = v[0] - u[0]; + float dy = v[1] - u[1]; + float dz = v[2] - u[2]; + return sqrt(dx * dx + dy * dy + dz * dz); +} + +float vec3_angle(vec3 v, vec3 u) { + return acos(vec3_dot(v, u) / (vec3_len(v) * vec3_len(u))); +} + +float vec3_dot(vec3 v, vec3 u) { + return v[0] * u[0] + v[1] * u[1] + v[2] * u[2]; +} + +vec3 vec3_cross(vec3 v, vec3 u) { + float v0 = v[0]; + float v1 = v[1]; + float v2 = v[2]; + v[0] = v1 * u[2] - v2 * u[1]; + v[1] = v0 * u[2] - v2 * u[0]; + v[2] = v0 * u[1] - v1 * u[0]; + 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; + v[2] += (u[2] - v[2]) * t; + return v; +} diff --git a/src/math/vec3.h b/src/math/vec3.h new file mode 100644 index 00000000..879c1c11 --- /dev/null +++ b/src/math/vec3.h @@ -0,0 +1,18 @@ +#ifndef LOVR_VECTOR_TYPES +#define LOVR_VECTOR_TYPES +typedef float* vec3; +#endif + +vec3 vec3_init(float x, float y, float z); +vec3 vec3_set(vec3 v, vec3 u); +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_normalize(vec3 v); +float vec3_len(vec3 v); +float vec3_dist(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_lerp(vec3 v, vec3 u, float t); From fdb363df4b71f7b6bfbc7d3e1c597849b99f765d Mon Sep 17 00:00:00 2001 From: bjorn Date: Tue, 17 Jan 2017 22:11:17 -0800 Subject: [PATCH 02/17] Get closure on that lovr.event memory leak; --- src/lovr/event.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lovr/event.c b/src/lovr/event.c index a5371020..be03fcf6 100644 --- a/src/lovr/event.c +++ b/src/lovr/event.c @@ -2,6 +2,8 @@ #include "event/event.h" #include "util.h" +static int pollRef; + static int nextEvent(lua_State* L) { Event* event = lovrEventPoll(); @@ -44,6 +46,11 @@ const luaL_Reg lovrEvent[] = { int l_lovrEventInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrEvent); + + // Store nextEvent in the registry to avoid creating a closure every time we poll for events. + lua_pushcfunction(L, nextEvent); + pollRef = luaL_ref(L, LUA_REGISTRYINDEX); + map_init(&EventTypes); map_set(&EventTypes, "quit", EVENT_QUIT); lovrEventInit(); @@ -56,7 +63,7 @@ int l_lovrEventClear(lua_State* L) { } int l_lovrEventPoll(lua_State* L) { - lua_pushcclosure(L, nextEvent, 0); + lua_rawgeti(L, LUA_REGISTRYINDEX, pollRef); return 1; } From e8e2a99e5b3b553e08e60b98201453ced403b3c4 Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 18 Jan 2017 00:51:09 -0800 Subject: [PATCH 03/17] Finish internal math library; --- src/graphics/graphics.c | 20 ++- src/graphics/graphics.h | 2 +- src/graphics/model.c | 21 ++- src/graphics/model.h | 3 +- src/graphics/shader.c | 4 +- src/graphics/shader.h | 2 +- src/graphics/texture.c | 4 +- src/headset/vive.c | 10 +- src/loaders/model.c | 2 +- src/math/mat4.c | 257 +++++++++++++++++++++++++++++++++++++ src/math/mat4.h | 16 +++ src/math/math.h | 9 ++ src/math/quat.c | 144 +++++++++++++++++++++ src/math/quat.h | 12 ++ src/math/vec3.c | 40 +++++- src/math/vec3.h | 12 +- src/matrix.c | 276 ---------------------------------------- src/matrix.h | 26 ---- 18 files changed, 520 insertions(+), 340 deletions(-) create mode 100644 src/math/mat4.c create mode 100644 src/math/mat4.h create mode 100644 src/math/math.h create mode 100644 src/math/quat.c create mode 100644 src/math/quat.h delete mode 100644 src/matrix.c delete mode 100644 src/matrix.h diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 7f005a03..b583ae94 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -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); } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 2af33d15..22f77a85 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -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 diff --git a/src/graphics/model.c b/src/graphics/model.c index 91a8532e..d4362051 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -3,12 +3,10 @@ #include 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); diff --git a/src/graphics/model.h b/src/graphics/model.h index a8894827..835fda52 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -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" diff --git a/src/graphics/shader.c b/src/graphics/shader.c index 37d0f84f..f3883b41 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -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); } diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 30dd02ab..751062f1 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -1,5 +1,5 @@ #include "glfw.h" -#include "matrix.h" +#include "math/mat4.h" #include "vendor/map/map.h" #include "util.h" diff --git a/src/graphics/texture.c b/src/graphics/texture.c index 4e93e5f0..dc1fbe41 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -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); } } diff --git a/src/headset/vive.c b/src/headset/vive.c index 322deb10..2b4b2ab8 100644 --- a/src/headset/vive.c +++ b/src/headset/vive.c @@ -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 #include @@ -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) { diff --git a/src/loaders/model.c b/src/loaders/model.c index a0e3751f..b06a9a7f 100644 --- a/src/loaders/model.c +++ b/src/loaders/model.c @@ -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); diff --git a/src/math/mat4.c b/src/math/mat4.c new file mode 100644 index 00000000..0be059ae --- /dev/null +++ b/src/math/mat4.c @@ -0,0 +1,257 @@ +#include "math/mat4.h" +#include "util.h" +#include +#include +#include + +// 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; +} diff --git a/src/math/mat4.h b/src/math/mat4.h new file mode 100644 index 00000000..b92eeab1 --- /dev/null +++ b/src/math/mat4.h @@ -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); diff --git a/src/math/math.h b/src/math/math.h new file mode 100644 index 00000000..f530080e --- /dev/null +++ b/src/math/math.h @@ -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 diff --git a/src/math/quat.c b/src/math/quat.c new file mode 100644 index 00000000..b5913b63 --- /dev/null +++ b/src/math/quat.c @@ -0,0 +1,144 @@ +#include "math/quat.h" +#include "math/vec3.h" +#include +#include + +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; +} diff --git a/src/math/quat.h b/src/math/quat.h new file mode 100644 index 00000000..cfbc67bd --- /dev/null +++ b/src/math/quat.h @@ -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); diff --git a/src/math/vec3.c b/src/math/vec3.c index 40f8e91e..9e7db735 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -1,4 +1,5 @@ #include "math/vec3.h" +#include "math/quat.h" #include #include @@ -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; diff --git a/src/math/vec3.h b/src/math/vec3.h index 879c1c11..a3fef7de 100644 --- a/src/math/vec3.h +++ b/src/math/vec3.h @@ -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); diff --git a/src/matrix.c b/src/matrix.c deleted file mode 100644 index 5521d33d..00000000 --- a/src/matrix.c +++ /dev/null @@ -1,276 +0,0 @@ -#include "matrix.h" -#include "util.h" -#include -#include -#include - -/* - 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; -} diff --git a/src/matrix.h b/src/matrix.h deleted file mode 100644 index 3bd5c75c..00000000 --- a/src/matrix.h +++ /dev/null @@ -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); From f19967e0e619fa95593c08a02415ef63e9fdfa83 Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 18 Jan 2017 00:52:24 -0800 Subject: [PATCH 04/17] More general luax_registertype; --- src/lovr/audio.c | 2 +- src/lovr/graphics.c | 10 +++++----- src/lovr/headset.c | 2 +- src/util.c | 8 +++++--- src/util.h | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/lovr/audio.c b/src/lovr/audio.c index c795690b..93b84983 100644 --- a/src/lovr/audio.c +++ b/src/lovr/audio.c @@ -24,7 +24,7 @@ const luaL_Reg lovrAudio[] = { int l_lovrAudioInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrAudio); - luax_registertype(L, "Source", lovrSource); + luax_registertype(L, "Source", lovrSource, luax_releasetype); map_init(&TimeUnits); map_set(&TimeUnits, "seconds", UNIT_SECONDS); diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index fc7d99bc..2f7fcf65 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -95,11 +95,11 @@ const luaL_Reg lovrGraphics[] = { int l_lovrGraphicsInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrGraphics); - luax_registertype(L, "Buffer", lovrBuffer); - luax_registertype(L, "Model", lovrModel); - luax_registertype(L, "Shader", lovrShader); - luax_registertype(L, "Skybox", lovrSkybox); - luax_registertype(L, "Texture", lovrTexture); + luax_registertype(L, "Buffer", lovrBuffer, luax_releasetype); + luax_registertype(L, "Model", lovrModel, luax_releasetype); + luax_registertype(L, "Shader", lovrShader, luax_releasetype); + luax_registertype(L, "Skybox", lovrSkybox, luax_releasetype); + luax_registertype(L, "Texture", lovrTexture, luax_releasetype); map_init(&BufferAttributeTypes); map_set(&BufferAttributeTypes, "float", BUFFER_FLOAT); diff --git a/src/lovr/headset.c b/src/lovr/headset.c index 3d24d9a1..a399aba2 100644 --- a/src/lovr/headset.c +++ b/src/lovr/headset.c @@ -38,7 +38,7 @@ const luaL_Reg lovrHeadset[] = { int l_lovrHeadsetInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrHeadset); - luax_registertype(L, "Controller", lovrController); + luax_registertype(L, "Controller", lovrController, luax_releasetype); map_init(&ControllerAxes); map_set(&ControllerAxes, "trigger", CONTROLLER_AXIS_TRIGGER); diff --git a/src/util.c b/src/util.c index 4a8ac238..f78ec5a9 100644 --- a/src/util.c +++ b/src/util.c @@ -73,7 +73,7 @@ static int luax_pushobjectname(lua_State* L) { return 1; } -void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions) { +void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc) { // Push metatable luaL_newmetatable(L, name); @@ -84,8 +84,10 @@ void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions lua_setfield(L, -1, "__index"); // m.__gc = gc - lua_pushcfunction(L, luax_releasetype); - lua_setfield(L, -2, "__gc"); + if (gc) { + lua_pushcfunction(L, gc); + lua_setfield(L, -2, "__gc"); + } // m.name = name lua_pushstring(L, name); diff --git a/src/util.h b/src/util.h index e0f93dcf..d3769e8b 100644 --- a/src/util.h +++ b/src/util.h @@ -43,7 +43,7 @@ void lovrRetain(const Ref* ref); void lovrRelease(const Ref* ref); int luax_preloadmodule(lua_State* L, const char* key, lua_CFunction f); -void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions); +void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc); int luax_releasetype(lua_State* L); void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* typeName); void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* typeName); From 4f0f685e043a5ba83ebd545e773ca9e7b4a0528c Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 18 Jan 2017 19:59:45 -0800 Subject: [PATCH 05/17] luax_istype; --- src/util.c | 19 +++++++++++++++---- src/util.h | 5 +++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/util.c b/src/util.c index f78ec5a9..bde4d51e 100644 --- a/src/util.c +++ b/src/util.c @@ -111,22 +111,33 @@ int luax_releasetype(lua_State* L) { return 0; } -void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* typeName) { +int luax_istype(lua_State* L, int index, const char* name) { + if (lua_getmetatable(L, index)) { + luaL_getmetatable(L, name); + int equal = lua_equal(L, -1, -2); + lua_pop(L, 2); + return equal; + } + + return 0; +} + +void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* debug) { const char* key = luaL_checkstring(L, index); void* value = map_get(map, key); if (!value) { - luaL_error(L, "Invalid %s '%s'", typeName, key); + luaL_error(L, "Invalid %s '%s'", debug, key); return NULL; } return value; } -void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* typeName) { +void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* debug) { const char* key = luaL_optstring(L, index, fallback); void* value = map_get(map, key); if (!value) { - luaL_error(L, "Invalid %s '%s'", typeName, key); + luaL_error(L, "Invalid %s '%s'", debug, key); return NULL; } diff --git a/src/util.h b/src/util.h index d3769e8b..376c8940 100644 --- a/src/util.h +++ b/src/util.h @@ -45,5 +45,6 @@ void lovrRelease(const Ref* ref); int luax_preloadmodule(lua_State* L, const char* key, lua_CFunction f); void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc); int luax_releasetype(lua_State* L); -void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* typeName); -void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* typeName); +int luax_istype(lua_State* L, int index, const char* name); +void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* debug); +void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* debug); From c7399c80785cb398c50ce9e65272f897f539b916 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 01:56:10 -0800 Subject: [PATCH 06/17] Reorder mat4 functions; --- src/math/mat4.c | 32 ++++++++++++++++---------------- src/math/mat4.h | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/math/mat4.c b/src/math/mat4.c index 0be059ae..de396b21 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -172,22 +172,6 @@ mat4 mat4_translate(mat4 m, float x, float y, float z) { 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]; @@ -207,6 +191,22 @@ mat4 mat4_rotate(mat4 m, quat q) { return mat4_multiply(m, rotation); } +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_orthographic(mat4 m, float left, float right, float top, float bottom, float near, float far) { float rl = right - left; float tb = top - bottom; diff --git a/src/math/mat4.h b/src/math/mat4.h index b92eeab1..a7a2959c 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -9,8 +9,8 @@ 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_scale(mat4 m, float x, float y, float z); 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); From a3ccb1691302fcb83358a95f071940c947a7e7b5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 01:56:17 -0800 Subject: [PATCH 07/17] Rough math module; --- src/lovr.c | 5 +- src/lovr/math.c | 80 +++++++++++++++++++++++ src/lovr/math.h | 9 +++ src/lovr/types/rotation.c | 82 ++++++++++++++++++++++++ src/lovr/types/rotation.h | 16 +++++ src/lovr/types/transform.c | 119 ++++++++++++++++++++++++++++++++++ src/lovr/types/transform.h | 19 ++++++ src/lovr/types/vector.c | 128 +++++++++++++++++++++++++++++++++++++ src/lovr/types/vector.h | 23 +++++++ 9 files changed, 480 insertions(+), 1 deletion(-) create mode 100644 src/lovr/math.c create mode 100644 src/lovr/math.h create mode 100644 src/lovr/types/rotation.c create mode 100644 src/lovr/types/rotation.h create mode 100644 src/lovr/types/transform.c create mode 100644 src/lovr/types/transform.h create mode 100644 src/lovr/types/vector.c create mode 100644 src/lovr/types/vector.h diff --git a/src/lovr.c b/src/lovr.c index e343e9cd..65801890 100644 --- a/src/lovr.c +++ b/src/lovr.c @@ -4,6 +4,7 @@ #include "lovr/filesystem.h" #include "lovr/graphics.h" #include "lovr/headset.h" +#include "lovr/math.h" #include "lovr/timer.h" #include "glfw.h" #include "util.h" @@ -62,6 +63,7 @@ void lovrInit(lua_State* L, int argc, char** argv) { luax_preloadmodule(L, "lovr.filesystem", l_lovrFilesystemInit); luax_preloadmodule(L, "lovr.graphics", l_lovrGraphicsInit); luax_preloadmodule(L, "lovr.headset", l_lovrHeadsetInit); + luax_preloadmodule(L, "lovr.math", l_lovrMathInit); luax_preloadmodule(L, "lovr.timer", l_lovrTimerInit); // Bootstrap @@ -73,6 +75,7 @@ void lovrInit(lua_State* L, int argc, char** argv) { " event = true, " " graphics = true, " " headset = true, " + " math = true, " " timer = true " " } " "} " @@ -88,7 +91,7 @@ void lovrInit(lua_State* L, int argc, char** argv) { " success, err = pcall(lovr.conf, conf) " "end " - "local modules = { 'audio', 'event', 'graphics', 'headset', 'timer' } " + "local modules = { 'audio', 'event', 'graphics', 'headset', 'math', 'timer' } " "for _, module in ipairs(modules) do " " if conf.modules[module] then " " lovr[module] = require('lovr.' .. module) " diff --git a/src/lovr/math.c b/src/lovr/math.c new file mode 100644 index 00000000..a6ea107b --- /dev/null +++ b/src/lovr/math.c @@ -0,0 +1,80 @@ +#include "lovr/math.h" +#include "lovr/types/vector.h" +#include "lovr/types/rotation.h" +#include "lovr/types/transform.h" +#include "math/vec3.h" +#include "math/quat.h" +#include "math/mat4.h" +#include "util.h" + +const luaL_Reg lovrMath[] = { + { "newVector", l_lovrMathNewVector }, + { "newRotation", l_lovrMathNewRotation }, + { "newTransform", l_lovrMathNewTransform }, + { NULL, NULL } +}; + +int l_lovrMathInit(lua_State* L) { + lua_newtable(L); + luaL_register(L, NULL, lovrMath); + luax_registertype(L, "Vector", lovrVector, NULL); + luax_registertype(L, "Rotation", lovrRotation, NULL); + luax_registertype(L, "Transform", lovrTransform, NULL); + return 1; +} + +int l_lovrMathNewVector(lua_State* L) { + if (lua_gettop(L) == 1) { + vec3 v = luax_newvector(L); + v[0] = v[1] = v[2] = luaL_checknumber(L, 1); + return 1; + } else { + vec3 v = luax_newvector(L); + v[0] = luaL_checknumber(L, 1); + v[1] = luaL_checknumber(L, 2); + v[2] = luaL_checknumber(L, 3); + return 1; + } +} + +int l_lovrMathNewRotation(lua_State* L) { + if (lua_gettop(L) == 4) { + float angle = luaL_optnumber(L, 1, 0); + float axis[3]; + axis[0] = luaL_optnumber(L, 2, 0); + axis[1] = luaL_optnumber(L, 3, 0); + axis[2] = luaL_optnumber(L, 4, 0); + quat_fromAngleAxis(luax_newrotation(L), angle, axis); + } else if (lua_isnumber(L, 1) && luax_istype(L, 2, "Vector")) { + quat_fromAngleAxis(luax_newrotation(L), lua_tonumber(L, 1), luax_checkvector(L, 2)); + } else { + quat_between(luax_newrotation(L), luax_checkvector(L, 1), luax_checkvector(L, 2)); + } + + return 1; +} + +int l_lovrMathNewTransform(lua_State* L) { + int hasArgs = lua_gettop(L) > 0; + mat4 m = luax_newtransform(L); + mat4_identity(m); + + if (hasArgs) { + float x = luaL_checknumber(L, 1); + float y = luaL_checknumber(L, 2); + float z = luaL_checknumber(L, 3); + float s = luaL_optnumber(L, 4, 1); + float angle = luaL_optnumber(L, 5, 0); + float ax = luaL_optnumber(L, 6, 0); + float ay = luaL_optnumber(L, 7, 0); + float az = luaL_optnumber(L, 8, 0); + float rotation[4]; + float axis[3] = { ax, ay, az }; + quat_fromAngleAxis(rotation, angle, axis); + mat4_translate(m, x, y, z); + mat4_scale(m, s, s, s); + mat4_rotate(m, rotation); + } + + return 1; +} diff --git a/src/lovr/math.h b/src/lovr/math.h new file mode 100644 index 00000000..b7ebb509 --- /dev/null +++ b/src/lovr/math.h @@ -0,0 +1,9 @@ +#include +#include +#include + +extern const luaL_Reg lovrMath[]; +int l_lovrMathInit(lua_State* L); +int l_lovrMathNewVector(lua_State* L); +int l_lovrMathNewRotation(lua_State* L); +int l_lovrMathNewTransform(lua_State* L); diff --git a/src/lovr/types/rotation.c b/src/lovr/types/rotation.c new file mode 100644 index 00000000..2211688a --- /dev/null +++ b/src/lovr/types/rotation.c @@ -0,0 +1,82 @@ +#include "lovr/types/rotation.h" +#include "math/vec3.h" +#include "util.h" + +quat luax_newrotation(lua_State* L) { + quat q = (quat) lua_newuserdata(L, 4 * sizeof(float)); + luaL_getmetatable(L, "Rotation"); + lua_setmetatable(L, -2); + return q; +} + +quat luax_checkrotation(lua_State* L, int i) { + return luaL_checkudata(L, i, "Rotation"); +} + +const luaL_Reg lovrRotation[] = { + { "clone", l_lovrRotationClone }, + { "unpack", l_lovrRotationUnpack }, + { "normalize", l_lovrRotationNormalize }, + { "rotate", l_lovrRotationRotate }, + { "slerp", l_lovrRotationSlerp }, + { "__mul", l_lovrRotationMul }, + { "__len", l_lovrRotationLen }, + { NULL, NULL } +}; + +int l_lovrRotationClone(lua_State* L) { + quat q = luax_checkrotation(L, 1); + quat_set(luax_newrotation(L), q); + return 1; +} + +int l_lovrRotationUnpack(lua_State* L) { + quat q = luax_checkrotation(L, 1); + float angle, x, y, z; + quat_toAngleAxis(q, &angle, &x, &y, &z); + lua_pushnumber(L, angle); + lua_pushnumber(L, x); + lua_pushnumber(L, y); + lua_pushnumber(L, z); + return 4; +} + +int l_lovrRotationNormalize(lua_State* L) { + quat q = luax_checkrotation(L, 1); + quat_normalize(q); + return 1; +} + +int l_lovrRotationRotate(lua_State* L) { + quat q = luax_checkrotation(L, 1); + float v[3]; + v[0] = luaL_checknumber(L, 2); + v[1] = luaL_checknumber(L, 3); + v[2] = luaL_checknumber(L, 4); + vec3_rotate(v, q); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; +} + +int l_lovrRotationSlerp(lua_State* L) { + quat q = luax_checkrotation(L, 1); + quat r = luax_checkrotation(L, 2); + float t = luaL_checknumber(L, 3); + quat_slerp(quat_set(luax_newrotation(L), q), r, t); + return 1; +} + +int l_lovrRotationMul(lua_State* L) { + quat q = luax_checkrotation(L, 1); + quat r = luax_checkrotation(L, 2); + quat_multiply(quat_set(luax_newrotation(L), q), r); + return 1; +} + +int l_lovrRotationLen(lua_State* L) { + quat q = luax_checkrotation(L, 1); + lua_pushnumber(L, quat_length(q)); + return 1; +} diff --git a/src/lovr/types/rotation.h b/src/lovr/types/rotation.h new file mode 100644 index 00000000..90855c28 --- /dev/null +++ b/src/lovr/types/rotation.h @@ -0,0 +1,16 @@ +#include "math/quat.h" +#include +#include +#include + +vec3 luax_newrotation(lua_State* L); +vec3 luax_checkrotation(lua_State* L, int i); + +extern const luaL_Reg lovrRotation[]; +int l_lovrRotationClone(lua_State* L); +int l_lovrRotationUnpack(lua_State* L); +int l_lovrRotationNormalize(lua_State* L); +int l_lovrRotationRotate(lua_State* L); +int l_lovrRotationSlerp(lua_State* L); +int l_lovrRotationMul(lua_State* L); +int l_lovrRotationLen(lua_State* L); diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c new file mode 100644 index 00000000..47494a17 --- /dev/null +++ b/src/lovr/types/transform.c @@ -0,0 +1,119 @@ +#include "lovr/types/transform.h" +#include "lovr/types/rotation.h" +#include "math/vec3.h" +#include "util.h" + +mat4 luax_newtransform(lua_State* L) { + mat4 m = (mat4) lua_newuserdata(L, 16 * sizeof(float)); + luaL_getmetatable(L, "Transform"); + lua_setmetatable(L, -2); + return m; +} + +mat4 luax_checktransform(lua_State* L, int i) { + return luaL_checkudata(L, i, "Transform"); +} + +const luaL_Reg lovrTransform[] = { + { "clone", l_lovrTransformClone }, + { "unpack", l_lovrTransformUnpack }, + { "inverse", l_lovrTransformInverse }, + { "apply", l_lovrTransformApply }, + { "origin", l_lovrTransformOrigin }, + { "translate", l_lovrTransformTranslate }, + { "rotate", l_lovrTransformRotate }, + { "scale", l_lovrTransformScale }, + { "transform", l_lovrTransformTransform }, + { "__mul", l_lovrTransformMul }, + { NULL, NULL } +}; + +int l_lovrTransformClone(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + mat4_set(luax_newtransform(L), m); + return 1; +} + +int l_lovrTransformUnpack(lua_State* L) { + return 0; +} + +int l_lovrTransformInverse(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + mat4_invert(mat4_set(luax_newtransform(L), m)); + return 1; +} + +int l_lovrTransformApply(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + mat4 n = luax_checktransform(L, 2); + mat4_multiply(m, n); + return 1; +} + +int l_lovrTransformOrigin(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + mat4_identity(m); + return 1; +} + +int l_lovrTransformTranslate(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + mat4_translate(m, x, y, z); + lua_settop(L, 1); + return 1; +} + +int l_lovrTransformRotate(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + + if (lua_isnumber(L, 2)) { + float angle = luaL_checknumber(L, 2); + float axis[3]; + axis[0] = luaL_checknumber(L, 3); + axis[1] = luaL_checknumber(L, 4); + axis[2] = luaL_checknumber(L, 5); + float q[4]; + quat_fromAngleAxis(q, angle, axis); + mat4_rotate(m, q); + } else if (luax_istype(L, 2, "Rotation")) { + quat q = luax_checkrotation(L, 2); + mat4_rotate(m, q); + } + + lua_settop(L, 1); + return 1; +} + +int l_lovrTransformScale(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + float x = luaL_checknumber(L, 2); + float y = lua_gettop(L) > 2 ? luaL_checknumber(L, 3) : x; + float z = lua_gettop(L) > 2 ? luaL_checknumber(L, 4) : x; + mat4_scale(m, x, y, z); + lua_settop(L, 1); + return 1; +} + +int l_lovrTransformTransform(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + float v[3]; + v[0] = luaL_checknumber(L, 2); + v[1] = luaL_checknumber(L, 3); + v[2] = luaL_checknumber(L, 4); + vec3_transform(v, m); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; +} + +int l_lovrTransformMul(lua_State* L) { + mat4 m = luax_checktransform(L, 1); + mat4 n = luax_checktransform(L, 2); + mat4_multiply(mat4_set(luax_newtransform(L), m), n); + return 1; +} diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h new file mode 100644 index 00000000..41773b3e --- /dev/null +++ b/src/lovr/types/transform.h @@ -0,0 +1,19 @@ +#include "math/mat4.h" +#include +#include +#include + +mat4 luax_newtransform(lua_State* L); +mat4 luax_checktransform(lua_State* L, int i); + +extern const luaL_Reg lovrTransform[]; +int l_lovrTransformClone(lua_State* L); +int l_lovrTransformUnpack(lua_State* L); +int l_lovrTransformInverse(lua_State* L); +int l_lovrTransformApply(lua_State* L); +int l_lovrTransformOrigin(lua_State* L); +int l_lovrTransformTranslate(lua_State* L); +int l_lovrTransformRotate(lua_State* L); +int l_lovrTransformScale(lua_State* L); +int l_lovrTransformTransform(lua_State* L); +int l_lovrTransformMul(lua_State* L); diff --git a/src/lovr/types/vector.c b/src/lovr/types/vector.c new file mode 100644 index 00000000..24d4fcf5 --- /dev/null +++ b/src/lovr/types/vector.c @@ -0,0 +1,128 @@ +#include "lovr/types/vector.h" +#include "util.h" + +vec3 luax_newvector(lua_State* L) { + vec3 v = (vec3) lua_newuserdata(L, 3 * sizeof(float)); + luaL_getmetatable(L, "Vector"); + lua_setmetatable(L, -2); + return v; +} + +vec3 luax_checkvector(lua_State* L, int i) { + return luaL_checkudata(L, i, "Vector"); +} + +const luaL_Reg lovrVector[] = { + { "clone", l_lovrVectorClone }, + { "unpack", l_lovrVectorUnpack }, + { "scale", l_lovrVectorScale }, + { "normalize", l_lovrVectorNormalize }, + { "distance", l_lovrVectorDistance }, + { "angle", l_lovrVectorAngle }, + { "dot", l_lovrVectorDot }, + { "cross", l_lovrVectorCross }, + { "lerp", l_lovrVectorLerp }, + { "__add", l_lovrVectorAdd }, + { "__sub", l_lovrVectorSub }, + { "__mul", l_lovrVectorMul }, + { "__div", l_lovrVectorDiv }, + { "__len", l_lovrVectorLength }, + { NULL, NULL } +}; + +int l_lovrVectorClone(lua_State* L) { + vec3 v = luax_checkvector(L, 1); + vec3_set(luax_newvector(L), v); + return 1; +} + +int l_lovrVectorUnpack(lua_State* L) { + vec3 v = luax_checkvector(L, 1); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; +} + +int l_lovrVectorScale(lua_State* L) { + vec3 v = luax_checkvector(L, 1); + float s = luaL_checknumber(L, 2); + vec3_scale(v, s); + return 1; +} + +int l_lovrVectorNormalize(lua_State* L) { + vec3 v = luax_checkvector(L, 1); + vec3_normalize(v); + return 1; +} + +int l_lovrVectorDistance(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + lua_pushnumber(L, vec3_distance(u, v)); + return 1; +} + +int l_lovrVectorAngle(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + lua_pushnumber(L, vec3_angle(u, v)); + return 1; +} + +int l_lovrVectorDot(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + lua_pushnumber(L, vec3_dot(u, v)); + return 1; +} + +int l_lovrVectorCross(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + vec3_cross(vec3_set(luax_newvector(L), u), v); + return 1; +} + +int l_lovrVectorLerp(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + float t = luaL_checknumber(L, 3); + vec3_lerp(vec3_set(luax_newvector(L), u), v, t); + return 1; +} + +int l_lovrVectorAdd(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + vec3_add(vec3_set(luax_newvector(L), u), v); + return 1; +} + +int l_lovrVectorSub(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + vec3_sub(vec3_set(luax_newvector(L), u), v); + return 1; +} + +int l_lovrVectorMul(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + vec3_mul(vec3_set(luax_newvector(L), u), v); + return 1; +} + +int l_lovrVectorDiv(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + vec3 v = luax_checkvector(L, 2); + vec3_div(vec3_set(luax_newvector(L), u), v); + return 1; +} + +int l_lovrVectorLength(lua_State* L) { + vec3 u = luax_checkvector(L, 1); + lua_pushnumber(L, vec3_length(u)); + return 1; +} diff --git a/src/lovr/types/vector.h b/src/lovr/types/vector.h new file mode 100644 index 00000000..bcf87d6e --- /dev/null +++ b/src/lovr/types/vector.h @@ -0,0 +1,23 @@ +#include "math/vec3.h" +#include +#include +#include + +vec3 luax_newvector(lua_State* L); +vec3 luax_checkvector(lua_State* L, int i); + +extern const luaL_Reg lovrVector[]; +int l_lovrVectorClone(lua_State* L); +int l_lovrVectorUnpack(lua_State* L); +int l_lovrVectorScale(lua_State* L); +int l_lovrVectorNormalize(lua_State* L); +int l_lovrVectorDistance(lua_State* L); +int l_lovrVectorAngle(lua_State* L); +int l_lovrVectorDot(lua_State* L); +int l_lovrVectorCross(lua_State* L); +int l_lovrVectorLerp(lua_State* L); +int l_lovrVectorAdd(lua_State* L); +int l_lovrVectorSub(lua_State* L); +int l_lovrVectorMul(lua_State* L); +int l_lovrVectorDiv(lua_State* L); +int l_lovrVectorLength(lua_State* L); From 3dbafc82141159eeb8763b8dbed67ffa022d08b0 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 18:04:45 -0800 Subject: [PATCH 08/17] Cleanup; --- .gitignore | 1 + src/graphics/graphics.c | 19 ++------ src/graphics/graphics.h | 6 +-- src/graphics/model.c | 15 ++---- src/graphics/model.h | 2 +- src/graphics/shader.c | 6 +-- src/graphics/shader.h | 4 +- src/headset/headset.c | 12 ++--- src/headset/headset.h | 8 ++-- src/headset/vive.c | 16 +++---- src/headset/vive.h | 4 +- src/loaders/model.c | 3 +- src/lovr/headset.c | 6 +-- src/lovr/math.c | 22 ++++----- src/lovr/types/controller.c | 6 +-- src/lovr/types/rotation.c | 56 +++++++++++++++------- src/lovr/types/rotation.h | 3 +- src/lovr/types/transform.c | 94 +++++++++++++++++++++++-------------- src/lovr/types/transform.h | 2 +- src/lovr/types/vector.c | 36 ++++++++++---- src/lovr/types/vector.h | 3 +- src/math/mat4.c | 39 +++++---------- src/math/mat4.h | 8 ++-- src/math/quat.c | 44 ++++++++++------- src/math/quat.h | 7 +-- src/math/vec3.c | 52 +++++++------------- src/math/vec3.h | 4 +- 27 files changed, 252 insertions(+), 226 deletions(-) diff --git a/.gitignore b/.gitignore index e19fc7bf..eb8f32df 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ deps data src/obj src/Tupfile +/watch.sh *.lua *.glsl .DS_Store diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index b583ae94..6cb32836 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -15,9 +15,6 @@ static GraphicsState state; // Base void lovrGraphicsInit() { - for (int i = 0; i < MAX_TRANSFORMS; i++) { - state.transforms[i] = mat4_init(); - } for (int i = 0; i < MAX_CANVASES; i++) { state.canvases[i] = malloc(sizeof(CanvasState)); } @@ -39,9 +36,6 @@ void lovrGraphicsInit() { void lovrGraphicsDestroy() { lovrGraphicsSetShader(NULL); glUseProgram(0); - for (int i = 0; i < MAX_TRANSFORMS; i++) { - free(state.transforms[i]); - } for (int i = 0; i < MAX_CANVASES; i++) { free(state.canvases[i]); } @@ -342,27 +336,20 @@ void lovrGraphicsTranslate(float x, float y, float z) { } void lovrGraphicsRotate(float angle, float ax, float ay, float az) { - float rotation[4]; - float axis[3] = { ax, ay, az }; - quat_fromAngleAxis(rotation, angle, axis); - mat4_rotate(state.transforms[state.transform], rotation); + mat4_rotate(state.transforms[state.transform], angle, ax, ay, az); } void lovrGraphicsScale(float x, float y, float z) { mat4_scale(state.transforms[state.transform], x, y, z); } +// M *= T * S * R 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_identity(transform); mat4_translate(transform, tx, ty, tz); mat4_scale(transform, sx, sy, sz); - mat4_rotate(transform, rotation); + mat4_rotate(transform, angle, ax, ay, az); lovrGraphicsMatrixTransform(transform); } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 22f77a85..68553a34 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -50,10 +50,10 @@ typedef struct { Shader* skyboxShader; Shader* fullscreenShader; Texture* defaultTexture; - int transform; - mat4 transforms[MAX_TRANSFORMS]; - int canvas; + float transforms[MAX_TRANSFORMS][16]; CanvasState* canvases[MAX_CANVASES]; + int transform; + int canvas; unsigned int color; char colorMask; int isScissorEnabled; diff --git a/src/graphics/model.c b/src/graphics/model.c index d4362051..9e7fcd47 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -3,10 +3,12 @@ #include static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec_float_t* vertices, vec_uint_t* indices) { - mat4 newTransform = mat4_init(); + float newTransform[16]; if (transform) { mat4_set(newTransform, transform); + } else { + mat4_identity(newTransform); } mat4_multiply(newTransform, node->transform); @@ -21,12 +23,8 @@ 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 vec[3] = { - vertex.x, - vertex.y, - vertex.z - }; - + float vec[3]; + vec3_set(vec, vertex.x, vertex.y, vertex.z); vec3_transform(vec, newTransform); vec_pusharr(vertices, vec, 3); @@ -56,8 +54,6 @@ static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec for (int c = 0; c < node->children.length; c++) { visitNode(modelData, node->children.data[c], newTransform, vertices, indices); } - - free(newTransform); } Model* lovrModelCreate(ModelData* modelData) { @@ -133,7 +129,6 @@ void lovrModelDataDestroy(ModelData* modelData) { while (nodes.length > 0) { ModelNode* node = vec_first(&nodes); vec_extend(&nodes, &node->children); - free(node->transform); vec_deinit(&node->meshes); vec_deinit(&node->children); vec_splice(&nodes, 0, 1); diff --git a/src/graphics/model.h b/src/graphics/model.h index 835fda52..c1ce9d3b 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -33,7 +33,7 @@ typedef struct { typedef vec_t(ModelMesh*) vec_model_mesh_t; typedef struct ModelNode { - mat4 transform; + float transform[16]; vec_uint_t meshes; vec_void_t children; } ModelNode; diff --git a/src/graphics/shader.c b/src/graphics/shader.c index f3883b41..a404f51e 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -162,8 +162,8 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) { // Initial state shader->id = id; - shader->transform = mat4_init(); - shader->projection = mat4_init(); + mat4_identity(shader->transform); + mat4_identity(shader->projection); shader->color = 0; // Send initial uniform values to shader @@ -175,8 +175,6 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) { void lovrShaderDestroy(const Ref* ref) { Shader* shader = containerof(ref, Shader); glDeleteProgram(shader->id); - free(shader->transform); - free(shader->projection); map_deinit(&shader->uniforms); free(shader); } diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 751062f1..78513208 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -26,8 +26,8 @@ typedef struct { Ref ref; int id; map_uniform_t uniforms; - mat4 transform; - mat4 projection; + float transform[16]; + float projection[16]; unsigned int color; } Shader; #endif diff --git a/src/headset/headset.c b/src/headset/headset.c index d113d63b..e8d7d301 100644 --- a/src/headset/headset.c +++ b/src/headset/headset.c @@ -108,13 +108,13 @@ void lovrHeadsetGetPosition(float* x, float* y, float* z) { headset->getPosition(headset, x, y, z); } -void lovrHeadsetGetOrientation(float* w, float* x, float* y, float* z) { +void lovrHeadsetGetOrientation(float* angle, float* x, float* y, float* z) { if (!headset) { - *w = *x = *y = *z = 0.f; + *angle = *x = *y = *z = 0.f; return; } - headset->getOrientation(headset, w, x, y, z); + headset->getOrientation(headset, angle, x, y, z); } void lovrHeadsetGetVelocity(float* x, float* y, float* z) { @@ -160,13 +160,13 @@ void lovrHeadsetControllerGetPosition(Controller* controller, float* x, float* y headset->controllerGetPosition(headset, controller, x, y, z); } -void lovrHeadsetControllerGetOrientation(Controller* controller, float* w, float* x, float* y, float* z) { +void lovrHeadsetControllerGetOrientation(Controller* controller, float* angle, float* x, float* y, float* z) { if (!headset || !controller) { - *w = *x = *y = *z = 0.f; + *angle = *x = *y = *z = 0.f; return; } - headset->controllerGetOrientation(headset, controller, w, x, y, z); + headset->controllerGetOrientation(headset, controller, angle, x, y, z); } float lovrHeadsetControllerGetAxis(Controller* controller, ControllerAxis axis) { diff --git a/src/headset/headset.h b/src/headset/headset.h index 707fdd25..f5fdd5c8 100644 --- a/src/headset/headset.h +++ b/src/headset/headset.h @@ -44,13 +44,13 @@ typedef struct { char (*isBoundsVisible)(void* headset); void (*setBoundsVisible)(void* headset, char visible); void (*getPosition)(void* headset, float* x, float* y, float* z); - void (*getOrientation)(void* headset, float* w, float* x, float* y, float* z); + void (*getOrientation)(void* headset, float* angle, float* x, float* y, float* z); void (*getVelocity)(void* headset, float* x, float* y, float* z); void (*getAngularVelocity)(void* headset, float* x, float* y, float* z); vec_controller_t* (*getControllers)(void* headset); char (*controllerIsPresent)(void* headset, Controller* controller); void (*controllerGetPosition)(void* headset, Controller* controller, float* x, float* y, float* z); - void (*controllerGetOrientation)(void* headset, Controller* controller, float* w, float* x, float* y, float* z); + void (*controllerGetOrientation)(void* headset, Controller* controller, float* angle, float* x, float* y, float* z); float (*controllerGetAxis)(void* headset, Controller* controller, ControllerAxis axis); int (*controllerIsDown)(void* headset, Controller* controller, ControllerButton button); void (*controllerVibrate)(void* headset, Controller* controller, float duration); @@ -73,13 +73,13 @@ void lovrHeadsetGetBoundsGeometry(float* geometry); char lovrHeadsetIsBoundsVisible(); void lovrHeadsetSetBoundsVisible(char visible); void lovrHeadsetGetPosition(float* x, float* y, float* z); -void lovrHeadsetGetOrientation(float* w, float* x, float* y, float* z); +void lovrHeadsetGetOrientation(float* angle, float* x, float* y, float* z); void lovrHeadsetGetVelocity(float* x, float* y, float* z); void lovrHeadsetGetAngularVelocity(float* x, float* y, float* z); vec_controller_t* lovrHeadsetGetControllers(); char lovrHeadsetControllerIsPresent(Controller* controller); void lovrHeadsetControllerGetPosition(Controller* controller, float* x, float* y, float* z); -void lovrHeadsetControllerGetOrientation(Controller* controller, float* w, float* x, float* y, float* z); +void lovrHeadsetControllerGetOrientation(Controller* controller, float* angle, float* x, float* y, float* z); float lovrHeadsetControllerGetAxis(Controller* controller, ControllerAxis axis); int lovrHeadsetControllerIsDown(Controller* controller, ControllerButton button); void lovrHeadsetControllerVibrate(Controller* controller, float duration); diff --git a/src/headset/vive.c b/src/headset/vive.c index 2b4b2ab8..40030585 100644 --- a/src/headset/vive.c +++ b/src/headset/vive.c @@ -257,19 +257,19 @@ void viveGetPosition(void* headset, float* x, float* y, float* z) { *z = pose.mDeviceToAbsoluteTracking.m[2][3]; } -void viveGetOrientation(void* headset, float* w, float* x, float* y, float *z) { +void viveGetOrientation(void* headset, float* angle, float* x, float* y, float *z) { Vive* vive = (Vive*) headset; TrackedDevicePose_t pose = viveGetPose(vive, vive->headsetIndex); if (!pose.bPoseIsValid || !pose.bDeviceIsConnected) { - *w = *x = *y = *z = 0.f; + *angle = *x = *y = *z = 0.f; return; } float matrix[16]; float rotation[4]; - mat4_toQuat(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), rotation); - quat_toAngleAxis(rotation, w, x, y, z); + quat_fromMat4(rotation, mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m)); + quat_getAngleAxis(rotation, angle, x, y, z); } void viveGetVelocity(void* headset, float* x, float* y, float* z) { @@ -343,19 +343,19 @@ void viveControllerGetPosition(void* headset, Controller* controller, float* x, *z = pose.mDeviceToAbsoluteTracking.m[2][3]; } -void viveControllerGetOrientation(void* headset, Controller* controller, float* w, float* x, float* y, float* z) { +void viveControllerGetOrientation(void* headset, Controller* controller, float* angle, float* x, float* y, float* z) { Vive* vive = (Vive*) headset; TrackedDevicePose_t pose = viveGetPose(vive, controller->id); if (!pose.bPoseIsValid || !pose.bDeviceIsConnected) { - *w = *x = *y = *z = 0.f; + *angle = *x = *y = *z = 0.f; return; } float matrix[16]; float rotation[4]; - mat4_toQuat(mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m), rotation); - quat_toAngleAxis(rotation, w, x, y, z); + quat_fromMat4(rotation, mat4_fromMat44(matrix, pose.mDeviceToAbsoluteTracking.m)); + quat_getAngleAxis(rotation, angle, x, y, z); } float viveControllerGetAxis(void* headset, Controller* controller, ControllerAxis axis) { diff --git a/src/headset/vive.h b/src/headset/vive.h index b0794ce5..1a484c44 100644 --- a/src/headset/vive.h +++ b/src/headset/vive.h @@ -47,14 +47,14 @@ void viveGetBoundsGeometry(void* headset, float* geometry); char viveIsBoundsVisible(void* headset); void viveSetBoundsVisible(void* headset, char visible); void viveGetPosition(void* headset, float* x, float* y, float* z); -void viveGetOrientation(void* headset, float* w, float* x, float* y, float* z); +void viveGetOrientation(void* headset, float* angle, float* x, float* y, float* z); void viveGetVelocity(void* headset, float* x, float* y, float* z); void viveGetAngularVelocity(void* headset, float* x, float* y, float* z); Controller* viveAddController(void* headset, unsigned int deviceIndex); vec_controller_t* viveGetControllers(void* headset); char viveControllerIsPresent(void* headset, Controller* controller); void viveControllerGetPosition(void* headset, Controller* controller, float* x, float* y, float* z); -void viveControllerGetOrientation(void* headset, Controller* controller, float* w, float* x, float* y, float* z); +void viveControllerGetOrientation(void* headset, Controller* controller, float* angle, float* x, float* y, float* z); float viveControllerGetAxis(void* headset, Controller* controller, ControllerAxis axis); int viveControllerIsDown(void* headset, Controller* controller, ControllerButton button); void viveControllerVibrate(void* headset, Controller* controller, float duration); diff --git a/src/loaders/model.c b/src/loaders/model.c index b06a9a7f..c3974a87 100644 --- a/src/loaders/model.c +++ b/src/loaders/model.c @@ -9,7 +9,7 @@ static void assimpNodeTraversal(ModelNode* node, struct aiNode* assimpNode) { // Transform struct aiMatrix4x4 m = assimpNode->mTransformation; aiTransposeMatrix4(&m); - node->transform = mat4_set(mat4_init(), (float*) &m); + mat4_set(node->transform, (float*) &m); // Meshes vec_init(&node->meshes); @@ -148,7 +148,6 @@ ModelData* lovrModelDataFromOpenVRModel(OpenVRModel* vrModel) { } ModelNode* root = malloc(sizeof(ModelNode)); - root->transform = mat4_init(); vec_init(&root->meshes); vec_push(&root->meshes, 0); vec_init(&root->children); diff --git a/src/lovr/headset.c b/src/lovr/headset.c index a399aba2..50f8d9c0 100644 --- a/src/lovr/headset.c +++ b/src/lovr/headset.c @@ -155,9 +155,9 @@ int l_lovrHeadsetGetPosition(lua_State* L) { } int l_lovrHeadsetGetOrientation(lua_State* L) { - float w, x, y, z; - lovrHeadsetGetOrientation(&w, &x, &y, &z); - lua_pushnumber(L, w); + float angle, x, y, z; + lovrHeadsetGetOrientation(&angle, &x, &y, &z); + lua_pushnumber(L, angle); lua_pushnumber(L, x); lua_pushnumber(L, y); lua_pushnumber(L, z); diff --git a/src/lovr/math.c b/src/lovr/math.c index a6ea107b..39c8f494 100644 --- a/src/lovr/math.c +++ b/src/lovr/math.c @@ -24,17 +24,18 @@ int l_lovrMathInit(lua_State* L) { } int l_lovrMathNewVector(lua_State* L) { + float x, y, z; + if (lua_gettop(L) == 1) { - vec3 v = luax_newvector(L); - v[0] = v[1] = v[2] = luaL_checknumber(L, 1); - return 1; + x = y = z = luaL_checknumber(L, 1); } else { - vec3 v = luax_newvector(L); - v[0] = luaL_checknumber(L, 1); - v[1] = luaL_checknumber(L, 2); - v[2] = luaL_checknumber(L, 3); - return 1; + x = luaL_checknumber(L, 1); + y = luaL_checknumber(L, 2); + z = luaL_checknumber(L, 3); } + + vec3_set(luax_newvector(L), x, y, z); + return 1; } int l_lovrMathNewRotation(lua_State* L) { @@ -68,12 +69,9 @@ int l_lovrMathNewTransform(lua_State* L) { float ax = luaL_optnumber(L, 6, 0); float ay = luaL_optnumber(L, 7, 0); float az = luaL_optnumber(L, 8, 0); - float rotation[4]; - float axis[3] = { ax, ay, az }; - quat_fromAngleAxis(rotation, angle, axis); mat4_translate(m, x, y, z); mat4_scale(m, s, s, s); - mat4_rotate(m, rotation); + mat4_rotate(m, angle, ax, ay, az); } return 1; diff --git a/src/lovr/types/controller.c b/src/lovr/types/controller.c index c3bfecd4..56630276 100644 --- a/src/lovr/types/controller.c +++ b/src/lovr/types/controller.c @@ -34,9 +34,9 @@ int l_lovrControllerGetPosition(lua_State* L) { int l_lovrControllerGetOrientation(lua_State* L) { Controller* controller = luax_checktype(L, 1, Controller); - float w, x, y, z; - lovrHeadsetControllerGetOrientation(controller, &w, &x, &y, &z); - lua_pushnumber(L, w); + float angle, x, y, z; + lovrHeadsetControllerGetOrientation(controller, &angle, &x, &y, &z); + lua_pushnumber(L, angle); lua_pushnumber(L, x); lua_pushnumber(L, y); lua_pushnumber(L, z); diff --git a/src/lovr/types/rotation.c b/src/lovr/types/rotation.c index 2211688a..5c18f05b 100644 --- a/src/lovr/types/rotation.c +++ b/src/lovr/types/rotation.c @@ -1,4 +1,5 @@ #include "lovr/types/rotation.h" +#include "lovr/types/vector.h" #include "math/vec3.h" #include "util.h" @@ -16,9 +17,10 @@ quat luax_checkrotation(lua_State* L, int i) { const luaL_Reg lovrRotation[] = { { "clone", l_lovrRotationClone }, { "unpack", l_lovrRotationUnpack }, + { "apply", l_lovrRotationApply }, { "normalize", l_lovrRotationNormalize }, { "rotate", l_lovrRotationRotate }, - { "slerp", l_lovrRotationSlerp }, + { "mix", l_lovrRotationMix }, { "__mul", l_lovrRotationMul }, { "__len", l_lovrRotationLen }, { NULL, NULL } @@ -26,14 +28,14 @@ const luaL_Reg lovrRotation[] = { int l_lovrRotationClone(lua_State* L) { quat q = luax_checkrotation(L, 1); - quat_set(luax_newrotation(L), q); + quat_init(luax_newrotation(L), q); return 1; } int l_lovrRotationUnpack(lua_State* L) { quat q = luax_checkrotation(L, 1); float angle, x, y, z; - quat_toAngleAxis(q, &angle, &x, &y, &z); + quat_getAngleAxis(q, &angle, &x, &y, &z); lua_pushnumber(L, angle); lua_pushnumber(L, x); lua_pushnumber(L, y); @@ -41,6 +43,14 @@ int l_lovrRotationUnpack(lua_State* L) { return 4; } +int l_lovrRotationApply(lua_State* L) { + quat q = luax_checkrotation(L, 1); + quat r = luax_checkrotation(L, 2); + quat_multiply(q, r); + lua_pushvalue(L, 1); + return 1; +} + int l_lovrRotationNormalize(lua_State* L) { quat q = luax_checkrotation(L, 1); quat_normalize(q); @@ -49,30 +59,42 @@ int l_lovrRotationNormalize(lua_State* L) { int l_lovrRotationRotate(lua_State* L) { quat q = luax_checkrotation(L, 1); - float v[3]; - v[0] = luaL_checknumber(L, 2); - v[1] = luaL_checknumber(L, 3); - v[2] = luaL_checknumber(L, 4); - vec3_rotate(v, q); - lua_pushnumber(L, v[0]); - lua_pushnumber(L, v[1]); - lua_pushnumber(L, v[2]); - return 3; + if (lua_isnumber(L, 2)) { + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + float v[3]; + vec3_rotate(vec3_set(v, x, y, z), q); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; + } else { + vec3 v = luax_checkvector(L, 2); + vec3_rotate(v, q); + return 1; + } } -int l_lovrRotationSlerp(lua_State* L) { +int l_lovrRotationMix(lua_State* L) { quat q = luax_checkrotation(L, 1); quat r = luax_checkrotation(L, 2); float t = luaL_checknumber(L, 3); - quat_slerp(quat_set(luax_newrotation(L), q), r, t); + quat_slerp(quat_init(luax_newrotation(L), q), r, t); return 1; } int l_lovrRotationMul(lua_State* L) { quat q = luax_checkrotation(L, 1); - quat r = luax_checkrotation(L, 2); - quat_multiply(quat_set(luax_newrotation(L), q), r); - return 1; + if (luax_istype(L, 2, "Rotation")) { + quat r = luax_checkrotation(L, 2); + quat_multiply(quat_init(luax_newrotation(L), q), r); + return 1; + } else { + vec3 v = luax_checkvector(L, 2); + vec3_rotate(vec3_init(luax_newvector(L), v), q); + return 1; + } } int l_lovrRotationLen(lua_State* L) { diff --git a/src/lovr/types/rotation.h b/src/lovr/types/rotation.h index 90855c28..da67036d 100644 --- a/src/lovr/types/rotation.h +++ b/src/lovr/types/rotation.h @@ -9,8 +9,9 @@ vec3 luax_checkrotation(lua_State* L, int i); extern const luaL_Reg lovrRotation[]; int l_lovrRotationClone(lua_State* L); int l_lovrRotationUnpack(lua_State* L); +int l_lovrRotationApply(lua_State* L); int l_lovrRotationNormalize(lua_State* L); int l_lovrRotationRotate(lua_State* L); -int l_lovrRotationSlerp(lua_State* L); +int l_lovrRotationMix(lua_State* L); int l_lovrRotationMul(lua_State* L); int l_lovrRotationLen(lua_State* L); diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index 47494a17..6e071019 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -1,5 +1,6 @@ #include "lovr/types/transform.h" #include "lovr/types/rotation.h" +#include "lovr/types/vector.h" #include "math/vec3.h" #include "util.h" @@ -17,8 +18,8 @@ mat4 luax_checktransform(lua_State* L, int i) { const luaL_Reg lovrTransform[] = { { "clone", l_lovrTransformClone }, { "unpack", l_lovrTransformUnpack }, - { "inverse", l_lovrTransformInverse }, { "apply", l_lovrTransformApply }, + { "inverse", l_lovrTransformInverse }, { "origin", l_lovrTransformOrigin }, { "translate", l_lovrTransformTranslate }, { "rotate", l_lovrTransformRotate }, @@ -38,16 +39,24 @@ int l_lovrTransformUnpack(lua_State* L) { return 0; } -int l_lovrTransformInverse(lua_State* L) { +int l_lovrTransformApply(lua_State* L) { mat4 m = luax_checktransform(L, 1); - mat4_invert(mat4_set(luax_newtransform(L), m)); + + if (luax_istype(L, 2, "Transform")) { + mat4 n = luax_checktransform(L, 2); + mat4_multiply(m, n); + } else { + quat q = luax_checkrotation(L, 2); + mat4_rotateQuat(m, q); + } + + lua_pushvalue(L, 1); return 1; } -int l_lovrTransformApply(lua_State* L) { +int l_lovrTransformInverse(lua_State* L) { mat4 m = luax_checktransform(L, 1); - mat4 n = luax_checktransform(L, 2); - mat4_multiply(m, n); + mat4_invert(mat4_set(luax_newtransform(L), m)); return 1; } @@ -59,11 +68,18 @@ int l_lovrTransformOrigin(lua_State* L) { int l_lovrTransformTranslate(lua_State* L) { mat4 m = luax_checktransform(L, 1); - float x = luaL_checknumber(L, 2); - float y = luaL_checknumber(L, 3); - float z = luaL_checknumber(L, 4); - mat4_translate(m, x, y, z); - lua_settop(L, 1); + + if (lua_isnumber(L, 2)) { + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + mat4_translate(m, x, y, z); + } else { + vec3 v = luax_checkvector(L, 1); + mat4_translate(m, v[0], v[1], v[2]); + } + + lua_pushvalue(L, 1); return 1; } @@ -72,43 +88,53 @@ int l_lovrTransformRotate(lua_State* L) { if (lua_isnumber(L, 2)) { float angle = luaL_checknumber(L, 2); - float axis[3]; - axis[0] = luaL_checknumber(L, 3); - axis[1] = luaL_checknumber(L, 4); - axis[2] = luaL_checknumber(L, 5); - float q[4]; - quat_fromAngleAxis(q, angle, axis); - mat4_rotate(m, q); + float x = luaL_checknumber(L, 3); + float y = luaL_checknumber(L, 4); + float z = luaL_checknumber(L, 5); + mat4_rotate(m, angle, x, y, z); } else if (luax_istype(L, 2, "Rotation")) { quat q = luax_checkrotation(L, 2); - mat4_rotate(m, q); + mat4_rotateQuat(m, q); } - lua_settop(L, 1); + lua_pushvalue(L, 1); return 1; } int l_lovrTransformScale(lua_State* L) { mat4 m = luax_checktransform(L, 1); - float x = luaL_checknumber(L, 2); - float y = lua_gettop(L) > 2 ? luaL_checknumber(L, 3) : x; - float z = lua_gettop(L) > 2 ? luaL_checknumber(L, 4) : x; - mat4_scale(m, x, y, z); - lua_settop(L, 1); + + if (lua_isnumber(L, 2)) { + float x = luaL_checknumber(L, 2); + float y = lua_gettop(L) > 2 ? luaL_checknumber(L, 3) : x; + float z = lua_gettop(L) > 2 ? luaL_checknumber(L, 4) : x; + mat4_scale(m, x, y, z); + } else { + vec3 v = luax_checkvector(L, 1); + mat4_scale(m, v[0], v[1], v[2]); + } + + lua_pushvalue(L, 1); return 1; } int l_lovrTransformTransform(lua_State* L) { mat4 m = luax_checktransform(L, 1); - float v[3]; - v[0] = luaL_checknumber(L, 2); - v[1] = luaL_checknumber(L, 3); - v[2] = luaL_checknumber(L, 4); - vec3_transform(v, m); - lua_pushnumber(L, v[0]); - lua_pushnumber(L, v[1]); - lua_pushnumber(L, v[2]); - return 3; + if (lua_isnumber(L, 2)) { + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + float v[3]; + vec3_transform(vec3_set(v, x, y, z), m); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; + } else { + vec3 v = luax_checkvector(L, 2); + vec3_transform(v, m); + return 1; + } } int l_lovrTransformMul(lua_State* L) { diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h index 41773b3e..c784f977 100644 --- a/src/lovr/types/transform.h +++ b/src/lovr/types/transform.h @@ -9,8 +9,8 @@ mat4 luax_checktransform(lua_State* L, int i); extern const luaL_Reg lovrTransform[]; int l_lovrTransformClone(lua_State* L); int l_lovrTransformUnpack(lua_State* L); -int l_lovrTransformInverse(lua_State* L); int l_lovrTransformApply(lua_State* L); +int l_lovrTransformInverse(lua_State* L); int l_lovrTransformOrigin(lua_State* L); int l_lovrTransformTranslate(lua_State* L); int l_lovrTransformRotate(lua_State* L); diff --git a/src/lovr/types/vector.c b/src/lovr/types/vector.c index 24d4fcf5..5bfcdd70 100644 --- a/src/lovr/types/vector.c +++ b/src/lovr/types/vector.c @@ -1,4 +1,6 @@ #include "lovr/types/vector.h" +#include "lovr/types/rotation.h" +#include "lovr/types/transform.h" #include "util.h" vec3 luax_newvector(lua_State* L) { @@ -15,6 +17,7 @@ vec3 luax_checkvector(lua_State* L, int i) { const luaL_Reg lovrVector[] = { { "clone", l_lovrVectorClone }, { "unpack", l_lovrVectorUnpack }, + { "apply", l_lovrVectorApply }, { "scale", l_lovrVectorScale }, { "normalize", l_lovrVectorNormalize }, { "distance", l_lovrVectorDistance }, @@ -26,13 +29,13 @@ const luaL_Reg lovrVector[] = { { "__sub", l_lovrVectorSub }, { "__mul", l_lovrVectorMul }, { "__div", l_lovrVectorDiv }, - { "__len", l_lovrVectorLength }, + { "__len", l_lovrVectorLen }, { NULL, NULL } }; int l_lovrVectorClone(lua_State* L) { vec3 v = luax_checkvector(L, 1); - vec3_set(luax_newvector(L), v); + vec3_init(luax_newvector(L), v); return 1; } @@ -44,6 +47,21 @@ int l_lovrVectorUnpack(lua_State* L) { return 3; } +int l_lovrVectorApply(lua_State* L) { + vec3 v = luax_checkvector(L, 1); + + if (luax_istype(L, 2, "Rotation")) { + quat q = luax_checkrotation(L, 2); + vec3_rotate(v, q); + } else if (luax_istype(L, 2, "Transform")) { + mat4 m = luax_checktransform(L, 2); + vec3_transform(v, m); + } + + lua_pushvalue(L, 1); + return 1; +} + int l_lovrVectorScale(lua_State* L) { vec3 v = luax_checkvector(L, 1); float s = luaL_checknumber(L, 2); @@ -81,7 +99,7 @@ int l_lovrVectorDot(lua_State* L) { int l_lovrVectorCross(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); - vec3_cross(vec3_set(luax_newvector(L), u), v); + vec3_cross(vec3_init(luax_newvector(L), u), v); return 1; } @@ -89,39 +107,39 @@ int l_lovrVectorLerp(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); float t = luaL_checknumber(L, 3); - vec3_lerp(vec3_set(luax_newvector(L), u), v, t); + vec3_lerp(vec3_init(luax_newvector(L), u), v, t); return 1; } int l_lovrVectorAdd(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); - vec3_add(vec3_set(luax_newvector(L), u), v); + vec3_add(vec3_init(luax_newvector(L), u), v); return 1; } int l_lovrVectorSub(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); - vec3_sub(vec3_set(luax_newvector(L), u), v); + vec3_sub(vec3_init(luax_newvector(L), u), v); return 1; } int l_lovrVectorMul(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); - vec3_mul(vec3_set(luax_newvector(L), u), v); + vec3_mul(vec3_init(luax_newvector(L), u), v); return 1; } int l_lovrVectorDiv(lua_State* L) { vec3 u = luax_checkvector(L, 1); vec3 v = luax_checkvector(L, 2); - vec3_div(vec3_set(luax_newvector(L), u), v); + vec3_div(vec3_init(luax_newvector(L), u), v); return 1; } -int l_lovrVectorLength(lua_State* L) { +int l_lovrVectorLen(lua_State* L) { vec3 u = luax_checkvector(L, 1); lua_pushnumber(L, vec3_length(u)); return 1; diff --git a/src/lovr/types/vector.h b/src/lovr/types/vector.h index bcf87d6e..042af39a 100644 --- a/src/lovr/types/vector.h +++ b/src/lovr/types/vector.h @@ -9,6 +9,7 @@ vec3 luax_checkvector(lua_State* L, int i); extern const luaL_Reg lovrVector[]; int l_lovrVectorClone(lua_State* L); int l_lovrVectorUnpack(lua_State* L); +int l_lovrVectorApply(lua_State* L); int l_lovrVectorScale(lua_State* L); int l_lovrVectorNormalize(lua_State* L); int l_lovrVectorDistance(lua_State* L); @@ -20,4 +21,4 @@ int l_lovrVectorAdd(lua_State* L); int l_lovrVectorSub(lua_State* L); int l_lovrVectorMul(lua_State* L); int l_lovrVectorDiv(lua_State* L); -int l_lovrVectorLength(lua_State* L); +int l_lovrVectorLen(lua_State* L); diff --git a/src/math/mat4.c b/src/math/mat4.c index de396b21..14ac3ec4 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -1,5 +1,6 @@ #include "math/mat4.h" -#include "util.h" +#include "math/quat.h" +#include "math/vec3.h" #include #include #include @@ -9,9 +10,8 @@ // m2 m6 m10 m14 // m3 m7 m11 m15 -mat4 mat4_init() { - mat4 m = malloc(16 * sizeof(float)); - return mat4_identity(m); +mat4 mat4_set(mat4 m, mat4 n) { + return memcpy(m, n, 16 * sizeof(float)); } mat4 mat4_fromMat34(mat4 m, float (*n)[4]) { @@ -54,10 +54,6 @@ mat4 mat4_fromMat44(mat4 m, float (*n)[4]) { 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; @@ -172,7 +168,14 @@ mat4 mat4_translate(mat4 m, float x, float y, float z) { return m; } -mat4 mat4_rotate(mat4 m, quat q) { +mat4 mat4_rotate(mat4 m, float angle, float x, float y, float z) { + float q[4]; + float v[3]; + quat_fromAngleAxis(q, angle, vec3_set(v, x, y, z)); + return mat4_rotateQuat(m, q); +} + +mat4 mat4_rotateQuat(mat4 m, quat q) { float x = q[0]; float y = q[1]; float z = q[2]; @@ -237,21 +240,3 @@ mat4 mat4_perspective(mat4 m, float near, float far, float fovy, float aspect) { 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; -} diff --git a/src/math/mat4.h b/src/math/mat4.h index a7a2959c..02d232c1 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -1,16 +1,16 @@ #include "math/math.h" -mat4 mat4_init(); +#define mat4_init mat4_set +mat4 mat4_set(mat4 m, mat4 n); 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_rotate(mat4 m, quat q); +mat4 mat4_rotate(mat4 m, float angle, float x, float y, float z); +mat4 mat4_rotateQuat(mat4 m, quat q); mat4 mat4_scale(mat4 m, float x, float y, float z); 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); diff --git a/src/math/quat.c b/src/math/quat.c index b5913b63..d0700a0e 100644 --- a/src/math/quat.c +++ b/src/math/quat.c @@ -1,10 +1,14 @@ #include "math/quat.h" #include "math/vec3.h" +#include "util.h" #include #include -quat quat_init(float x, float y, float z, float w) { - quat q = malloc(4 * sizeof(float)); +quat quat_init(quat q, quat r) { + return quat_set(q, r[0], r[1], r[2], r[3]); +} + +quat quat_set(quat q, float x, float y, float z, float w) { q[0] = x; q[1] = y; q[2] = z; @@ -25,19 +29,28 @@ quat quat_fromAngleAxis(quat q, float angle, vec3 axis) { quat quat_fromDirection(quat q, vec3 forward, vec3 up) { vec3 qq = (vec3) q; - vec3_set(qq, forward); + vec3_init(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]; +quat quat_fromMat4(quat q, mat4 m) { + 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; } @@ -111,25 +124,22 @@ quat quat_between(quat q, vec3 u, vec3 v) { q[3] = 1.f; return q; } else if (dot < -.99999) { - float axis[3] = { 1, 0, 0 }; - vec3_cross(axis, u); + float axis[3]; + vec3_cross(vec3_set(axis, 1, 0, 0), u); if (vec3_length(axis) < .00001) { - axis[0] = 0; - axis[1] = 1; - axis[2] = 0; - vec3_cross(axis, u); + vec3_cross(vec3_set(axis, 0, 1, 0), u); } vec3_normalize(axis); quat_fromAngleAxis(q, M_PI, axis); return q; } - vec3_cross(vec3_set(q, u), v); + vec3_cross(vec3_init(q, u), v); q[3] = 1 + dot; return quat_normalize(q); } -void quat_toAngleAxis(quat q, float* angle, float* x, float* y, float* z) { +void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z) { if (q[3] > 1 || q[3] < -1) { quat_normalize(q); } diff --git a/src/math/quat.h b/src/math/quat.h index cfbc67bd..a6866b66 100644 --- a/src/math/quat.h +++ b/src/math/quat.h @@ -1,12 +1,13 @@ #include "math/math.h" -quat quat_init(float x, float y, float z, float w); +quat quat_init(quat q, quat r); +quat quat_set(quat q, 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_fromMat4(quat q, mat4 m); 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); +void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z); diff --git a/src/math/vec3.c b/src/math/vec3.c index 9e7db735..4125f67b 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -3,21 +3,17 @@ #include #include -vec3 vec3_init(float x, float y, float z) { - vec3 v = malloc(3 * sizeof(float)); +vec3 vec3_init(vec3 v, vec3 u) { + return vec3_set(v, u[0], u[1], u[2]); +} + +vec3 vec3_set(vec3 v, float x, float y, float z) { v[0] = x; v[1] = y; v[2] = z; return v; } -vec3 vec3_set(vec3 v, vec3 u) { - v[0] = u[0]; - v[1] = u[1]; - v[2] = u[2]; - return v; -} - vec3 vec3_add(vec3 v, vec3 u) { v[0] += u[0]; v[1] += u[1]; @@ -55,15 +51,7 @@ vec3 vec3_scale(vec3 v, float s) { vec3 vec3_normalize(vec3 v) { float len = vec3_length(v); - if (len == 0) { - return v; - } - - len = 1 / len; - v[0] *= len; - v[1] *= len; - v[2] *= len; - return v; + return len == 0 ? v : vec3_scale(v, 1 / len); } float vec3_length(vec3 v) { @@ -86,21 +74,19 @@ float vec3_dot(vec3 v, vec3 u) { } vec3 vec3_cross(vec3 v, vec3 u) { - float v0 = v[0]; - float v1 = v[1]; - float v2 = v[2]; - v[0] = v1 * u[2] - v2 * u[1]; - v[1] = v0 * u[2] - v2 * u[0]; - v[2] = v0 * u[1] - v1 * u[0]; - return v; + return vec3_set(v, + v[1] * u[2] - v[2] * u[1], + v[2] * u[0] - v[0] * u[2], + v[0] * u[1] - v[1] * u[0] + ); } 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); + vec3_init(u, q); + vec3_cross(vec3_init(c, u), v); float uu = vec3_dot(u, u); float uv = vec3_dot(u, v); vec3_scale(u, 2 * uv); @@ -110,13 +96,11 @@ vec3 vec3_rotate(vec3 v, quat q) { } 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; + return vec3_set(v, + v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12], + v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13], + v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14] + ); } vec3 vec3_lerp(vec3 v, vec3 u, float t) { diff --git a/src/math/vec3.h b/src/math/vec3.h index a3fef7de..e0d1c406 100644 --- a/src/math/vec3.h +++ b/src/math/vec3.h @@ -1,7 +1,7 @@ #include "math/math.h" -vec3 vec3_init(float x, float y, float z); -vec3 vec3_set(vec3 v, vec3 u); +vec3 vec3_init(vec3 v, vec3 u); +vec3 vec3_set(vec3 v, float x, float y, float z); vec3 vec3_add(vec3 v, vec3 u); vec3 vec3_sub(vec3 v, vec3 u); vec3 vec3_mul(vec3 v, vec3 u); From a118a6bff5db4b81cf5800fbe86469cb3b0daceb Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 18:50:51 -0800 Subject: [PATCH 09/17] Cleanup; --- src/audio/audio.c | 84 ++++++++--------------------------------- src/audio/audio.h | 2 + src/graphics/graphics.c | 15 +++----- 3 files changed, 24 insertions(+), 77 deletions(-) diff --git a/src/audio/audio.c b/src/audio/audio.c index eb2e80cd..786762bb 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -1,5 +1,7 @@ #include "audio/audio.h" #include "loaders/source.h" +#include "math/vec3.h" +#include "math/quat.h" #include "util.h" #include #include @@ -8,12 +10,6 @@ static AudioState state; static LPALCRESETDEVICESOFT alcResetDeviceSOFT; -static void cross(float ux, float uy, float uz, float vx, float vy, float vz, float* x, float* y, float* z) { - *x = uy * vz - uz * vy; - *y = ux * vz - uz * vx; - *z = ux * vy - uy * vx; -} - void lovrAudioInit() { ALCdevice* device = alcOpenDevice(NULL); if (!device) { @@ -35,6 +31,9 @@ void lovrAudioInit() { state.device = device; state.context = context; vec_init(&state.sources); + + vec3_set(state.position, 0, 0, 0); + quat_set(state.orientation, 0, 0, 0, -1); } void lovrAudioDestroy() { @@ -73,29 +72,7 @@ void lovrAudioAdd(Source* source) { } void lovrAudioGetOrientation(float* angle, float* ax, float* ay, float* az) { - float v[6]; - alGetListenerfv(AL_ORIENTATION, v); - float cx, cy, cz; - cross(v[0], v[1], v[2], v[3], v[4], v[5], &cx, &cy, &cz); - float w = 1 + v[0] * v[3] + v[1] * v[4] + v[2] * v[5]; - float len = sqrt(cx * cx + cy * cy + cz * cz + w * w); - if (len != 1) { - cx /= len; - cy /= len; - cz /= len; - w /= len; - } - *angle = 2 * acos(w); - float s = sqrt(1 - w * w); - if (s < .001) { - *ax = cx; - *ay = cy; - *az = cz; - } else { - *ax = cx / s; - *ay = cy / s; - *az = cz / s; - } + quat_getAngleAxis(state.orientation, angle, ax, ay, az); } void lovrAudioGetPosition(float* x, float* y, float* z) { @@ -135,52 +112,23 @@ void lovrAudioRewind() { } } -// Help void lovrAudioSetOrientation(float angle, float ax, float ay, float az) { - // Quaternion - float cos2 = cos(angle / 2.f); - float sin2 = sin(angle / 2.f); - float qx = sin2 * ax; - float qy = sin2 * ay; - float qz = sin2 * az; - float s = cos2; + // Rotate the unit forward/up vectors by the quaternion derived from the specified angle/axis + float f[3] = { 0, 0, -1 }; + float u[3] = { 0, 1, 0 }; + float axis[3] = { ax, ay, az }; + quat_fromAngleAxis(state.orientation, angle, axis); + vec3_rotate(f, state.orientation); + vec3_rotate(u, state.orientation); - float vx, vy, vz, qdotv, qdotq, a, b, c, cx, cy, cz; - - // Forward - vx = 0; - vy = 0; - vz = -1; - qdotv = qx * vx + qy * vy + qz * vz; - qdotq = qx * qx + qy * qy + qz * qz; - a = 2 * qdotv; - b = s * s - qdotq; - c = 2 * s; - cross(qx, qy, qz, vx, vy, vz, &cx, &cy, &cz); - float fx = a * qx + b * vx + c * cx; - float fy = a * qy + b * vy + c * cy; - float fz = a * qz + b * vz + c * cz; - - // Up - vx = 0; - vy = 1; - vz = 0; - qdotv = qx * vx + qy * vy + qz * vz; - qdotq = qx * qx + qy * qy + qz * qz; - a = 2 * qdotv; - b = s * s - qdotq; - c = 2 * s; - cross(qx, qy, qz, vx, vy, vz, &cx, &cy, &cz); - float ux = a * qx + b * vx + c * cx; - float uy = a * qy + b * vy + c * cy; - float uz = a * qz + b * vz + c * cz; - - ALfloat orientation[6] = { fx, fy, fz, ux, uy, uz }; + // Pass the rotated orientation vectors to OpenAL + ALfloat orientation[6] = { f[0], f[1], f[2], u[0], u[1], u[2] }; alListenerfv(AL_ORIENTATION, orientation); } void lovrAudioSetPosition(float x, float y, float z) { + vec3_set(state.position, x, y, z); alListener3f(AL_POSITION, x, y, z); } diff --git a/src/audio/audio.h b/src/audio/audio.h index d7a43b9b..9b98dc7d 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -11,6 +11,8 @@ typedef struct { ALCdevice* device; ALCcontext* context; vec_void_t sources; + float position[3]; + float orientation[4]; } AudioState; #endif diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 6cb32836..5aebae8e 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -415,16 +415,13 @@ void lovrGraphicsTriangle(DrawMode mode, float* points) { vec_pusharr(&state.shapeData, points, 9); lovrGraphicsDrawPrimitive(GL_LINE_LOOP, NULL, 0, 0, 0); } else { - float n[3] = { - points[1] * points[5] - points[2] * points[4], - points[2] * points[3] - points[0] * points[5], - points[0] * points[4] - points[1] * points[3] - }; + float normal[3]; + vec3_cross(vec3_init(normal, &points[0]), &points[3]); float data[18] = { - points[0], points[1], points[2], n[0], n[1], n[2], - points[3], points[4], points[5], n[0], n[1], n[2], - points[6], points[7], points[8], n[0], n[1], n[2] + points[0], points[1], points[2], normal[0], normal[1], normal[2], + points[3], points[4], points[5], normal[0], normal[1], normal[2], + points[6], points[7], points[8], normal[0], normal[1], normal[2] }; vec_clear(&state.shapeData); @@ -437,7 +434,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float // Normalize the normal vector float len = sqrt(nx * nx + ny * ny + nz + nz); - if (len != 1) { + if (len != 0) { len = 1 / len; nx *= len; ny *= len; From 5e2cfcc9bd16c3f5a0f3b6ca22ec86a747f691f8 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 19:11:42 -0800 Subject: [PATCH 10/17] graphics.cube and Model:draw accept Transform; --- src/graphics/graphics.c | 4 ++-- src/graphics/graphics.h | 2 +- src/graphics/model.c | 4 ++-- src/graphics/model.h | 2 +- src/lovr/graphics.c | 14 +++++--------- src/lovr/math.c | 14 +------------- src/lovr/types/model.c | 13 ++++--------- src/lovr/types/transform.c | 19 +++++++++++++++++++ src/lovr/types/transform.h | 1 + 9 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 5aebae8e..6e7de673 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -499,9 +499,9 @@ void lovrGraphicsPlaneFullscreen(Texture* texture) { lovrRelease(&lastShader->ref); } -void lovrGraphicsCube(DrawMode mode, Texture* texture, float x, float y, float z, float size, float angle, float axisX, float axisY, float axisZ) { +void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform) { lovrGraphicsPush(); - lovrGraphicsTransform(x, y, z, size, size, size, angle, axisX, axisY, axisZ); + lovrGraphicsMatrixTransform(transform); if (mode == DRAW_MODE_LINE) { float points[] = { diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 68553a34..c13e5372 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -134,5 +134,5 @@ void lovrGraphicsLine(float* points, int count); void lovrGraphicsTriangle(DrawMode mode, float* points); void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float z, float size, float nx, float ny, float nz); void lovrGraphicsPlaneFullscreen(Texture* texture); -void lovrGraphicsCube(DrawMode mode, Texture* texture, float x, float y, float z, float size, float angle, float axisX, float axisY, float axisZ); +void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform); void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az); diff --git a/src/graphics/model.c b/src/graphics/model.c index 9e7fcd47..73191496 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -140,9 +140,9 @@ void lovrModelDataDestroy(ModelData* modelData) { free(modelData); } -void lovrModelDraw(Model* model, float x, float y, float z, float scale, float angle, float ax, float ay, float az) { +void lovrModelDraw(Model* model, mat4 transform) { lovrGraphicsPush(); - lovrGraphicsTransform(x, y, z, scale, scale, scale, angle, ax, ay, az); + lovrGraphicsMatrixTransform(transform); lovrBufferDraw(model->buffer); lovrGraphicsPop(); } diff --git a/src/graphics/model.h b/src/graphics/model.h index c1ce9d3b..ebebfa8d 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -58,6 +58,6 @@ typedef struct { Model* lovrModelCreate(ModelData* modelData); void lovrModelDestroy(const Ref* ref); void lovrModelDataDestroy(ModelData* modelData); -void lovrModelDraw(Model* model, float x, float y, float z, float scale, float angle, float ax, float ay, float az); +void lovrModelDraw(Model* model, mat4 transform); Texture* lovrModelGetTexture(Model* model); void lovrModelSetTexture(Model* model, Texture* texture); diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index 2f7fcf65..32530a2a 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -4,10 +4,12 @@ #include "lovr/types/shader.h" #include "lovr/types/skybox.h" #include "lovr/types/texture.h" +#include "lovr/types/transform.h" #include "graphics/graphics.h" #include "loaders/model.h" #include "loaders/texture.h" #include "filesystem/filesystem.h" +#include "math/mat4.h" #include "util.h" #include @@ -509,15 +511,9 @@ int l_lovrGraphicsCube(lua_State* L) { drawMode = DRAW_MODE_FILL; texture = luax_checktype(L, 1, Texture); } - float x = luaL_optnumber(L, 2, 0.f); - float y = luaL_optnumber(L, 3, 0.f); - float z = luaL_optnumber(L, 4, 0.f); - float s = luaL_optnumber(L, 5, 1.f); - float angle = luaL_optnumber(L, 6, 0.f); - float axisX = luaL_optnumber(L, 7, 0.f); - float axisY = luaL_optnumber(L, 8, 1.f); - float axisZ = luaL_optnumber(L, 9, 0.f); - lovrGraphicsCube(drawMode, texture, x, y, z, s, angle, axisX, axisY, axisZ); + float transform[16]; + luax_readtransform(L, 2, transform); + lovrGraphicsCube(drawMode, texture, transform); return 0; } diff --git a/src/lovr/math.c b/src/lovr/math.c index 39c8f494..591deca9 100644 --- a/src/lovr/math.c +++ b/src/lovr/math.c @@ -59,20 +59,8 @@ int l_lovrMathNewTransform(lua_State* L) { int hasArgs = lua_gettop(L) > 0; mat4 m = luax_newtransform(L); mat4_identity(m); - if (hasArgs) { - float x = luaL_checknumber(L, 1); - float y = luaL_checknumber(L, 2); - float z = luaL_checknumber(L, 3); - float s = luaL_optnumber(L, 4, 1); - float angle = luaL_optnumber(L, 5, 0); - float ax = luaL_optnumber(L, 6, 0); - float ay = luaL_optnumber(L, 7, 0); - float az = luaL_optnumber(L, 8, 0); - mat4_translate(m, x, y, z); - mat4_scale(m, s, s, s); - mat4_rotate(m, angle, ax, ay, az); + luax_readtransform(L, 1, m); } - return 1; } diff --git a/src/lovr/types/model.c b/src/lovr/types/model.c index 9df00115..733cb06e 100644 --- a/src/lovr/types/model.c +++ b/src/lovr/types/model.c @@ -1,5 +1,6 @@ #include "lovr/types/model.h" #include "lovr/types/texture.h" +#include "lovr/types/transform.h" const luaL_Reg lovrModel[] = { { "draw", l_lovrModelDraw }, @@ -10,15 +11,9 @@ const luaL_Reg lovrModel[] = { int l_lovrModelDraw(lua_State* L) { Model* model = luax_checktype(L, 1, Model); - float x = luaL_optnumber(L, 2, 0.f); - float y = luaL_optnumber(L, 3, 0.f); - float z = luaL_optnumber(L, 4, 0.f); - float scale = luaL_optnumber(L, 5, 1.f); - float angle = luaL_optnumber(L, 6, 0.f); - float ax = luaL_optnumber(L, 7, 0.f); - float ay = luaL_optnumber(L, 8, 1.f); - float az = luaL_optnumber(L, 9, 0.f); - lovrModelDraw(model, x, y, z, scale, angle, ax, ay, az); + float transform[16]; + luax_readtransform(L, 2, transform); + lovrModelDraw(model, transform); return 0; } diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index 6e071019..389abe61 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -15,6 +15,25 @@ mat4 luax_checktransform(lua_State* L, int i) { return luaL_checkudata(L, i, "Transform"); } +void luax_readtransform(lua_State* L, int i, mat4 m) { + if (lua_isnumber(L, i)) { + float x = luaL_optnumber(L, i++, 0); + float y = luaL_optnumber(L, i++, 0); + float z = luaL_optnumber(L, i++, 0); + float s = luaL_optnumber(L, i++, 1); + float angle = luaL_optnumber(L, i++, 0); + float ax = luaL_optnumber(L, i++, 0); + float ay = luaL_optnumber(L, i++, 1); + float az = luaL_optnumber(L, i++, 0); + mat4_identity(m); + mat4_translate(m, x, y, z); + mat4_scale(m, s, s, s); + mat4_rotate(m, angle, ax, ay, az); + } else { + mat4_init(m, luax_checktransform(L, i)); + } +} + const luaL_Reg lovrTransform[] = { { "clone", l_lovrTransformClone }, { "unpack", l_lovrTransformUnpack }, diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h index c784f977..d72e5ba1 100644 --- a/src/lovr/types/transform.h +++ b/src/lovr/types/transform.h @@ -5,6 +5,7 @@ mat4 luax_newtransform(lua_State* L); mat4 luax_checktransform(lua_State* L, int i); +void luax_readtransform(lua_State* L, int i, mat4 transform); extern const luaL_Reg lovrTransform[]; int l_lovrTransformClone(lua_State* L); From 4fc7d27750ad81c24cfa0b49eff205da43cd1df5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 19:13:37 -0800 Subject: [PATCH 11/17] lovr.graphics.transform; --- src/lovr/graphics.c | 8 ++++++++ src/lovr/graphics.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index 32530a2a..f6a72f77 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -76,6 +76,7 @@ const luaL_Reg lovrGraphics[] = { { "translate", l_lovrGraphicsTranslate }, { "rotate", l_lovrGraphicsRotate }, { "scale", l_lovrGraphicsScale }, + { "transform", l_lovrGraphicsTransform }, { "points", l_lovrGraphicsPoints }, { "line", l_lovrGraphicsLine }, { "triangle", l_lovrGraphicsTriangle }, @@ -444,6 +445,13 @@ int l_lovrGraphicsScale(lua_State* L) { return 0; } +int l_lovrGraphicsTransform(lua_State* L) { + float transform[16]; + luax_readtransform(L, 1, transform); + lovrGraphicsMatrixTransform(transform); + return 0; +} + // Primitives int l_lovrGraphicsPoints(lua_State* L) { diff --git a/src/lovr/graphics.h b/src/lovr/graphics.h index b73fb2d8..94651820 100644 --- a/src/lovr/graphics.h +++ b/src/lovr/graphics.h @@ -56,6 +56,7 @@ int l_lovrGraphicsOrigin(lua_State* L); int l_lovrGraphicsTranslate(lua_State* L); int l_lovrGraphicsRotate(lua_State* L); int l_lovrGraphicsScale(lua_State* L); +int l_lovrGraphicsTransform(lua_State* L); // Primitives int l_lovrGraphicsPoints(lua_State* L); From 4e43af9624de202874b51f65cbcbc46ac206aff5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 19 Jan 2017 19:27:49 -0800 Subject: [PATCH 12/17] Kill l_lovrTransformUnpack for now; Oh well --- src/lovr/types/transform.c | 5 ----- src/lovr/types/transform.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index 389abe61..24ae758b 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -36,7 +36,6 @@ void luax_readtransform(lua_State* L, int i, mat4 m) { const luaL_Reg lovrTransform[] = { { "clone", l_lovrTransformClone }, - { "unpack", l_lovrTransformUnpack }, { "apply", l_lovrTransformApply }, { "inverse", l_lovrTransformInverse }, { "origin", l_lovrTransformOrigin }, @@ -54,10 +53,6 @@ int l_lovrTransformClone(lua_State* L) { return 1; } -int l_lovrTransformUnpack(lua_State* L) { - return 0; -} - int l_lovrTransformApply(lua_State* L) { mat4 m = luax_checktransform(L, 1); diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h index d72e5ba1..9c49de30 100644 --- a/src/lovr/types/transform.h +++ b/src/lovr/types/transform.h @@ -9,7 +9,6 @@ void luax_readtransform(lua_State* L, int i, mat4 transform); extern const luaL_Reg lovrTransform[]; int l_lovrTransformClone(lua_State* L); -int l_lovrTransformUnpack(lua_State* L); int l_lovrTransformApply(lua_State* L); int l_lovrTransformInverse(lua_State* L); int l_lovrTransformOrigin(lua_State* L); From 07803ef16a8b73ffc7698ac11de7541a9ab2b007 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 20 Jan 2017 19:46:45 -0800 Subject: [PATCH 13/17] Remove Vector and Rotation; --- src/lovr/audio.c | 2 +- src/lovr/graphics.c | 10 +-- src/lovr/headset.c | 2 +- src/lovr/math.c | 51 +----------- src/lovr/math.h | 2 - src/lovr/types/rotation.c | 104 ------------------------ src/lovr/types/rotation.h | 17 ---- src/lovr/types/transform.c | 158 ++++++++++++++----------------------- src/lovr/types/transform.h | 9 +-- src/lovr/types/vector.c | 146 ---------------------------------- src/lovr/types/vector.h | 24 ------ src/math/transform.c | 60 ++++++++++++++ src/math/transform.h | 23 ++++++ src/util.c | 27 ++----- src/util.h | 7 +- 15 files changed, 169 insertions(+), 473 deletions(-) delete mode 100644 src/lovr/types/rotation.c delete mode 100644 src/lovr/types/rotation.h delete mode 100644 src/lovr/types/vector.c delete mode 100644 src/lovr/types/vector.h create mode 100644 src/math/transform.c create mode 100644 src/math/transform.h diff --git a/src/lovr/audio.c b/src/lovr/audio.c index 93b84983..c795690b 100644 --- a/src/lovr/audio.c +++ b/src/lovr/audio.c @@ -24,7 +24,7 @@ const luaL_Reg lovrAudio[] = { int l_lovrAudioInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrAudio); - luax_registertype(L, "Source", lovrSource, luax_releasetype); + luax_registertype(L, "Source", lovrSource); map_init(&TimeUnits); map_set(&TimeUnits, "seconds", UNIT_SECONDS); diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index f6a72f77..72eb418b 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -98,11 +98,11 @@ const luaL_Reg lovrGraphics[] = { int l_lovrGraphicsInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrGraphics); - luax_registertype(L, "Buffer", lovrBuffer, luax_releasetype); - luax_registertype(L, "Model", lovrModel, luax_releasetype); - luax_registertype(L, "Shader", lovrShader, luax_releasetype); - luax_registertype(L, "Skybox", lovrSkybox, luax_releasetype); - luax_registertype(L, "Texture", lovrTexture, luax_releasetype); + luax_registertype(L, "Buffer", lovrBuffer); + luax_registertype(L, "Model", lovrModel); + luax_registertype(L, "Shader", lovrShader); + luax_registertype(L, "Skybox", lovrSkybox); + luax_registertype(L, "Texture", lovrTexture); map_init(&BufferAttributeTypes); map_set(&BufferAttributeTypes, "float", BUFFER_FLOAT); diff --git a/src/lovr/headset.c b/src/lovr/headset.c index 50f8d9c0..0aef999d 100644 --- a/src/lovr/headset.c +++ b/src/lovr/headset.c @@ -38,7 +38,7 @@ const luaL_Reg lovrHeadset[] = { int l_lovrHeadsetInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrHeadset); - luax_registertype(L, "Controller", lovrController, luax_releasetype); + luax_registertype(L, "Controller", lovrController); map_init(&ControllerAxes); map_set(&ControllerAxes, "trigger", CONTROLLER_AXIS_TRIGGER); diff --git a/src/lovr/math.c b/src/lovr/math.c index 591deca9..5370f9a0 100644 --- a/src/lovr/math.c +++ b/src/lovr/math.c @@ -1,15 +1,9 @@ #include "lovr/math.h" -#include "lovr/types/vector.h" -#include "lovr/types/rotation.h" #include "lovr/types/transform.h" -#include "math/vec3.h" -#include "math/quat.h" #include "math/mat4.h" #include "util.h" const luaL_Reg lovrMath[] = { - { "newVector", l_lovrMathNewVector }, - { "newRotation", l_lovrMathNewRotation }, { "newTransform", l_lovrMathNewTransform }, { NULL, NULL } }; @@ -17,50 +11,13 @@ const luaL_Reg lovrMath[] = { int l_lovrMathInit(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrMath); - luax_registertype(L, "Vector", lovrVector, NULL); - luax_registertype(L, "Rotation", lovrRotation, NULL); - luax_registertype(L, "Transform", lovrTransform, NULL); - return 1; -} - -int l_lovrMathNewVector(lua_State* L) { - float x, y, z; - - if (lua_gettop(L) == 1) { - x = y = z = luaL_checknumber(L, 1); - } else { - x = luaL_checknumber(L, 1); - y = luaL_checknumber(L, 2); - z = luaL_checknumber(L, 3); - } - - vec3_set(luax_newvector(L), x, y, z); - return 1; -} - -int l_lovrMathNewRotation(lua_State* L) { - if (lua_gettop(L) == 4) { - float angle = luaL_optnumber(L, 1, 0); - float axis[3]; - axis[0] = luaL_optnumber(L, 2, 0); - axis[1] = luaL_optnumber(L, 3, 0); - axis[2] = luaL_optnumber(L, 4, 0); - quat_fromAngleAxis(luax_newrotation(L), angle, axis); - } else if (lua_isnumber(L, 1) && luax_istype(L, 2, "Vector")) { - quat_fromAngleAxis(luax_newrotation(L), lua_tonumber(L, 1), luax_checkvector(L, 2)); - } else { - quat_between(luax_newrotation(L), luax_checkvector(L, 1), luax_checkvector(L, 2)); - } - + luax_registertype(L, "Transform", lovrTransform); return 1; } int l_lovrMathNewTransform(lua_State* L) { - int hasArgs = lua_gettop(L) > 0; - mat4 m = luax_newtransform(L); - mat4_identity(m); - if (hasArgs) { - luax_readtransform(L, 1, m); - } + float transfrom[16]; + luax_readtransform(L, 1, transfrom); + luax_pushtype(L, Transform, lovrTransformCreate(transfrom)); return 1; } diff --git a/src/lovr/math.h b/src/lovr/math.h index b7ebb509..f6348e60 100644 --- a/src/lovr/math.h +++ b/src/lovr/math.h @@ -4,6 +4,4 @@ extern const luaL_Reg lovrMath[]; int l_lovrMathInit(lua_State* L); -int l_lovrMathNewVector(lua_State* L); -int l_lovrMathNewRotation(lua_State* L); int l_lovrMathNewTransform(lua_State* L); diff --git a/src/lovr/types/rotation.c b/src/lovr/types/rotation.c deleted file mode 100644 index 5c18f05b..00000000 --- a/src/lovr/types/rotation.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "lovr/types/rotation.h" -#include "lovr/types/vector.h" -#include "math/vec3.h" -#include "util.h" - -quat luax_newrotation(lua_State* L) { - quat q = (quat) lua_newuserdata(L, 4 * sizeof(float)); - luaL_getmetatable(L, "Rotation"); - lua_setmetatable(L, -2); - return q; -} - -quat luax_checkrotation(lua_State* L, int i) { - return luaL_checkudata(L, i, "Rotation"); -} - -const luaL_Reg lovrRotation[] = { - { "clone", l_lovrRotationClone }, - { "unpack", l_lovrRotationUnpack }, - { "apply", l_lovrRotationApply }, - { "normalize", l_lovrRotationNormalize }, - { "rotate", l_lovrRotationRotate }, - { "mix", l_lovrRotationMix }, - { "__mul", l_lovrRotationMul }, - { "__len", l_lovrRotationLen }, - { NULL, NULL } -}; - -int l_lovrRotationClone(lua_State* L) { - quat q = luax_checkrotation(L, 1); - quat_init(luax_newrotation(L), q); - return 1; -} - -int l_lovrRotationUnpack(lua_State* L) { - quat q = luax_checkrotation(L, 1); - float angle, x, y, z; - quat_getAngleAxis(q, &angle, &x, &y, &z); - lua_pushnumber(L, angle); - lua_pushnumber(L, x); - lua_pushnumber(L, y); - lua_pushnumber(L, z); - return 4; -} - -int l_lovrRotationApply(lua_State* L) { - quat q = luax_checkrotation(L, 1); - quat r = luax_checkrotation(L, 2); - quat_multiply(q, r); - lua_pushvalue(L, 1); - return 1; -} - -int l_lovrRotationNormalize(lua_State* L) { - quat q = luax_checkrotation(L, 1); - quat_normalize(q); - return 1; -} - -int l_lovrRotationRotate(lua_State* L) { - quat q = luax_checkrotation(L, 1); - if (lua_isnumber(L, 2)) { - float x = luaL_checknumber(L, 2); - float y = luaL_checknumber(L, 3); - float z = luaL_checknumber(L, 4); - float v[3]; - vec3_rotate(vec3_set(v, x, y, z), q); - lua_pushnumber(L, v[0]); - lua_pushnumber(L, v[1]); - lua_pushnumber(L, v[2]); - return 3; - } else { - vec3 v = luax_checkvector(L, 2); - vec3_rotate(v, q); - return 1; - } -} - -int l_lovrRotationMix(lua_State* L) { - quat q = luax_checkrotation(L, 1); - quat r = luax_checkrotation(L, 2); - float t = luaL_checknumber(L, 3); - quat_slerp(quat_init(luax_newrotation(L), q), r, t); - return 1; -} - -int l_lovrRotationMul(lua_State* L) { - quat q = luax_checkrotation(L, 1); - if (luax_istype(L, 2, "Rotation")) { - quat r = luax_checkrotation(L, 2); - quat_multiply(quat_init(luax_newrotation(L), q), r); - return 1; - } else { - vec3 v = luax_checkvector(L, 2); - vec3_rotate(vec3_init(luax_newvector(L), v), q); - return 1; - } -} - -int l_lovrRotationLen(lua_State* L) { - quat q = luax_checkrotation(L, 1); - lua_pushnumber(L, quat_length(q)); - return 1; -} diff --git a/src/lovr/types/rotation.h b/src/lovr/types/rotation.h deleted file mode 100644 index da67036d..00000000 --- a/src/lovr/types/rotation.h +++ /dev/null @@ -1,17 +0,0 @@ -#include "math/quat.h" -#include -#include -#include - -vec3 luax_newrotation(lua_State* L); -vec3 luax_checkrotation(lua_State* L, int i); - -extern const luaL_Reg lovrRotation[]; -int l_lovrRotationClone(lua_State* L); -int l_lovrRotationUnpack(lua_State* L); -int l_lovrRotationApply(lua_State* L); -int l_lovrRotationNormalize(lua_State* L); -int l_lovrRotationRotate(lua_State* L); -int l_lovrRotationMix(lua_State* L); -int l_lovrRotationMul(lua_State* L); -int l_lovrRotationLen(lua_State* L); diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index 24ae758b..e5af1107 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -1,20 +1,7 @@ #include "lovr/types/transform.h" -#include "lovr/types/rotation.h" -#include "lovr/types/vector.h" #include "math/vec3.h" #include "util.h" -mat4 luax_newtransform(lua_State* L) { - mat4 m = (mat4) lua_newuserdata(L, 16 * sizeof(float)); - luaL_getmetatable(L, "Transform"); - lua_setmetatable(L, -2); - return m; -} - -mat4 luax_checktransform(lua_State* L, int i) { - return luaL_checkudata(L, i, "Transform"); -} - void luax_readtransform(lua_State* L, int i, mat4 m) { if (lua_isnumber(L, i)) { float x = luaL_optnumber(L, i++, 0); @@ -29,131 +16,108 @@ void luax_readtransform(lua_State* L, int i, mat4 m) { mat4_translate(m, x, y, z); mat4_scale(m, s, s, s); mat4_rotate(m, angle, ax, ay, az); + } else if (lua_isnoneornil(L, i)) { + mat4_identity(m); } else { - mat4_init(m, luax_checktransform(L, i)); + Transform* transform = luax_checktype(L, i, Transform); + mat4_init(m, transform->matrix); } } const luaL_Reg lovrTransform[] = { { "clone", l_lovrTransformClone }, - { "apply", l_lovrTransformApply }, { "inverse", l_lovrTransformInverse }, + { "apply", l_lovrTransformApply }, { "origin", l_lovrTransformOrigin }, { "translate", l_lovrTransformTranslate }, { "rotate", l_lovrTransformRotate }, { "scale", l_lovrTransformScale }, - { "transform", l_lovrTransformTransform }, - { "__mul", l_lovrTransformMul }, + { "transform", l_lovrTransformTransformPoint }, { NULL, NULL } }; int l_lovrTransformClone(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - mat4_set(luax_newtransform(L), m); - return 1; -} - -int l_lovrTransformApply(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - - if (luax_istype(L, 2, "Transform")) { - mat4 n = luax_checktransform(L, 2); - mat4_multiply(m, n); - } else { - quat q = luax_checkrotation(L, 2); - mat4_rotateQuat(m, q); - } - - lua_pushvalue(L, 1); + Transform* transform = luax_checktype(L, 1, Transform); + luax_pushtype(L, Transform, lovrTransformCreate(transform->matrix)); return 1; } int l_lovrTransformInverse(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - mat4_invert(mat4_set(luax_newtransform(L), m)); + Transform* transform = luax_checktype(L, 1, Transform); + Transform* inverse = lovrTransformCreate(lovrTransformInverse(transform)); + luax_pushtype(L, Transform, inverse); + return 1; +} + +int l_lovrTransformApply(lua_State* L) { + Transform* transform = luax_checktype(L, 1, Transform); + Transform* other = luax_checktype(L, 2, Transform); + lovrTransformApply(transform, other); + lua_pushvalue(L, 1); return 1; } int l_lovrTransformOrigin(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - mat4_identity(m); + lovrTransformOrigin(luax_checktype(L, 1, Transform)); + lua_pushvalue(L, 1); return 1; } int l_lovrTransformTranslate(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - - if (lua_isnumber(L, 2)) { - float x = luaL_checknumber(L, 2); - float y = luaL_checknumber(L, 3); - float z = luaL_checknumber(L, 4); - mat4_translate(m, x, y, z); - } else { - vec3 v = luax_checkvector(L, 1); - mat4_translate(m, v[0], v[1], v[2]); - } - + Transform* transform = luax_checktype(L, 1, Transform); + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + lovrTransformTranslate(transform, x, y, z); lua_pushvalue(L, 1); return 1; } int l_lovrTransformRotate(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - - if (lua_isnumber(L, 2)) { - float angle = luaL_checknumber(L, 2); - float x = luaL_checknumber(L, 3); - float y = luaL_checknumber(L, 4); - float z = luaL_checknumber(L, 5); - mat4_rotate(m, angle, x, y, z); - } else if (luax_istype(L, 2, "Rotation")) { - quat q = luax_checkrotation(L, 2); - mat4_rotateQuat(m, q); - } - + Transform* transform = luax_checktype(L, 1, Transform); + float angle = luaL_checknumber(L, 2); + float x = luaL_checknumber(L, 3); + float y = luaL_checknumber(L, 4); + float z = luaL_checknumber(L, 5); + lovrTransformRotate(transform, angle, x, y, z); lua_pushvalue(L, 1); return 1; } int l_lovrTransformScale(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - - if (lua_isnumber(L, 2)) { - float x = luaL_checknumber(L, 2); - float y = lua_gettop(L) > 2 ? luaL_checknumber(L, 3) : x; - float z = lua_gettop(L) > 2 ? luaL_checknumber(L, 4) : x; - mat4_scale(m, x, y, z); - } else { - vec3 v = luax_checkvector(L, 1); - mat4_scale(m, v[0], v[1], v[2]); - } - + Transform* transform = luax_checktype(L, 1, Transform); + float x = luaL_checknumber(L, 2); + float y = lua_gettop(L) > 2 ? luaL_checknumber(L, 3) : x; + float z = lua_gettop(L) > 2 ? luaL_checknumber(L, 4) : x; + lovrTransformScale(transform, x, y, z); lua_pushvalue(L, 1); return 1; } -int l_lovrTransformTransform(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - if (lua_isnumber(L, 2)) { - float x = luaL_checknumber(L, 2); - float y = luaL_checknumber(L, 3); - float z = luaL_checknumber(L, 4); - float v[3]; - vec3_transform(vec3_set(v, x, y, z), m); - lua_pushnumber(L, v[0]); - lua_pushnumber(L, v[1]); - lua_pushnumber(L, v[2]); - return 3; - } else { - vec3 v = luax_checkvector(L, 2); - vec3_transform(v, m); - return 1; - } +int l_lovrTransformTransformPoint(lua_State* L) { + Transform* transform = luax_checktype(L, 1, Transform); + float point[3] = { + luaL_checknumber(L, 2), + luaL_checknumber(L, 3), + luaL_checknumber(L, 4) + }; + lovrTransformTransformPoint(transform, point); + lua_pushnumber(L, point[0]); + lua_pushnumber(L, point[1]); + lua_pushnumber(L, point[2]); + return 3; } -int l_lovrTransformMul(lua_State* L) { - mat4 m = luax_checktransform(L, 1); - mat4 n = luax_checktransform(L, 2); - mat4_multiply(mat4_set(luax_newtransform(L), m), n); - return 1; +int l_lovrTransformInverseTransformPoint(lua_State* L) { + Transform* transform = luax_checktype(L, 1, Transform); + float point[3] = { + luaL_checknumber(L, 2), + luaL_checknumber(L, 3), + luaL_checknumber(L, 4) + }; + lovrTransformInverseTransformPoint(transform, point); + lua_pushnumber(L, point[0]); + lua_pushnumber(L, point[1]); + lua_pushnumber(L, point[2]); + return 3; } diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h index 9c49de30..8da2160c 100644 --- a/src/lovr/types/transform.h +++ b/src/lovr/types/transform.h @@ -1,19 +1,18 @@ +#include "math/transform.h" #include "math/mat4.h" #include #include #include -mat4 luax_newtransform(lua_State* L); -mat4 luax_checktransform(lua_State* L, int i); void luax_readtransform(lua_State* L, int i, mat4 transform); extern const luaL_Reg lovrTransform[]; int l_lovrTransformClone(lua_State* L); -int l_lovrTransformApply(lua_State* L); int l_lovrTransformInverse(lua_State* L); +int l_lovrTransformApply(lua_State* L); int l_lovrTransformOrigin(lua_State* L); int l_lovrTransformTranslate(lua_State* L); int l_lovrTransformRotate(lua_State* L); int l_lovrTransformScale(lua_State* L); -int l_lovrTransformTransform(lua_State* L); -int l_lovrTransformMul(lua_State* L); +int l_lovrTransformTransformPoint(lua_State* L); +int l_lovrTransformInverseTransformPoint(lua_State* L); diff --git a/src/lovr/types/vector.c b/src/lovr/types/vector.c deleted file mode 100644 index 5bfcdd70..00000000 --- a/src/lovr/types/vector.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "lovr/types/vector.h" -#include "lovr/types/rotation.h" -#include "lovr/types/transform.h" -#include "util.h" - -vec3 luax_newvector(lua_State* L) { - vec3 v = (vec3) lua_newuserdata(L, 3 * sizeof(float)); - luaL_getmetatable(L, "Vector"); - lua_setmetatable(L, -2); - return v; -} - -vec3 luax_checkvector(lua_State* L, int i) { - return luaL_checkudata(L, i, "Vector"); -} - -const luaL_Reg lovrVector[] = { - { "clone", l_lovrVectorClone }, - { "unpack", l_lovrVectorUnpack }, - { "apply", l_lovrVectorApply }, - { "scale", l_lovrVectorScale }, - { "normalize", l_lovrVectorNormalize }, - { "distance", l_lovrVectorDistance }, - { "angle", l_lovrVectorAngle }, - { "dot", l_lovrVectorDot }, - { "cross", l_lovrVectorCross }, - { "lerp", l_lovrVectorLerp }, - { "__add", l_lovrVectorAdd }, - { "__sub", l_lovrVectorSub }, - { "__mul", l_lovrVectorMul }, - { "__div", l_lovrVectorDiv }, - { "__len", l_lovrVectorLen }, - { NULL, NULL } -}; - -int l_lovrVectorClone(lua_State* L) { - vec3 v = luax_checkvector(L, 1); - vec3_init(luax_newvector(L), v); - return 1; -} - -int l_lovrVectorUnpack(lua_State* L) { - vec3 v = luax_checkvector(L, 1); - lua_pushnumber(L, v[0]); - lua_pushnumber(L, v[1]); - lua_pushnumber(L, v[2]); - return 3; -} - -int l_lovrVectorApply(lua_State* L) { - vec3 v = luax_checkvector(L, 1); - - if (luax_istype(L, 2, "Rotation")) { - quat q = luax_checkrotation(L, 2); - vec3_rotate(v, q); - } else if (luax_istype(L, 2, "Transform")) { - mat4 m = luax_checktransform(L, 2); - vec3_transform(v, m); - } - - lua_pushvalue(L, 1); - return 1; -} - -int l_lovrVectorScale(lua_State* L) { - vec3 v = luax_checkvector(L, 1); - float s = luaL_checknumber(L, 2); - vec3_scale(v, s); - return 1; -} - -int l_lovrVectorNormalize(lua_State* L) { - vec3 v = luax_checkvector(L, 1); - vec3_normalize(v); - return 1; -} - -int l_lovrVectorDistance(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - lua_pushnumber(L, vec3_distance(u, v)); - return 1; -} - -int l_lovrVectorAngle(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - lua_pushnumber(L, vec3_angle(u, v)); - return 1; -} - -int l_lovrVectorDot(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - lua_pushnumber(L, vec3_dot(u, v)); - return 1; -} - -int l_lovrVectorCross(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - vec3_cross(vec3_init(luax_newvector(L), u), v); - return 1; -} - -int l_lovrVectorLerp(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - float t = luaL_checknumber(L, 3); - vec3_lerp(vec3_init(luax_newvector(L), u), v, t); - return 1; -} - -int l_lovrVectorAdd(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - vec3_add(vec3_init(luax_newvector(L), u), v); - return 1; -} - -int l_lovrVectorSub(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - vec3_sub(vec3_init(luax_newvector(L), u), v); - return 1; -} - -int l_lovrVectorMul(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - vec3_mul(vec3_init(luax_newvector(L), u), v); - return 1; -} - -int l_lovrVectorDiv(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - vec3 v = luax_checkvector(L, 2); - vec3_div(vec3_init(luax_newvector(L), u), v); - return 1; -} - -int l_lovrVectorLen(lua_State* L) { - vec3 u = luax_checkvector(L, 1); - lua_pushnumber(L, vec3_length(u)); - return 1; -} diff --git a/src/lovr/types/vector.h b/src/lovr/types/vector.h deleted file mode 100644 index 042af39a..00000000 --- a/src/lovr/types/vector.h +++ /dev/null @@ -1,24 +0,0 @@ -#include "math/vec3.h" -#include -#include -#include - -vec3 luax_newvector(lua_State* L); -vec3 luax_checkvector(lua_State* L, int i); - -extern const luaL_Reg lovrVector[]; -int l_lovrVectorClone(lua_State* L); -int l_lovrVectorUnpack(lua_State* L); -int l_lovrVectorApply(lua_State* L); -int l_lovrVectorScale(lua_State* L); -int l_lovrVectorNormalize(lua_State* L); -int l_lovrVectorDistance(lua_State* L); -int l_lovrVectorAngle(lua_State* L); -int l_lovrVectorDot(lua_State* L); -int l_lovrVectorCross(lua_State* L); -int l_lovrVectorLerp(lua_State* L); -int l_lovrVectorAdd(lua_State* L); -int l_lovrVectorSub(lua_State* L); -int l_lovrVectorMul(lua_State* L); -int l_lovrVectorDiv(lua_State* L); -int l_lovrVectorLen(lua_State* L); diff --git a/src/math/transform.c b/src/math/transform.c new file mode 100644 index 00000000..aff5b98d --- /dev/null +++ b/src/math/transform.c @@ -0,0 +1,60 @@ +#include "transform.h" +#include "math/mat4.h" +#include "math/vec3.h" + +Transform* lovrTransformCreate(mat4 transfrom) { + Transform* transform = lovrAlloc(sizeof(Transform), lovrTransformDestroy); + if (!transform) return NULL; + + transform->isDirty = 1; + + if (transfrom) { + mat4_set(transform->matrix, transfrom); + } else { + mat4_identity(transform->matrix); + } + + return transform; +} + +void lovrTransformDestroy(const Ref* ref) { + Transform* transform = containerof(ref, Transform); + free(transform); +} + +mat4 lovrTransformInverse(Transform* transform) { + if (transform->isDirty) { + transform->isDirty = 0; + mat4_invert(mat4_set(transform->inverse, transform->matrix)); + } + + return transform->inverse; +} + +void lovrTransformApply(Transform* transform, Transform* other) { + mat4_multiply(transform->matrix, other->matrix); +} + +void lovrTransformOrigin(Transform* transform) { + mat4_identity(transform->matrix); +} + +void lovrTransformTranslate(Transform* transform, float x, float y, float z) { + mat4_translate(transform->matrix, x, y, z); +} + +void lovrTransformRotate(Transform* transform, float angle, float x, float y, float z) { + mat4_rotate(transform->matrix, angle, x, y, z); +} + +void lovrTransformScale(Transform* transform, float x, float y, float z) { + mat4_scale(transform->matrix, x, y, z); +} + +void lovrTransformTransformPoint(Transform* transform, vec3 point) { + vec3_transform(point, transform->matrix); +} + +void lovrTransformInverseTransformPoint(Transform* transform, vec3 point) { + vec3_transform(point, lovrTransformInverse(transform)); +} diff --git a/src/math/transform.h b/src/math/transform.h new file mode 100644 index 00000000..9f921318 --- /dev/null +++ b/src/math/transform.h @@ -0,0 +1,23 @@ +#include "util.h" +#include "math/math.h" + +#ifndef LOVR_TRANSFORM_TYPES +#define LOVR_TRANSFORM_TYPES +typedef struct Transform { + Ref ref; + float matrix[16]; + float inverse[16]; + int isDirty; +} Transform; +#endif + +Transform* lovrTransformCreate(mat4 transfrom); +void lovrTransformDestroy(const Ref* ref); +void lovrTransformApply(Transform* transform, Transform* other); +mat4 lovrTransformInverse(Transform* transform); +void lovrTransformOrigin(Transform* transform); +void lovrTransformTranslate(Transform* transform, float x, float y, float z); +void lovrTransformRotate(Transform* transform, float angle, float x, float y, float z); +void lovrTransformScale(Transform* transform, float x, float y, float z); +void lovrTransformTransformPoint(Transform* transform, vec3 point); +void lovrTransformInverseTransformPoint(Transform* transform, vec3 point); diff --git a/src/util.c b/src/util.c index bde4d51e..4a8ac238 100644 --- a/src/util.c +++ b/src/util.c @@ -73,7 +73,7 @@ static int luax_pushobjectname(lua_State* L) { return 1; } -void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc) { +void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions) { // Push metatable luaL_newmetatable(L, name); @@ -84,10 +84,8 @@ void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions lua_setfield(L, -1, "__index"); // m.__gc = gc - if (gc) { - lua_pushcfunction(L, gc); - lua_setfield(L, -2, "__gc"); - } + lua_pushcfunction(L, luax_releasetype); + lua_setfield(L, -2, "__gc"); // m.name = name lua_pushstring(L, name); @@ -111,33 +109,22 @@ int luax_releasetype(lua_State* L) { return 0; } -int luax_istype(lua_State* L, int index, const char* name) { - if (lua_getmetatable(L, index)) { - luaL_getmetatable(L, name); - int equal = lua_equal(L, -1, -2); - lua_pop(L, 2); - return equal; - } - - return 0; -} - -void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* debug) { +void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* typeName) { const char* key = luaL_checkstring(L, index); void* value = map_get(map, key); if (!value) { - luaL_error(L, "Invalid %s '%s'", debug, key); + luaL_error(L, "Invalid %s '%s'", typeName, key); return NULL; } return value; } -void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* debug) { +void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* typeName) { const char* key = luaL_optstring(L, index, fallback); void* value = map_get(map, key); if (!value) { - luaL_error(L, "Invalid %s '%s'", debug, key); + luaL_error(L, "Invalid %s '%s'", typeName, key); return NULL; } diff --git a/src/util.h b/src/util.h index 376c8940..e0f93dcf 100644 --- a/src/util.h +++ b/src/util.h @@ -43,8 +43,7 @@ void lovrRetain(const Ref* ref); void lovrRelease(const Ref* ref); int luax_preloadmodule(lua_State* L, const char* key, lua_CFunction f); -void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc); +void luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions); int luax_releasetype(lua_State* L); -int luax_istype(lua_State* L, int index, const char* name); -void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* debug); -void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* debug); +void* luax_checkenum(lua_State* L, int index, map_int_t* map, const char* typeName); +void* luax_optenum(lua_State* L, int index, const char* fallback, map_int_t* map, const char* typeName); From 8a3d52b3c61af85037e1136d6635ddb2cb26908f Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 20 Jan 2017 19:55:54 -0800 Subject: [PATCH 14/17] Cleanup ugh; --- src/audio/audio.c | 4 +++- src/graphics/graphics.c | 6 ++++-- src/graphics/graphics.h | 2 +- src/graphics/model.c | 2 ++ src/graphics/model.h | 3 +-- src/graphics/shader.c | 1 + src/graphics/shader.h | 2 +- src/graphics/texture.c | 1 + src/headset/vive.c | 20 +++++++++----------- src/headset/vive.h | 3 +++ src/loaders/model.c | 1 + 11 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/audio/audio.c b/src/audio/audio.c index 786762bb..f388cd1b 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -76,7 +76,9 @@ void lovrAudioGetOrientation(float* angle, float* ax, float* ay, float* az) { } void lovrAudioGetPosition(float* x, float* y, float* z) { - alGetListener3f(AL_POSITION, x, y, z); + *x = state.position[0]; + *y = state.position[1]; + *z = state.position[2]; } float lovrAudioGetVolume() { diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 6e7de673..cc08ab48 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -1,6 +1,7 @@ #include "graphics/graphics.h" #include "loaders/texture.h" -#include "math/quat.h" +#include "math/mat4.h" +#include "math/vec3.h" #include "util.h" #include "glfw.h" #define _USE_MATH_DEFINES @@ -343,8 +344,9 @@ void lovrGraphicsScale(float x, float y, float z) { mat4_scale(state.transforms[state.transform], x, y, z); } -// M *= T * S * R void lovrGraphicsTransform(float tx, float ty, float tz, float sx, float sy, float sz, float angle, float ax, float ay, float az) { + + // M *= T * S * R float transform[16]; mat4_identity(transform); mat4_translate(transform, tx, ty, tz); diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index c13e5372..75332b79 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -3,7 +3,7 @@ #include "graphics/shader.h" #include "graphics/skybox.h" #include "graphics/texture.h" -#include "math/mat4.h" +#include "math/math.h" #ifndef LOVR_GRAPHICS_TYPES #define LOVR_GRAPHICS_TYPES diff --git a/src/graphics/model.c b/src/graphics/model.c index 73191496..53f775e7 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -1,5 +1,7 @@ #include "graphics/model.h" #include "graphics/graphics.h" +#include "math/mat4.h" +#include "math/vec3.h" #include static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec_float_t* vertices, vec_uint_t* indices) { diff --git a/src/graphics/model.h b/src/graphics/model.h index ebebfa8d..9ac59575 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -1,7 +1,6 @@ #include "graphics/buffer.h" #include "graphics/texture.h" -#include "math/mat4.h" -#include "math/vec3.h" +#include "math/math.h" #include "glfw.h" #include "util.h" #include "vendor/vec/vec.h" diff --git a/src/graphics/shader.c b/src/graphics/shader.c index a404f51e..39d37297 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -1,4 +1,5 @@ #include "graphics/shader.h" +#include "math/mat4.h" #include "util.h" #include diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 78513208..bb22cbea 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -1,5 +1,5 @@ #include "glfw.h" -#include "math/mat4.h" +#include "math/math.h" #include "vendor/map/map.h" #include "util.h" diff --git a/src/graphics/texture.c b/src/graphics/texture.c index dc1fbe41..f9228928 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -1,5 +1,6 @@ #include "graphics/texture.h" #include "graphics/graphics.h" +#include "math/mat4.h" #include "util.h" #include #include diff --git a/src/headset/vive.c b/src/headset/vive.c index 40030585..1f9b43ac 100644 --- a/src/headset/vive.c +++ b/src/headset/vive.c @@ -455,7 +455,7 @@ void* viveControllerGetModel(void* headset, Controller* controller, ControllerMo void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) { Vive* vive = (Vive*) headset; - float headMatrix[16], eyeMatrix[16], projectionMatrix[16]; + float head[16], transform[16], projection[16]; float (*matrix)[4]; lovrGraphicsPushCanvas(); @@ -464,28 +464,27 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) // Head transform matrix = vive->renderPoses[vive->headsetIndex].mDeviceToAbsoluteTracking.m; - mat4_invert(mat4_fromMat34(headMatrix, matrix)); + mat4_invert(mat4_fromMat34(head, matrix)); - for (int i = 0; i < 2; i++) { - EVREye eye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right; + for (EVREye eye = EYE_LEFT; eye <= EYE_RIGHT; eye++) { // Eye transform matrix = vive->system->GetEyeToHeadTransform(eye).m; - mat4_invert(mat4_fromMat34(eyeMatrix, matrix)); - mat4 transformMatrix = mat4_multiply(eyeMatrix, headMatrix); + mat4_invert(mat4_fromMat34(transform, matrix)); + mat4_multiply(transform, head); // Projection matrix = vive->system->GetProjectionMatrix(eye, vive->clipNear, vive->clipFar).m; - mat4_fromMat44(projectionMatrix, matrix); + mat4_fromMat44(projection, matrix); // Render lovrTextureBindFramebuffer(vive->texture); lovrGraphicsPush(); lovrGraphicsOrigin(); - lovrGraphicsMatrixTransform(transformMatrix); - lovrGraphicsSetProjectionRaw(projectionMatrix); + lovrGraphicsMatrixTransform(transform); + lovrGraphicsSetProjectionRaw(projection); lovrGraphicsClear(1, 1); - callback(i, userdata); + callback(eye - EYE_LEFT, userdata); lovrGraphicsPop(); lovrTextureResolveMSAA(vive->texture); @@ -499,6 +498,5 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) vive->isRendering = 0; lovrGraphicsPopCanvas(); - lovrGraphicsPlaneFullscreen(vive->texture); } diff --git a/src/headset/vive.h b/src/headset/vive.h index 1a484c44..e6d6cad9 100644 --- a/src/headset/vive.h +++ b/src/headset/vive.h @@ -6,6 +6,9 @@ #ifndef LOVR_VIVE_TYPES #define LOVR_VIVE_TYPES +#define EYE_LEFT EVREye_Eye_Left +#define EYE_RIGHT EVREye_Eye_Right + typedef struct { Headset headset; diff --git a/src/loaders/model.c b/src/loaders/model.c index c3974a87..c142d137 100644 --- a/src/loaders/model.c +++ b/src/loaders/model.c @@ -1,4 +1,5 @@ #include "loaders/model.h" +#include "math/mat4.h" #include #include #include From 039309a22272d8e79791b4d03fbbfba7a8bdc4ef Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 20 Jan 2017 20:11:18 -0800 Subject: [PATCH 15/17] Remove unused math code; --- src/lovr/graphics.c | 1 - src/math/mat4.c | 22 -------------- src/math/mat4.h | 1 - src/math/quat.c | 70 --------------------------------------------- src/math/quat.h | 4 --- src/math/vec3.c | 39 ------------------------- src/math/vec3.h | 6 ---- 7 files changed, 143 deletions(-) diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index 72eb418b..b4946578 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -9,7 +9,6 @@ #include "loaders/model.h" #include "loaders/texture.h" #include "filesystem/filesystem.h" -#include "math/mat4.h" #include "util.h" #include diff --git a/src/math/mat4.c b/src/math/mat4.c index 14ac3ec4..2b086f32 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -60,28 +60,6 @@ mat4 mat4_identity(mat4 m) { 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], diff --git a/src/math/mat4.h b/src/math/mat4.h index 02d232c1..a1deaaec 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -5,7 +5,6 @@ mat4 mat4_set(mat4 m, mat4 n); mat4 mat4_fromMat34(mat4 m, float (*n)[4]); mat4 mat4_fromMat44(mat4 m, float (*n)[4]); 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); diff --git a/src/math/quat.c b/src/math/quat.c index d0700a0e..cb57cea8 100644 --- a/src/math/quat.c +++ b/src/math/quat.c @@ -41,32 +41,13 @@ quat quat_fromMat4(quat q, mat4 m) { 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; -} - -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; } @@ -88,57 +69,6 @@ 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]; - vec3_cross(vec3_set(axis, 1, 0, 0), u); - if (vec3_length(axis) < .00001) { - vec3_cross(vec3_set(axis, 0, 1, 0), u); - } - vec3_normalize(axis); - quat_fromAngleAxis(q, M_PI, axis); - return q; - } - - vec3_cross(vec3_init(q, u), v); - q[3] = 1 + dot; - return quat_normalize(q); -} - void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z) { if (q[3] > 1 || q[3] < -1) { quat_normalize(q); diff --git a/src/math/quat.h b/src/math/quat.h index a6866b66..609dbfdc 100644 --- a/src/math/quat.h +++ b/src/math/quat.h @@ -3,11 +3,7 @@ quat quat_init(quat q, quat r); quat quat_set(quat q, 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_fromMat4(quat q, mat4 m); -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_getAngleAxis(quat q, float* angle, float* x, float* y, float* z); diff --git a/src/math/vec3.c b/src/math/vec3.c index 4125f67b..5d72496a 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -21,27 +21,6 @@ vec3 vec3_add(vec3 v, vec3 u) { return v; } -vec3 vec3_sub(vec3 v, vec3 u) { - v[0] -= u[0]; - v[1] -= u[1]; - v[2] -= u[2]; - return v; -} - -vec3 vec3_mul(vec3 v, vec3 u) { - v[0] *= u[0]; - v[1] *= u[1]; - v[2] *= u[2]; - return v; -} - -vec3 vec3_div(vec3 v, vec3 u) { - v[0] /= u[0]; - v[1] /= u[1]; - v[2] /= u[2]; - return v; -} - vec3 vec3_scale(vec3 v, float s) { v[0] *= s; v[1] *= s; @@ -58,17 +37,6 @@ float vec3_length(vec3 v) { return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); } -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]; - return sqrt(dx * dx + dy * dy + dz * dz); -} - -float vec3_angle(vec3 v, vec3 u) { - return acos(vec3_dot(v, u) / (vec3_length(v) * vec3_length(u))); -} - float vec3_dot(vec3 v, vec3 u) { return v[0] * u[0] + v[1] * u[1] + v[2] * u[2]; } @@ -102,10 +70,3 @@ vec3 vec3_transform(vec3 v, mat4 m) { v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14] ); } - -vec3 vec3_lerp(vec3 v, vec3 u, float t) { - v[0] += (u[0] - v[0]) * t; - v[1] += (u[1] - v[1]) * t; - v[2] += (u[2] - v[2]) * t; - return v; -} diff --git a/src/math/vec3.h b/src/math/vec3.h index e0d1c406..6cd101c9 100644 --- a/src/math/vec3.h +++ b/src/math/vec3.h @@ -3,16 +3,10 @@ vec3 vec3_init(vec3 v, vec3 u); vec3 vec3_set(vec3 v, float x, float y, float z); 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_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); From 1f4ecad44b487e6adfd3cf41a0f4d114bfdb8e14 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 20 Jan 2017 20:16:26 -0800 Subject: [PATCH 16/17] Shuffle things around; --- src/audio/audio.c | 4 ++-- src/graphics/model.c | 5 ++--- src/lovr/types/transform.c | 1 - src/math/mat4.c | 8 ++++++++ src/math/mat4.h | 1 + src/math/quat.c | 14 ++++++++++++++ src/math/quat.h | 1 + src/math/transform.c | 5 ++--- src/math/vec3.c | 23 ----------------------- src/math/vec3.h | 2 -- 10 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/audio/audio.c b/src/audio/audio.c index f388cd1b..f999be4b 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -121,8 +121,8 @@ void lovrAudioSetOrientation(float angle, float ax, float ay, float az) { float u[3] = { 0, 1, 0 }; float axis[3] = { ax, ay, az }; quat_fromAngleAxis(state.orientation, angle, axis); - vec3_rotate(f, state.orientation); - vec3_rotate(u, state.orientation); + quat_rotate(state.orientation, f); + quat_rotate(state.orientation, u); // Pass the rotated orientation vectors to OpenAL ALfloat orientation[6] = { f[0], f[1], f[2], u[0], u[1], u[2] }; diff --git a/src/graphics/model.c b/src/graphics/model.c index 53f775e7..3bfc0271 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -25,9 +25,8 @@ 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 vec[3]; - vec3_set(vec, vertex.x, vertex.y, vertex.z); - vec3_transform(vec, newTransform); + float vec[3] = { vertex.x, vertex.y, vertex.z }; + mat4_transform(newTransform, vec); vec_pusharr(vertices, vec, 3); if (modelData->hasNormals) { diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index e5af1107..fd730ed4 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -1,5 +1,4 @@ #include "lovr/types/transform.h" -#include "math/vec3.h" #include "util.h" void luax_readtransform(lua_State* L, int i, mat4 m) { diff --git a/src/math/mat4.c b/src/math/mat4.c index 2b086f32..bd2f7706 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -218,3 +218,11 @@ mat4 mat4_perspective(mat4 m, float near, float far, float fovy, float aspect) { m[15] = 0.0f; return m; } + +void mat4_transform(mat4 m, vec3 v) { + vec3_set(v, + v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12], + v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13], + v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14] + ); +} diff --git a/src/math/mat4.h b/src/math/mat4.h index a1deaaec..abbaf71d 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -13,3 +13,4 @@ mat4 mat4_rotateQuat(mat4 m, quat q); mat4 mat4_scale(mat4 m, float x, float y, float z); 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); +void mat4_transform(mat4 m, vec3 v); diff --git a/src/math/quat.c b/src/math/quat.c index cb57cea8..44c9b990 100644 --- a/src/math/quat.c +++ b/src/math/quat.c @@ -69,6 +69,20 @@ float quat_length(quat q) { return sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); } +void quat_rotate(quat q, vec3 v) { + float s = q[3]; + float u[3]; + float c[3]; + vec3_init(u, q); + vec3_cross(vec3_init(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); + vec3_add(v, vec3_add(u, c)); +} + void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z) { if (q[3] > 1 || q[3] < -1) { quat_normalize(q); diff --git a/src/math/quat.h b/src/math/quat.h index 609dbfdc..04a8afa4 100644 --- a/src/math/quat.h +++ b/src/math/quat.h @@ -6,4 +6,5 @@ quat quat_fromAngleAxis(quat q, float angle, vec3 axis); quat quat_fromMat4(quat q, mat4 m); quat quat_normalize(quat q); float quat_length(quat q); +void quat_rotate(quat q, vec3 v); void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z); diff --git a/src/math/transform.c b/src/math/transform.c index aff5b98d..f07da3b3 100644 --- a/src/math/transform.c +++ b/src/math/transform.c @@ -1,6 +1,5 @@ #include "transform.h" #include "math/mat4.h" -#include "math/vec3.h" Transform* lovrTransformCreate(mat4 transfrom) { Transform* transform = lovrAlloc(sizeof(Transform), lovrTransformDestroy); @@ -52,9 +51,9 @@ void lovrTransformScale(Transform* transform, float x, float y, float z) { } void lovrTransformTransformPoint(Transform* transform, vec3 point) { - vec3_transform(point, transform->matrix); + mat4_transform(transform->matrix, point); } void lovrTransformInverseTransformPoint(Transform* transform, vec3 point) { - vec3_transform(point, lovrTransformInverse(transform)); + mat4_transform(lovrTransformInverse(transform), point); } diff --git a/src/math/vec3.c b/src/math/vec3.c index 5d72496a..45665a29 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -1,5 +1,4 @@ #include "math/vec3.h" -#include "math/quat.h" #include #include @@ -48,25 +47,3 @@ vec3 vec3_cross(vec3 v, vec3 u) { v[0] * u[1] - v[1] * u[0] ); } - -vec3 vec3_rotate(vec3 v, quat q) { - float s = q[3]; - float u[3]; - float c[3]; - vec3_init(u, q); - vec3_cross(vec3_init(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) { - return vec3_set(v, - v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12], - v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13], - v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14] - ); -} diff --git a/src/math/vec3.h b/src/math/vec3.h index 6cd101c9..1a143d7f 100644 --- a/src/math/vec3.h +++ b/src/math/vec3.h @@ -8,5 +8,3 @@ vec3 vec3_normalize(vec3 v); float vec3_length(vec3 v); 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); From 9e0d8801b69860a5b0c8fac6ea370278dc84c0fe Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 20 Jan 2017 20:43:00 -0800 Subject: [PATCH 17/17] mat4_setTransform; --- src/graphics/graphics.c | 16 ++++------------ src/graphics/graphics.h | 1 - src/lovr/types/transform.c | 17 ++++++++++++----- src/lovr/types/transform.h | 1 + src/math/mat4.c | 7 +++++++ src/math/mat4.h | 1 + src/math/transform.c | 5 +++++ 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index cc08ab48..8152b058 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -344,17 +344,6 @@ void lovrGraphicsScale(float x, float y, float z) { mat4_scale(state.transforms[state.transform], x, y, z); } -void lovrGraphicsTransform(float tx, float ty, float tz, float sx, float sy, float sz, float angle, float ax, float ay, float az) { - - // M *= T * S * R - float transform[16]; - mat4_identity(transform); - mat4_translate(transform, tx, ty, tz); - mat4_scale(transform, sx, sy, sz); - mat4_rotate(transform, angle, ax, ay, az); - lovrGraphicsMatrixTransform(transform); -} - void lovrGraphicsMatrixTransform(mat4 transform) { mat4_multiply(state.transforms[state.transform], transform); } @@ -451,8 +440,11 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float // Angle between normal vector and the normal vector of the default geometry (dot product) float theta = acos(nz); + float transform[16]; + mat4_setTransform(transform, x, y, z, size, theta, cx, cy, cz); + lovrGraphicsPush(); - lovrGraphicsTransform(x, y, z, size, size, size, theta, cx, cy, cz); + lovrGraphicsMatrixTransform(transform); if (mode == DRAW_MODE_LINE) { float points[] = { diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 75332b79..b491ee26 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -124,7 +124,6 @@ void lovrGraphicsOrigin(); void lovrGraphicsTranslate(float x, float y, float z); void lovrGraphicsRotate(float angle, float ax, float ay, float az); 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); void lovrGraphicsMatrixTransform(mat4 transform); // Primitives diff --git a/src/lovr/types/transform.c b/src/lovr/types/transform.c index fd730ed4..a48dd127 100644 --- a/src/lovr/types/transform.c +++ b/src/lovr/types/transform.c @@ -11,10 +11,7 @@ void luax_readtransform(lua_State* L, int i, mat4 m) { float ax = luaL_optnumber(L, i++, 0); float ay = luaL_optnumber(L, i++, 1); float az = luaL_optnumber(L, i++, 0); - mat4_identity(m); - mat4_translate(m, x, y, z); - mat4_scale(m, s, s, s); - mat4_rotate(m, angle, ax, ay, az); + mat4_setTransform(m, x, y, z, s, angle, ax, ay, az); } else if (lua_isnoneornil(L, i)) { mat4_identity(m); } else { @@ -31,7 +28,9 @@ const luaL_Reg lovrTransform[] = { { "translate", l_lovrTransformTranslate }, { "rotate", l_lovrTransformRotate }, { "scale", l_lovrTransformScale }, - { "transform", l_lovrTransformTransformPoint }, + { "setTransformation", l_lovrTransformSetTransformation }, + { "transformPoint", l_lovrTransformTransformPoint }, + { "inverseTransformPoint", l_lovrTransformInverseTransformPoint }, { NULL, NULL } }; @@ -93,6 +92,14 @@ int l_lovrTransformScale(lua_State* L) { return 1; } +int l_lovrTransformSetTransformation(lua_State* L) { + Transform* transform = luax_checktype(L, 1, Transform); + lovrTransformOrigin(transform); // Dirty the Transform + luax_readtransform(L, 2, transform->matrix); + lua_pushvalue(L, 1); + return 1; +} + int l_lovrTransformTransformPoint(lua_State* L) { Transform* transform = luax_checktype(L, 1, Transform); float point[3] = { diff --git a/src/lovr/types/transform.h b/src/lovr/types/transform.h index 8da2160c..958c0821 100644 --- a/src/lovr/types/transform.h +++ b/src/lovr/types/transform.h @@ -14,5 +14,6 @@ int l_lovrTransformOrigin(lua_State* L); int l_lovrTransformTranslate(lua_State* L); int l_lovrTransformRotate(lua_State* L); int l_lovrTransformScale(lua_State* L); +int l_lovrTransformSetTransformation(lua_State* L); int l_lovrTransformTransformPoint(lua_State* L); int l_lovrTransformInverseTransformPoint(lua_State* L); diff --git a/src/math/mat4.c b/src/math/mat4.c index bd2f7706..50903fea 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -188,6 +188,13 @@ mat4 mat4_scale(mat4 m, float x, float y, float z) { return m; } +mat4 mat4_setTransform(mat4 m, float x, float y, float z, float s, float angle, float ax, float ay, float az) { + mat4_identity(m); + mat4_translate(m, x, y, z); + mat4_scale(m, s, s, s); + return mat4_rotate(m, angle, ax, ay, az); +} + 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; diff --git a/src/math/mat4.h b/src/math/mat4.h index abbaf71d..c8fc2817 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -11,6 +11,7 @@ mat4 mat4_translate(mat4 m, float x, float y, float z); mat4 mat4_rotate(mat4 m, float angle, float x, float y, float z); mat4 mat4_rotateQuat(mat4 m, quat q); mat4 mat4_scale(mat4 m, float x, float y, float z); +mat4 mat4_setTransform(mat4 m, float x, float y, float z, float s, float angle, float ax, float ay, float az); 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); void mat4_transform(mat4 m, vec3 v); diff --git a/src/math/transform.c b/src/math/transform.c index f07da3b3..2c7effb0 100644 --- a/src/math/transform.c +++ b/src/math/transform.c @@ -31,22 +31,27 @@ mat4 lovrTransformInverse(Transform* transform) { } void lovrTransformApply(Transform* transform, Transform* other) { + transform->isDirty = 1; mat4_multiply(transform->matrix, other->matrix); } void lovrTransformOrigin(Transform* transform) { + transform->isDirty = 1; mat4_identity(transform->matrix); } void lovrTransformTranslate(Transform* transform, float x, float y, float z) { + transform->isDirty = 1; mat4_translate(transform->matrix, x, y, z); } void lovrTransformRotate(Transform* transform, float angle, float x, float y, float z) { + transform->isDirty = 1; mat4_rotate(transform->matrix, angle, x, y, z); } void lovrTransformScale(Transform* transform, float x, float y, float z) { + transform->isDirty = 1; mat4_scale(transform->matrix, x, y, z); }