lovr.math.lookAt;

Returns the angle/axis rotation for looking at a point.
This commit is contained in:
bjorn 2017-07-23 22:37:52 -07:00
parent 6a8e22f5be
commit 112e6f8f00
4 changed files with 85 additions and 9 deletions

View File

@ -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 }
};

View File

@ -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],

View File

@ -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);

View File

@ -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;