From 112e6f8f00612ad2c99b907d071f9dbcce10f5f7 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 23 Jul 2017 22:37:52 -0700 Subject: [PATCH] lovr.math.lookAt; Returns the angle/axis rotation for looking at a point. --- src/api/math.c | 16 ++++++++++++ src/math/mat4.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ src/math/mat4.h | 1 + src/math/quat.c | 9 ------- 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/api/math.c b/src/api/math.c index e37fbc20..e07f2ada 100644 --- a/src/api/math.c +++ b/src/api/math.c @@ -18,8 +18,24 @@ int l_lovrMathNewTransform(lua_State* L) { return 1; } +int l_lovrMathLookAt(lua_State* L) { + float from[3] = { luaL_checknumber(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3) }; + float to[3] = { luaL_checknumber(L, 4), luaL_checknumber(L, 5), luaL_checknumber(L, 6) }; + float up[3] = { luaL_optnumber(L, 7, 0), luaL_optnumber(L, 8, 1), luaL_optnumber(L, 9, 0) }; + float m[16], q[4], angle, ax, ay, az; + mat4_lookAt(m, from, to, up); + quat_fromMat4(q, m); + quat_getAngleAxis(q, &angle, &ax, &ay, &az); + lua_pushnumber(L, -angle); + lua_pushnumber(L, ax); + lua_pushnumber(L, ay); + lua_pushnumber(L, az); + return 4; +} + const luaL_Reg lovrMath[] = { { "newTransform", l_lovrMathNewTransform }, + { "lookAt", l_lovrMathLookAt }, { NULL, NULL } }; diff --git a/src/math/mat4.c b/src/math/mat4.c index c5ec4633..5cef4c90 100644 --- a/src/math/mat4.c +++ b/src/math/mat4.c @@ -246,6 +246,74 @@ mat4 mat4_perspective(mat4 m, float near, float far, float fovy, float aspect) { return m; } +// Modified from gl-matrix.c +mat4 mat4_lookAt(mat4 m, vec3 from, vec3 to, vec3 up) { + float x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + + if (from[0] == to[0] && from[1] == to[1] && from[2] == to[2]) { + return mat4_identity(m); + } + + z0 = from[0] - to[0]; + z1 = from[1] - to[1]; + z2 = from[2] - to[2]; + + len = 1 / sqrt(z0 * z0 + z1 * z1 + z2 * z2); + z0 *= len; + z1 *= len; + z2 *= len; + + x0 = up[1] * z2 - up[2] * z1; + x1 = up[2] * z0 - up[0] * z2; + x2 = up[0] * z1 - up[1] * z0; + len = sqrt(x0 * x0 + x1 * x1 + x2 * x2); + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + + len = sqrt(y0 * y0 + y1 * y1 + y2 * y2); + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + m[0] = x0; + m[1] = y0; + m[2] = z0; + m[3] = 0; + m[4] = x1; + m[5] = y1; + m[6] = z1; + m[7] = 0; + m[8] = x2; + m[9] = y2; + m[10] = z2; + m[11] = 0; + m[12] = -(x0 * from[0] + x1 * from[1] + x2 * from[2]); + m[13] = -(y0 * from[0] + y1 * from[1] + y2 * from[2]); + m[14] = -(z0 * from[0] + z1 * from[1] + z2 * from[2]); + m[15] = 1; + + 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], diff --git a/src/math/mat4.h b/src/math/mat4.h index 22f1d579..f04b75eb 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -17,5 +17,6 @@ mat4 mat4_scale(mat4 m, float x, float y, float z); mat4 mat4_setTransform(mat4 m, float x, float y, float z, float sx, float sy, float sz, 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); +mat4 mat4_lookAt(mat4 m, vec3 from, vec3 to, vec3 up); void mat4_transform(mat4 m, vec3 v); void mat4_transformDirection(mat4 m, vec3 v); diff --git a/src/math/quat.c b/src/math/quat.c index 37fe01ac..85a58f3b 100644 --- a/src/math/quat.c +++ b/src/math/quat.c @@ -26,15 +26,6 @@ quat quat_fromAngleAxis(quat q, float angle, vec3 axis) { return q; } -quat quat_fromDirection(quat q, vec3 forward, vec3 up) { - vec3 qq = (vec3) q; - vec3_init(qq, forward); - vec3_normalize(qq); - q[3] = 1 + vec3_dot(qq, up); - vec3_cross(qq, up); - return q; -} - 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;