mirror of https://github.com/bjornbytes/lovr.git
Rough math module;
This commit is contained in:
parent
c7399c8078
commit
a3ccb16913
|
@ -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) "
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
Loading…
Reference in New Issue