You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
854 lines
17 KiB
C
854 lines
17 KiB
C
#include "math3d-left.h"
|
|
#include <lua.h>
|
|
#include <lauxlib.h>
|
|
|
|
// https://github.com/huanzai/math3d
|
|
|
|
static void *
|
|
check_userdata(lua_State *L, int idx)
|
|
{
|
|
void *ret = lua_touserdata(L, idx);
|
|
luaL_argcheck(L, ret != NULL, idx, "Userdata should not be NULL");
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
lnewvec3(lua_State *L)
|
|
{
|
|
struct vector3 tmp;
|
|
if (lua_isuserdata(L, 1))
|
|
{
|
|
struct vector3 *copy = check_userdata(L, 1);
|
|
tmp = *copy;
|
|
}
|
|
else
|
|
{
|
|
tmp.x = luaL_optnumber(L, 1, 0);
|
|
tmp.y = luaL_optnumber(L, 2, 0);
|
|
tmp.z = luaL_optnumber(L, 3, 0);
|
|
}
|
|
struct vector3 *vec3 = lua_newuserdata(L, sizeof(*vec3));
|
|
*vec3 = tmp;
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_pack(lua_State *L)
|
|
{
|
|
struct vector3 *vec3 = check_userdata(L, 1);
|
|
vec3->x = luaL_optnumber(L, 2, 0);
|
|
vec3->y = luaL_optnumber(L, 3, 0);
|
|
vec3->z = luaL_optnumber(L, 4, 0);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_unpack(lua_State *L)
|
|
{
|
|
struct vector3 *vec3 = check_userdata(L, 1);
|
|
lua_pushnumber(L, vec3->x);
|
|
lua_pushnumber(L, vec3->y);
|
|
lua_pushnumber(L, vec3->z);
|
|
return 3;
|
|
}
|
|
|
|
static int
|
|
lvec3_dot(lua_State *L)
|
|
{
|
|
struct vector3 *a = check_userdata(L, 1);
|
|
struct vector3 *b = check_userdata(L, 2);
|
|
float v = vector3_dot(a, b);
|
|
lua_pushnumber(L, v);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_cross(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *a = check_userdata(L, 2);
|
|
struct vector3 *b = check_userdata(L, 3);
|
|
vector3_cross(v, a, b);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_vector(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *a = check_userdata(L, 2);
|
|
struct vector3 *b = check_userdata(L, 3);
|
|
vector3_vector(v, a, b);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_length(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
float len = vector3_length(v);
|
|
lua_pushnumber(L, len);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_normalize(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
vector3_normalize(v);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_copy(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *from = check_userdata(L, 2);
|
|
*v = *from;
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_tostring(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
lua_pushfstring(L, "[%f, %f, %f]", v->x, v->y, v->z);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_rotation(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *from = check_userdata(L, 2);
|
|
vector3_to_rotation(v, from);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_lerp(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *a = check_userdata(L, 2);
|
|
struct vector3 *b = check_userdata(L, 3);
|
|
float f = luaL_checknumber(L, 4);
|
|
vector3_lerp(v, a, b, f);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
create_meta(lua_State *L, luaL_Reg *l, const char *name, lua_CFunction tostring)
|
|
{
|
|
int n = 0;
|
|
while (l[n].name)
|
|
++n;
|
|
lua_newtable(L);
|
|
lua_createtable(L, 0, n);
|
|
int i;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
lua_pushcfunction(L, l[i].func);
|
|
lua_setfield(L, -2, l[i].name);
|
|
}
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushstring(L, name);
|
|
lua_setfield(L, -2, "__metatable");
|
|
lua_pushcfunction(L, tostring);
|
|
lua_setfield(L, -2, "__tostring");
|
|
}
|
|
|
|
static int
|
|
lvec3_transmat(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
matrix44_trans(m, v->x, v->y, v->z);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_scalemat(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
matrix44_scale(m, v->x, v->y, v->z);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_rotmat(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
matrix44_rot(m, v->x, v->y, v->z);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_rotaxis(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
float angle = luaL_checknumber(L, 3);
|
|
matrix44_rot_axis(m, v, angle);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_mul(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
vector3_mul(v, m);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_mul33(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
vector3_mul33(v, m);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_distAABB(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct vector3 *mins = check_userdata(L, 2);
|
|
struct vector3 *maxs = check_userdata(L, 3);
|
|
float d = vector3_distAABB(v, mins, maxs);
|
|
lua_pushnumber(L, d);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lvec3_plane(lua_State *L)
|
|
{
|
|
struct vector3 *v = check_userdata(L, 1);
|
|
struct plane *p = check_userdata(L, 2);
|
|
float d = luaL_optnumber(L, 3, 0);
|
|
plane_init(p, v, d);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
vector3(lua_State *L)
|
|
{
|
|
luaL_Reg l[] = {
|
|
{"pack", lvec3_pack},
|
|
{"unpack", lvec3_unpack},
|
|
{"dot", lvec3_dot},
|
|
{"cross", lvec3_cross},
|
|
{"vector", lvec3_vector},
|
|
{"length", lvec3_length},
|
|
{"normalize", lvec3_normalize},
|
|
{"copy", lvec3_copy},
|
|
{"rotation", lvec3_rotation},
|
|
{"lerp", lvec3_lerp},
|
|
{"transmat", lvec3_transmat},
|
|
{"scalemat", lvec3_scalemat},
|
|
{"rotmat", lvec3_rotmat},
|
|
{"rotaxis", lvec3_rotaxis},
|
|
{"mul", lvec3_mul},
|
|
{"mul33", lvec3_mul33},
|
|
{"plane", lvec3_plane},
|
|
{"distAABB", lvec3_distAABB},
|
|
{NULL, NULL},
|
|
};
|
|
create_meta(L, l, "vector3", lvec3_tostring);
|
|
lua_pushcclosure(L, lnewvec3, 1);
|
|
}
|
|
|
|
static int
|
|
lnewquat(lua_State *L)
|
|
{
|
|
if (lua_isuserdata(L, 1))
|
|
{
|
|
struct quaternion *tmp = check_userdata(L, 1);
|
|
struct quaternion *q = lua_newuserdata(L, sizeof(*q));
|
|
*q = *tmp;
|
|
}
|
|
else if lua_isnoneornil (L, 1)
|
|
{
|
|
struct quaternion *q = lua_newuserdata(L, sizeof(*q));
|
|
q->x = 0;
|
|
q->y = 0;
|
|
q->z = 0;
|
|
q->w = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
float x = luaL_checknumber(L, 1);
|
|
float y = luaL_checknumber(L, 2);
|
|
float z = luaL_checknumber(L, 3);
|
|
struct quaternion *q = lua_newuserdata(L, sizeof(*q));
|
|
quaternion_init(q, x, y, z);
|
|
}
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
lua_setmetatable(L, -2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_tostring(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
lua_pushfstring(L, "[%f, %f, %f, %f]", q->x, q->y, q->z, q->w);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_mul(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
struct quaternion *a = check_userdata(L, 2);
|
|
struct quaternion *b = check_userdata(L, 3);
|
|
quaternion_mul(q, a, b);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_copy(lua_State *L)
|
|
{
|
|
struct quaternion *a = check_userdata(L, 1);
|
|
struct quaternion *b = check_userdata(L, 2);
|
|
*a = *b;
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_slerp(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
struct quaternion *a = check_userdata(L, 2);
|
|
struct quaternion *b = check_userdata(L, 3);
|
|
float t = luaL_checknumber(L, 4);
|
|
quaternion_slerp(q, a, b, t);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_nslerp(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
struct quaternion *a = check_userdata(L, 2);
|
|
struct quaternion *b = check_userdata(L, 3);
|
|
float t = luaL_checknumber(L, 4);
|
|
quaternion_nslerp(q, a, b, t);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_inverted(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
quaternion_inverted(q);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_matrix(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
union matrix44 *mat = check_userdata(L, 2);
|
|
matrix44_from_quaternion(mat, q);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_pack(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
q->x = luaL_checknumber(L, 2);
|
|
q->y = luaL_checknumber(L, 3);
|
|
q->z = luaL_checknumber(L, 4);
|
|
q->w = luaL_checknumber(L, 5);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lquat_unpack(lua_State *L)
|
|
{
|
|
struct quaternion *q = check_userdata(L, 1);
|
|
lua_pushnumber(L, q->x);
|
|
lua_pushnumber(L, q->y);
|
|
lua_pushnumber(L, q->z);
|
|
lua_pushnumber(L, q->w);
|
|
return 4;
|
|
}
|
|
|
|
static void
|
|
quaternion(lua_State *L)
|
|
{
|
|
luaL_Reg l[] = {
|
|
{"mul", lquat_mul},
|
|
{"copy", lquat_copy},
|
|
{"pack", lquat_pack},
|
|
{"unpack", lquat_unpack},
|
|
{"slerp", lquat_slerp},
|
|
{"nslerp", lquat_nslerp},
|
|
{"inverted", lquat_inverted},
|
|
{"matrix", lquat_matrix},
|
|
{NULL, NULL},
|
|
};
|
|
create_meta(L, l, "quateraion", lquat_tostring);
|
|
lua_pushcclosure(L, lnewquat, 1);
|
|
}
|
|
|
|
static int
|
|
lnewmat(lua_State *L)
|
|
{
|
|
if (lua_isuserdata(L, 1))
|
|
{
|
|
union matrix44 *tmp = check_userdata(L, 1);
|
|
union matrix44 *mat = lua_newuserdata(L, sizeof(*mat));
|
|
*mat = *tmp;
|
|
}
|
|
else if lua_isnoneornil (L, 1)
|
|
{
|
|
union matrix44 *mat = lua_newuserdata(L, sizeof(*mat));
|
|
matrix44_identity(mat);
|
|
}
|
|
else
|
|
{
|
|
float x = luaL_checknumber(L, 1);
|
|
float y = luaL_checknumber(L, 2);
|
|
float z = luaL_checknumber(L, 3);
|
|
union matrix44 *mat = lua_newuserdata(L, sizeof(*mat));
|
|
matrix44_rot(mat, x, y, z);
|
|
}
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
lua_setmetatable(L, -2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_tostring(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
lua_pushfstring(L, "[(%f, %f, %f, %f) (%f, %f, %f, %f) (%f, %f, %f, %f) (%f, %f, %f, %f)]",
|
|
m->c[0][0], m->c[0][1], m->c[0][2], m->c[0][3],
|
|
m->c[1][0], m->c[1][1], m->c[1][2], m->c[1][3],
|
|
m->c[2][0], m->c[2][1], m->c[2][2], m->c[2][3],
|
|
m->c[3][0], m->c[3][1], m->c[3][2], m->c[3][3]);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_pack(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
int i;
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
m->x[i] = luaL_checknumber(L, 2 + i);
|
|
}
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_unpack(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
int i;
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
lua_pushnumber(L, m->x[i]);
|
|
}
|
|
return 16;
|
|
}
|
|
|
|
static int
|
|
lmat_copy(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
union matrix44 *from = check_userdata(L, 2);
|
|
*m = *from;
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_identity(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
matrix44_identity(m);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_perspective(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
float l = luaL_checknumber(L, 2);
|
|
float r = luaL_checknumber(L, 3);
|
|
float b = luaL_checknumber(L, 4);
|
|
float t = luaL_checknumber(L, 5);
|
|
float n = luaL_checknumber(L, 6);
|
|
float f = luaL_checknumber(L, 7);
|
|
matrix44_perspective(m, l, r, b, t, n, f);
|
|
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_ortho(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
float l = luaL_checknumber(L, 2);
|
|
float r = luaL_checknumber(L, 3);
|
|
float b = luaL_checknumber(L, 4);
|
|
float t = luaL_checknumber(L, 5);
|
|
float n = luaL_checknumber(L, 6);
|
|
float f = luaL_checknumber(L, 7);
|
|
matrix44_ortho(m, l, r, b, t, n, f);
|
|
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_mul(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
union matrix44 *a = check_userdata(L, 2);
|
|
union matrix44 *b = check_userdata(L, 3);
|
|
if (b == NULL)
|
|
{
|
|
b = a;
|
|
a = m;
|
|
}
|
|
matrix44_mul(m, a, b);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_fastmul43(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
union matrix44 *a = check_userdata(L, 2);
|
|
union matrix44 *b = check_userdata(L, 3);
|
|
matrix44_fastmul43(m, a, b);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_transposed(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
matrix44_transposed(m);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_determinant(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
float v = matrix44_determinant(m);
|
|
lua_pushnumber(L, v);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_inverted(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
union matrix44 *from = check_userdata(L, 2);
|
|
matrix44_inverted(m, from);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_trans(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
struct vector3 *v = check_userdata(L, 2);
|
|
matrix44_gettrans(m, v);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_scale(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
struct vector3 *v = check_userdata(L, 2);
|
|
matrix44_getscale(m, v);
|
|
lua_settop(L, 2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lmat_decompose(lua_State *L)
|
|
{
|
|
union matrix44 *m = check_userdata(L, 1);
|
|
struct vector3 *trans = check_userdata(L, 2);
|
|
struct vector3 *rot = check_userdata(L, 3);
|
|
struct vector3 *scale = check_userdata(L, 4);
|
|
matrix44_decompose(m, trans, rot, scale);
|
|
lua_settop(L, 4);
|
|
return 3;
|
|
}
|
|
|
|
static void
|
|
matrix(lua_State *L)
|
|
{
|
|
luaL_Reg l[] = {
|
|
{"pack", lmat_pack},
|
|
{"unpack", lmat_unpack},
|
|
{"copy", lmat_copy},
|
|
{"identity", lmat_identity},
|
|
{"perspective", lmat_perspective},
|
|
{"ortho", lmat_ortho},
|
|
{"mul", lmat_mul},
|
|
{"fastmul43", lmat_fastmul43},
|
|
{"transposed", lmat_transposed},
|
|
{"determinant", lmat_determinant},
|
|
{"inverted", lmat_inverted},
|
|
{"trans", lmat_trans},
|
|
{"scale", lmat_scale},
|
|
{"decompose", lmat_decompose},
|
|
{NULL, NULL},
|
|
};
|
|
create_meta(L, l, "matrix", lmat_tostring);
|
|
lua_pushcclosure(L, lnewmat, 1);
|
|
}
|
|
|
|
static int
|
|
lnewvec4(lua_State *L)
|
|
{
|
|
struct vector4 tmp;
|
|
if (lua_isuserdata(L, 1))
|
|
{
|
|
struct vector4 *copy = check_userdata(L, 1);
|
|
tmp = *copy;
|
|
}
|
|
else
|
|
{
|
|
tmp.x = luaL_optnumber(L, 1, 0);
|
|
tmp.y = luaL_optnumber(L, 2, 0);
|
|
tmp.z = luaL_optnumber(L, 3, 0);
|
|
tmp.z = luaL_optnumber(L, 4, 1.0);
|
|
}
|
|
struct vector4 *vec4 = lua_newuserdata(L, sizeof(*vec4));
|
|
*vec4 = tmp;
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
#define lvec4_tostring lquat_tostring
|
|
#define lvec4_copy lquat_copy
|
|
#define lvec4_pack lquat_pack
|
|
#define lvec4_unpack lquat_unpack
|
|
|
|
static int
|
|
lvec4_mul(lua_State *L)
|
|
{
|
|
struct vector4 *v = check_userdata(L, 1);
|
|
union matrix44 *m = check_userdata(L, 2);
|
|
vector4_mul(v, m);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
vector4(lua_State *L)
|
|
{
|
|
luaL_Reg l[] = {
|
|
{"copy", lvec4_copy},
|
|
{"pack", lvec4_pack},
|
|
{"unpack", lvec4_unpack},
|
|
{"mul", lvec4_mul},
|
|
{NULL, NULL},
|
|
};
|
|
create_meta(L, l, "vector4", lvec4_tostring);
|
|
lua_pushcclosure(L, lnewvec4, 1);
|
|
}
|
|
|
|
static int
|
|
lnewplane(lua_State *L)
|
|
{
|
|
int top = lua_gettop(L);
|
|
if (top == 0)
|
|
{
|
|
struct plane *p = lua_newuserdata(L, sizeof(*p));
|
|
p->normal.x = 0;
|
|
p->normal.y = 0;
|
|
p->normal.z = 1;
|
|
p->dist = 0; // XY plane
|
|
}
|
|
else if (top == 1)
|
|
{
|
|
struct plane *copy = check_userdata(L, 1);
|
|
struct plane *p = lua_newuserdata(L, sizeof(*p));
|
|
*p = *copy;
|
|
}
|
|
else if (top == 3)
|
|
{
|
|
struct vector3 *a = check_userdata(L, 1);
|
|
struct vector3 *b = check_userdata(L, 2);
|
|
struct vector3 *c = check_userdata(L, 3);
|
|
struct plane *p = lua_newuserdata(L, sizeof(*p));
|
|
plane_init_dot3(p, a, b, c);
|
|
}
|
|
else
|
|
{
|
|
return luaL_error(L, "Invalid new plane");
|
|
}
|
|
lua_pushvalue(L, lua_upvalueindex(1));
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lplane_tostring(lua_State *L)
|
|
{
|
|
struct plane *p = check_userdata(L, 1);
|
|
lua_pushfstring(L, "[%f, %f, %f : %f]", p->normal.x, p->normal.x, p->normal.z, p->dist);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lplane_dist(lua_State *L)
|
|
{
|
|
struct plane *p = check_userdata(L, 1);
|
|
struct vector3 *v = check_userdata(L, 2);
|
|
float d = plane_dist(p, v);
|
|
lua_pushnumber(L, d);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lplane_copy(lua_State *L)
|
|
{
|
|
struct plane *p = check_userdata(L, 1);
|
|
struct plane *from = check_userdata(L, 2);
|
|
*p = *from;
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lplane_dot3(lua_State *L)
|
|
{
|
|
struct plane *p = check_userdata(L, 1);
|
|
struct vector3 *a = check_userdata(L, 2);
|
|
struct vector3 *b = check_userdata(L, 3);
|
|
struct vector3 *c = check_userdata(L, 4);
|
|
plane_init_dot3(p, a, b, c);
|
|
lua_settop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
plane(lua_State *L)
|
|
{
|
|
luaL_Reg l[] = {
|
|
{"copy", lplane_copy},
|
|
{"dist", lplane_dist},
|
|
{"dot3", lplane_dot3},
|
|
{NULL, NULL},
|
|
};
|
|
create_meta(L, l, "plane", lplane_tostring);
|
|
lua_pushcclosure(L, lnewplane, 1);
|
|
}
|
|
|
|
static int
|
|
lraytriangle(lua_State *L)
|
|
{
|
|
int top = lua_gettop(L);
|
|
if (top != 6)
|
|
{
|
|
return luaL_error(L, "intersection.raytriangle(rayOrig,rayDir,p0,p1,p2,ret)");
|
|
}
|
|
struct vector3 *ro = check_userdata(L, 1);
|
|
struct vector3 *rd = check_userdata(L, 2);
|
|
struct vector3 *p0 = check_userdata(L, 3);
|
|
struct vector3 *p1 = check_userdata(L, 4);
|
|
struct vector3 *p2 = check_userdata(L, 5);
|
|
struct vector3 *inst = check_userdata(L, 6);
|
|
if (intersection_raytriangle(ro, rd, p0, p1, p2, inst) == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
lrayAABB(lua_State *L)
|
|
{
|
|
int top = lua_gettop(L);
|
|
if (top != 4)
|
|
{
|
|
return luaL_error(L, "intersection.rayAABB(rayOrig,rayDir,mins,maxs)");
|
|
}
|
|
struct vector3 *ro = check_userdata(L, 1);
|
|
struct vector3 *rd = check_userdata(L, 2);
|
|
struct vector3 *mins = check_userdata(L, 3);
|
|
struct vector3 *maxs = check_userdata(L, 4);
|
|
int r = intersection_rayAABB(ro, rd, mins, maxs);
|
|
lua_pushboolean(L, r);
|
|
return 1;
|
|
}
|
|
|
|
int luaopen_math3d(lua_State *L)
|
|
{
|
|
luaL_checkversion(L);
|
|
lua_newtable(L);
|
|
vector3(L);
|
|
lua_setfield(L, -2, "vector3");
|
|
quaternion(L);
|
|
lua_setfield(L, -2, "quaternion");
|
|
matrix(L);
|
|
lua_setfield(L, -2, "matrix");
|
|
vector4(L);
|
|
lua_setfield(L, -2, "vector4");
|
|
plane(L);
|
|
lua_setfield(L, -2, "plane");
|
|
luaL_Reg l[] = {
|
|
{"raytriangle", lraytriangle},
|
|
{"rayAABB", lrayAABB},
|
|
{NULL, NULL},
|
|
};
|
|
luaL_newlib(L, l);
|
|
lua_setfield(L, -2, "intersection");
|
|
return 1;
|
|
}
|