Rough math module;

This commit is contained in:
bjorn 2017-01-19 01:56:17 -08:00
parent c7399c8078
commit a3ccb16913
9 changed files with 480 additions and 1 deletions

View File

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

80
src/lovr/math.c Normal file
View File

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

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

@ -0,0 +1,9 @@
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);

82
src/lovr/types/rotation.c Normal file
View File

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

16
src/lovr/types/rotation.h Normal file
View File

@ -0,0 +1,16 @@
#include "math/quat.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);

119
src/lovr/types/transform.c Normal file
View File

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

View File

@ -0,0 +1,19 @@
#include "math/mat4.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);

128
src/lovr/types/vector.c Normal file
View File

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

23
src/lovr/types/vector.h Normal file
View File

@ -0,0 +1,23 @@
#include "math/vec3.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);