From cc426d0453edb7f457f2877525ec19bc96766205 Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 16 Oct 2023 19:42:38 -0700 Subject: [PATCH 1/6] Experimental vector changes; - Removes temporary vectors. All vectors are permanent now. The temporary constructors still exist for compatibility, but they create permanent vectors. Also removes lovr.math.drain. - All vector methods (except :set) return new vectors instead of mutating. This makes some methods vestigial/weird, like :add/sub/mul/div and matrix "initializers" like :identity/:fov/:perspective/:ortho/:lookAt/:target/:reflect. --- etc/boot.lua | 3 - src/api/api.c | 8 +- src/api/api.h | 17 +- src/api/l_event.c | 15 +- src/api/l_graphics_buffer.c | 2 +- src/api/l_graphics_model.c | 6 +- src/api/l_graphics_pass.c | 8 +- src/api/l_math.c | 155 ++++------------- src/api/l_math_curve.c | 1 + src/api/l_math_randomGenerator.c | 1 + src/api/l_math_vectors.c | 283 ++++++++++++++++--------------- src/modules/math/math.c | 64 ------- src/modules/math/math.h | 30 ---- 13 files changed, 215 insertions(+), 378 deletions(-) diff --git a/etc/boot.lua b/etc/boot.lua index 72ff56e4..8ca9dcc4 100644 --- a/etc/boot.lua +++ b/etc/boot.lua @@ -174,7 +174,6 @@ function lovr.run() lovr.graphics.present() end if lovr.headset then lovr.headset.submit() end - if lovr.math then lovr.math.drain() end end end @@ -270,8 +269,6 @@ function lovr.errhand(message) lovr.graphics.present() end end - - lovr.math.drain() end end diff --git a/src/api/api.c b/src/api/api.c index a6d0067c..f593909f 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -494,13 +494,13 @@ void luax_optcolor(lua_State* L, int index, float color[4]) { break; case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: { - VectorType type; - float* v = luax_tovector(L, index, &type); - if (type == V_VEC3) { + int vectorType; + float* v = luax_tovector(L, index, &vectorType); + if (vectorType == V_VEC3) { memcpy(color, v, 3 * sizeof(float)); color[3] = 1.f; break; - } else if (type == V_VEC4) { + } else if (vectorType == V_VEC4) { memcpy(color, v, 4 * sizeof(float)); break; } diff --git a/src/api/api.h b/src/api/api.h index 327d7aba..3ad120ab 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -176,10 +176,19 @@ struct ColoredString* luax_checkcoloredstrings(lua_State* L, int index, uint32_t #endif #ifndef LOVR_DISABLE_MATH -#include "math/math.h" // TODO -float* luax_tovector(lua_State* L, int index, VectorType* type); -float* luax_checkvector(lua_State* L, int index, VectorType type, const char* expected); -float* luax_newtempvector(lua_State* L, VectorType type); +enum { + V_NONE, + V_VEC2, + V_VEC3, + V_VEC4, + V_QUAT, + V_MAT4, + MAX_VECTOR_TYPES +}; + +float* luax_tovector(lua_State* L, int index, int* type); +float* luax_checkvector(lua_State* L, int index, int type, const char* expected); +float* luax_newvector(lua_State* L, int type); int luax_readvec2(lua_State* L, int index, float* v, const char* expected); int luax_readvec3(lua_State* L, int index, float* v, const char* expected); int luax_readvec4(lua_State* L, int index, float* v, const char* expected); diff --git a/src/api/l_event.c b/src/api/l_event.c index 7235f011..9b36b092 100644 --- a/src/api/l_event.c +++ b/src/api/l_event.c @@ -87,10 +87,10 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) { /* fallthrough */ case LUA_TLIGHTUSERDATA: { - VectorType type; - float* v = luax_tovector(L, index, &type); + int vtype; + float* v = luax_tovector(L, index, &vtype); if (v) { - if (type == V_MAT4) { + if (vtype == V_MAT4) { variant->type = TYPE_MATRIX; variant->value.matrix.data = malloc(16 * sizeof(float)); lovrAssert(variant->value.matrix.data, "Out of memory"); @@ -98,8 +98,9 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) { break; } else { variant->type = TYPE_VECTOR; - variant->value.vector.type = type; - memcpy(variant->value.vector.data, v, (type == V_VEC2 ? 2 : 4) * sizeof(float)); + variant->value.vector.type = vtype; + size_t components = vtype == V_VEC2 ? 2 : (vtype == V_VEC3 ? 3 : 4); + memcpy(variant->value.vector.data, v, components * sizeof(float)); break; } } else if (lua_type(L, index) == LUA_TLIGHTUSERDATA) { @@ -125,8 +126,8 @@ int luax_pushvariant(lua_State* L, Variant* variant) { case TYPE_MINISTRING: lua_pushlstring(L, variant->value.ministring.data, variant->value.ministring.length); return 1; case TYPE_POINTER: lua_pushlightuserdata(L, variant->value.pointer); return 1; case TYPE_OBJECT: _luax_pushtype(L, variant->value.object.type, hash64(variant->value.object.type, strlen(variant->value.object.type)), variant->value.object.pointer); return 1; - case TYPE_VECTOR: memcpy(luax_newtempvector(L, variant->value.vector.type), variant->value.vector.data, (variant->value.vector.type == V_VEC2 ? 2 : 4) * sizeof(float)); return 1; - case TYPE_MATRIX: memcpy(luax_newtempvector(L, V_MAT4), variant->value.vector.data, 16 * sizeof(float)); return 1; + case TYPE_VECTOR: memcpy(luax_newvector(L, variant->value.vector.type), variant->value.vector.data, (variant->value.vector.type == V_VEC2 ? 2 : 4) * sizeof(float)); return 1; + case TYPE_MATRIX: memcpy(luax_newvector(L, V_MAT4), variant->value.vector.data, 16 * sizeof(float)); return 1; default: return 0; } } diff --git a/src/api/l_graphics_buffer.c b/src/api/l_graphics_buffer.c index 9c299121..544e86cb 100644 --- a/src/api/l_graphics_buffer.c +++ b/src/api/l_graphics_buffer.c @@ -109,7 +109,7 @@ void luax_checkfieldv(lua_State* L, int index, int type, void* data) { DataPointer p = { .raw = data }; uint32_t n = typeComponents[type]; lovrCheck(n > 1, "Expected number for scalar data type, got vector"); - VectorType vectorType; + int vectorType; float* v = luax_tovector(L, index, &vectorType); lovrCheck(v, "Expected vector, got non-vector userdata"); if (n >= TYPE_MAT2 && n <= TYPE_MAT4) { diff --git a/src/api/l_graphics_model.c b/src/api/l_graphics_model.c index c7f5280f..b2d14010 100644 --- a/src/api/l_graphics_model.c +++ b/src/api/l_graphics_model.c @@ -198,10 +198,10 @@ static int l_lovrModelSetNodeTransform(lua_State* L) { Model* model = luax_checktype(L, 1, Model); uint32_t node = luax_checknodeindex(L, 2, lovrModelGetInfo(model)->data); int index = 3; - VectorType type; + int vtype; float position[3], scale[3], rotation[4]; - float* m = luax_tovector(L, index, &type); - if (m && type == V_MAT4) { + float* m = luax_tovector(L, index, &vtype); + if (m && vtype == V_MAT4) { mat4_getPosition(m, position); mat4_getScale(m, scale); mat4_getOrientation(m, rotation); diff --git a/src/api/l_graphics_pass.c b/src/api/l_graphics_pass.c index bb5d4542..40dca281 100644 --- a/src/api/l_graphics_pass.c +++ b/src/api/l_graphics_pass.c @@ -258,9 +258,9 @@ static int l_lovrPassGetViewPose(lua_State* L) { static int l_lovrPassSetViewPose(lua_State* L) { Pass* pass = luax_checktype(L, 1, Pass); uint32_t view = luaL_checkinteger(L, 2) - 1; - VectorType type; - float* p = luax_tovector(L, 3, &type); - if (p && type == V_MAT4) { + int vtype; + float* p = luax_tovector(L, 3, &vtype); + if (p && vtype == V_MAT4) { float matrix[16]; mat4_init(matrix, p); bool inverted = lua_toboolean(L, 4); @@ -876,7 +876,7 @@ static int l_lovrPassSphere(lua_State* L) { static bool luax_checkendpoints(lua_State* L, int index, float transform[16], bool center) { float *v, *u; - VectorType t1, t2; + int t1, t2; if ((v = luax_tovector(L, index + 0, &t1)) == NULL || t1 != V_VEC3) return false; if ((u = luax_tovector(L, index + 1, &t2)) == NULL || t2 != V_VEC3) return false; float radius = luax_optfloat(L, index + 2, 1.); diff --git a/src/api/l_math.c b/src/api/l_math.c index 460eb03d..7a2c7f43 100644 --- a/src/api/l_math.c +++ b/src/api/l_math.c @@ -31,36 +31,22 @@ extern const luaL_Reg lovrVec4[]; extern const luaL_Reg lovrQuat[]; extern const luaL_Reg lovrMat4[]; -static LOVR_THREAD_LOCAL Pool* pool; - -static struct { const char* name; lua_CFunction constructor, indexer; const luaL_Reg* api; int metaref; } lovrVectorInfo[] = { - [V_VEC2] = { "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL }, - [V_VEC3] = { "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL }, - [V_VEC4] = { "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL }, - [V_QUAT] = { "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL }, - [V_MAT4] = { "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL } +static struct { size_t components; const char* name; lua_CFunction metacall, metaindex; const luaL_Reg* api; int metaref; } lovrVectorInfo[] = { + [V_VEC2] = { 2, "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL }, + [V_VEC3] = { 3, "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL }, + [V_VEC4] = { 4, "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL }, + [V_QUAT] = { 4, "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL }, + [V_MAT4] = { 16, "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL } }; -static void luax_destroypool(void) { - lovrRelease(pool, lovrPoolDestroy); -} - -float* luax_tovector(lua_State* L, int index, VectorType* type) { +float* luax_tovector(lua_State* L, int index, int* type) { void* p = lua_touserdata(L, index); if (p) { - if (lua_type(L, index) == LUA_TLIGHTUSERDATA) { - Vector v = { .pointer = p }; - if (v.handle.type > V_NONE && v.handle.type < MAX_VECTOR_TYPES) { - if (type) *type = v.handle.type; - return lovrPoolResolve(pool, v); - } - } else { - VectorType* t = p; - if (*t > V_NONE && *t < MAX_VECTOR_TYPES) { - if (type) *type = *t; - return (float*) (t + 1); - } + int* t = p; + if (*t > V_NONE && *t < MAX_VECTOR_TYPES) { + if (type) *type = *t; + return (float*) (t + 1); } } @@ -68,26 +54,19 @@ float* luax_tovector(lua_State* L, int index, VectorType* type) { return NULL; } -float* luax_checkvector(lua_State* L, int index, VectorType type, const char* expected) { - VectorType t; +float* luax_checkvector(lua_State* L, int index, int type, const char* expected) { + int t; float* p = luax_tovector(L, index, &t); if (!p || t != type) luax_typeerror(L, index, expected ? expected : lovrVectorInfo[type].name); return p; } -static float* luax_newvector(lua_State* L, VectorType type, size_t components) { - VectorType* p = lua_newuserdata(L, sizeof(VectorType) + components * sizeof(float)); - *p = type; +float* luax_newvector(lua_State* L, int type) { + void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); + *((int*) p) = type; lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); lua_setmetatable(L, -2); - return (float*) (p + 1); -} - -float* luax_newtempvector(lua_State* L, VectorType type) { - float* data; - Vector vector = lovrPoolAllocate(pool, type, &data); - lua_pushlightuserdata(L, vector.pointer); - return data; + return (float*) ((char*) p + sizeof(int)); } static int l_lovrMathNewCurve(lua_State* L) { @@ -213,70 +192,65 @@ static int l_lovrMathLinearToGamma(lua_State* L) { } static int l_lovrMathNewVec2(lua_State* L) { - luax_newvector(L, V_VEC2, 2); + luax_newvector(L, V_VEC2); lua_insert(L, 1); return l_lovrVec2Set(L); } static int l_lovrMathNewVec3(lua_State* L) { - luax_newvector(L, V_VEC3, 4); + luax_newvector(L, V_VEC3); lua_insert(L, 1); return l_lovrVec3Set(L); } static int l_lovrMathNewVec4(lua_State* L) { - luax_newvector(L, V_VEC4, 4); + luax_newvector(L, V_VEC4); lua_insert(L, 1); return l_lovrVec4Set(L); } static int l_lovrMathNewQuat(lua_State* L) { - luax_newvector(L, V_QUAT, 4); + luax_newvector(L, V_QUAT); lua_insert(L, 1); return l_lovrQuatSet(L); } static int l_lovrMathNewMat4(lua_State* L) { - luax_newvector(L, V_MAT4, 16); + luax_newvector(L, V_MAT4); lua_insert(L, 1); return l_lovrMat4Set(L); } static int l_lovrMathVec2(lua_State* L) { - luax_newtempvector(L, V_VEC2); + luax_newvector(L, V_VEC2); lua_replace(L, 1); return l_lovrVec2Set(L); } static int l_lovrMathVec3(lua_State* L) { - luax_newtempvector(L, V_VEC3); + luax_newvector(L, V_VEC3); lua_replace(L, 1); return l_lovrVec3Set(L); } static int l_lovrMathVec4(lua_State* L) { - luax_newtempvector(L, V_VEC4); + luax_newvector(L, V_VEC4); lua_replace(L, 1); return l_lovrVec4Set(L); } static int l_lovrMathQuat(lua_State* L) { - luax_newtempvector(L, V_QUAT); + luax_newvector(L, V_QUAT); lua_replace(L, 1); return l_lovrQuatSet(L); } static int l_lovrMathMat4(lua_State* L) { - luax_newtempvector(L, V_MAT4); + luax_newvector(L, V_MAT4); lua_replace(L, 1); return l_lovrMat4Set(L); } -static int l_lovrMathDrain(lua_State* L) { - lovrPoolDrain(pool); - return 0; -} - static const luaL_Reg lovrMath[] = { { "newCurve", l_lovrMathNewCurve }, { "newRandomGenerator", l_lovrMathNewRandomGenerator }, @@ -292,71 +266,22 @@ static const luaL_Reg lovrMath[] = { { "newVec4", l_lovrMathNewVec4 }, { "newQuat", l_lovrMathNewQuat }, { "newMat4", l_lovrMathNewMat4 }, - { "drain", l_lovrMathDrain }, { NULL, NULL } }; -static int l_lovrLightUserdata__index(lua_State* L) { - VectorType type; - if (!luax_tovector(L, 1, &type)) { - return 0; - } - - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_pushliteral(L, "__index"); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_call(L, 2, 1); - return 1; - } else { - return 0; - } - } - return 1; -} - -static int l_lovrLightUserdataOp(lua_State* L) { - VectorType type; - if (!luax_tovector(L, lua_islightuserdata(L, 1) ? 1 : 2, &type)) { - lua_pushliteral(L, "__tostring"); - if (lua_rawequal(L, -1, lua_upvalueindex(1))) { - lua_pop(L, 1); - lua_pushfstring(L, "%s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1)); - return 1; - } - lua_pop(L, 1); - return luaL_error(L, "Unsupported lightuserdata operator %q", lua_tostring(L, lua_upvalueindex(1))); - } - - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); - lua_pushvalue(L, lua_upvalueindex(1)); - lua_gettable(L, -2); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_call(L, 3, 1); - return 1; -} - int luaopen_lovr_math(lua_State* L) { lua_newtable(L); luax_register(L, lovrMath); luax_registertype(L, Curve); luax_registertype(L, RandomGenerator); - for (size_t i = V_NONE + 1; i < MAX_VECTOR_TYPES; i++) { + for (int i = V_NONE + 1; i < MAX_VECTOR_TYPES; i++) { lua_newtable(L); lua_newtable(L); - lua_pushcfunction(L, lovrVectorInfo[i].constructor); + lua_pushcfunction(L, lovrVectorInfo[i].metacall); lua_setfield(L, -2, "__call"); - lua_pushcfunction(L, lovrVectorInfo[i].indexer); + lua_pushcfunction(L, lovrVectorInfo[i].metaindex); lua_setfield(L, -2, "__index"); lua_setmetatable(L, -2); @@ -372,28 +297,10 @@ int luaopen_lovr_math(lua_State* L) { lovrVectorInfo[i].metaref = luaL_ref(L, LUA_REGISTRYINDEX); } - // Global lightuserdata metatable - lua_pushlightuserdata(L, NULL); - lua_newtable(L); - lua_pushcfunction(L, l_lovrLightUserdata__index); - lua_setfield(L, -2, "__index"); - const char* ops[] = { "__add", "__sub", "__mul", "__div", "__unm", "__len", "__tostring", "__newindex" }; - for (size_t i = 0; i < COUNTOF(ops); i++) { - lua_pushstring(L, ops[i]); - lua_pushcclosure(L, l_lovrLightUserdataOp, 1); - lua_setfield(L, -2, ops[i]); - } - lua_setmetatable(L, -2); - lua_pop(L, 1); - // Module lovrMathInit(); luax_atexit(L, lovrMathDestroy); - // Each Lua state gets its own thread-local Pool - pool = lovrPoolCreate(); - luax_atexit(L, luax_destroypool); - // Globals luax_pushconf(L); if (lua_istable(L, -1)) { @@ -401,7 +308,7 @@ int luaopen_lovr_math(lua_State* L) { if (lua_istable(L, -1)) { lua_getfield(L, -1, "globals"); if (lua_toboolean(L, -1)) { - for (size_t i = V_NONE + 1; i < MAX_VECTOR_TYPES; i++) { + for (int i = V_NONE + 1; i < MAX_VECTOR_TYPES; i++) { lua_getfield(L, -4, lovrVectorInfo[i].name); lua_setglobal(L, lovrVectorInfo[i].name); diff --git a/src/api/l_math_curve.c b/src/api/l_math_curve.c index 275e3e90..10a40d39 100644 --- a/src/api/l_math_curve.c +++ b/src/api/l_math_curve.c @@ -1,4 +1,5 @@ #include "api.h" +#include "math/math.h" #include "util.h" static int l_lovrCurveEvaluate(lua_State* L) { diff --git a/src/api/l_math_randomGenerator.c b/src/api/l_math_randomGenerator.c index 6590f2f7..47692031 100644 --- a/src/api/l_math_randomGenerator.c +++ b/src/api/l_math_randomGenerator.c @@ -1,4 +1,5 @@ #include "api.h" +#include "math/math.h" #include "util.h" #include diff --git a/src/api/l_math_vectors.c b/src/api/l_math_vectors.c index 4e1afaa6..5e5d873b 100644 --- a/src/api/l_math_vectors.c +++ b/src/api/l_math_vectors.c @@ -113,7 +113,7 @@ int luax_readscale(lua_State* L, int index, vec3 v, int components, const char* } return index; default: { - VectorType type; + int type; float* u = luax_tovector(L, index++, &type); if (type == V_VEC2) { v[0] = u[0]; @@ -159,7 +159,7 @@ int luax_readmat4(lua_State* L, int index, mat4 m, int scaleComponents) { case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: default: { - VectorType type; + int type; float* p = luax_tovector(L, index, &type); if (type == V_MAT4) { mat4_init(m, p); @@ -213,8 +213,8 @@ static int l_lovrVec2Add(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); float u[2]; luax_readvec2(L, 2, u, NULL); - vec2_add(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_add(vec2_init(out, v), u); return 1; } @@ -222,8 +222,8 @@ static int l_lovrVec2Sub(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); float u[2]; luax_readvec2(L, 2, u, NULL); - vec2_sub(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_sub(vec2_init(out, v), u); return 1; } @@ -231,8 +231,8 @@ static int l_lovrVec2Mul(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); float u[2]; luax_readvec2(L, 2, u, NULL); - vec2_mul(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_mul(vec2_init(out, v), u); return 1; } @@ -240,8 +240,8 @@ static int l_lovrVec2Div(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); float u[2]; luax_readvec2(L, 2, u, NULL); - vec2_div(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_div(vec2_init(out, v), u); return 1; } @@ -253,8 +253,8 @@ static int l_lovrVec2Length(lua_State* L) { static int l_lovrVec2Normalize(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); - vec2_normalize(v); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_normalize(vec2_init(out, v)); return 1; } @@ -279,8 +279,8 @@ static int l_lovrVec2Lerp(lua_State* L) { float u[2]; int index = luax_readvec2(L, 2, u, NULL); float t = luax_checkfloat(L, index); - vec2_lerp(v, u, t); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC2); + vec2_lerp(vec2_init(out, v), u, t); return 1; } @@ -293,7 +293,7 @@ static int l_lovrVec2Angle(lua_State* L) { } static int l_lovrVec2__add(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC2, NULL); @@ -313,7 +313,7 @@ static int l_lovrVec2__add(lua_State* L) { } static int l_lovrVec2__sub(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC2, NULL); @@ -333,7 +333,7 @@ static int l_lovrVec2__sub(lua_State* L) { } static int l_lovrVec2__mul(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC2, NULL); @@ -353,7 +353,7 @@ static int l_lovrVec2__mul(lua_State* L) { } static int l_lovrVec2__div(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC2, NULL); @@ -374,7 +374,7 @@ static int l_lovrVec2__div(lua_State* L) { static int l_lovrVec2__unm(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); vec2_scale(vec2_init(out, v), -1.f); return 1; } @@ -451,18 +451,18 @@ static int l_lovrVec2__index(lua_State* L) { lua_pushnumber(L, v[swizzles[2][key[0]] - 1]); return 1; } else if (length == 2 && swizzles[2][key[0]] && swizzles[2][key[1]]) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); out[0] = v[swizzles[2][key[0]] - 1]; out[1] = v[swizzles[2][key[1]] - 1]; return 1; } else if (length == 3 && swizzles[2][key[0]] && swizzles[2][key[1]] && swizzles[2][key[2]]) { - float* out = luax_newtempvector(L, V_VEC3); + float* out = luax_newvector(L, V_VEC3); out[0] = v[swizzles[2][key[0]] - 1]; out[1] = v[swizzles[2][key[1]] - 1]; out[2] = v[swizzles[2][key[2]] - 1]; return 1; } else if (length == 4 && swizzles[2][key[0]] && swizzles[2][key[1]] && swizzles[2][key[2]] && swizzles[2][key[3]]) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); out[0] = v[swizzles[2][key[0]] - 1]; out[1] = v[swizzles[2][key[1]] - 1]; out[2] = v[swizzles[2][key[2]] - 1]; @@ -491,7 +491,7 @@ int l_lovrVec2__metaindex(lua_State* L) { for (uint32_t i = 0; i < COUNTOF(properties); i++) { if (length == properties[i].name.length && !memcmp(key, properties[i].name.string, length)) { - float* v = luax_newtempvector(L, V_VEC2); + float* v = luax_newvector(L, V_VEC2); v[0] = properties[i].x; v[1] = properties[i].y; return 1; @@ -556,7 +556,7 @@ int l_lovrVec3Set(lua_State* L) { float x = luax_optfloat(L, 2, 0.f); vec3_set(v, x, luax_optfloat(L, 3, x), luax_optfloat(L, 4, x)); } else { - VectorType t; + int t; float* p = luax_tovector(L, 2, &t); if (p && t == V_VEC3) { vec3_init(v, p); @@ -576,8 +576,8 @@ static int l_lovrVec3Add(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float u[3]; luax_readvec3(L, 2, u, NULL); - vec3_add(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_add(vec3_init(out, v), u); return 1; } @@ -585,8 +585,8 @@ static int l_lovrVec3Sub(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float u[3]; luax_readvec3(L, 2, u, NULL); - vec3_sub(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_sub(vec3_init(out, v), u); return 1; } @@ -594,8 +594,8 @@ static int l_lovrVec3Mul(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float u[3]; luax_readvec3(L, 2, u, NULL); - vec3_mul(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_mul(vec3_init(out, v), u); return 1; } @@ -603,8 +603,8 @@ static int l_lovrVec3Div(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float u[3]; luax_readvec3(L, 2, u, NULL); - vec3_div(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_div(vec3_init(out, v), u); return 1; } @@ -616,8 +616,8 @@ static int l_lovrVec3Length(lua_State* L) { static int l_lovrVec3Normalize(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - vec3_normalize(v); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_normalize(vec3_init(out, v)); return 1; } @@ -641,8 +641,8 @@ static int l_lovrVec3Cross(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float u[3]; luax_readvec3(L, 2, u, NULL); - vec3_cross(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_cross(vec3_init(out, v), u); return 1; } @@ -651,8 +651,8 @@ static int l_lovrVec3Lerp(lua_State* L) { float u[3]; int index = luax_readvec3(L, 2, u, NULL); float t = luax_checkfloat(L, index); - vec3_lerp(v, u, t); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + vec3_lerp(vec3_init(out, v), u, t); return 1; } @@ -668,8 +668,8 @@ static int l_lovrVec3Transform(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float m[16]; luax_readmat4(L, 2, m, 1); - mat4_mulPoint(m, v); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + mat4_mulPoint(m, vec3_init(out, v)); return 1; } @@ -677,13 +677,13 @@ static int l_lovrVec3Rotate(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); float q[4]; luax_readquat(L, 2, q, NULL); - quat_rotate(q, v); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC3); + quat_rotate(q, vec3_init(out, v)); return 1; } static int l_lovrVec3__add(lua_State* L) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); if (lua_type(L, 1) == LUA_TNUMBER) { float x = luax_tofloat(L, 1); vec3 v = luax_checkvector(L, 2, V_VEC3, NULL); @@ -705,7 +705,7 @@ static int l_lovrVec3__add(lua_State* L) { } static int l_lovrVec3__sub(lua_State* L) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); if (lua_type(L, 1) == LUA_TNUMBER) { float x = luax_tofloat(L, 1); vec3 v = luax_checkvector(L, 2, V_VEC3, NULL); @@ -727,7 +727,7 @@ static int l_lovrVec3__sub(lua_State* L) { } static int l_lovrVec3__mul(lua_State* L) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); if (lua_type(L, 1) == LUA_TNUMBER) { vec3 v = luax_checkvector(L, 2, V_VEC3, NULL); vec3_scale(vec3_init(out, v), luax_tofloat(L, 1)); @@ -743,7 +743,7 @@ static int l_lovrVec3__mul(lua_State* L) { } static int l_lovrVec3__div(lua_State* L) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); if (lua_type(L, 1) == LUA_TNUMBER) { vec3 v = luax_checkvector(L, 2, V_VEC3, NULL); vec3_scale(vec3_init(out, v), 1.f / luax_tofloat(L, 1)); @@ -760,7 +760,7 @@ static int l_lovrVec3__div(lua_State* L) { static int l_lovrVec3__unm(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); vec3_scale(vec3_init(out, v), -1.f); return 1; } @@ -843,18 +843,18 @@ static int l_lovrVec3__index(lua_State* L) { lua_pushnumber(L, v[swizzles[3][key[0]] - 1]); return 1; } else if (length == 2 && swizzles[3][key[0]] && swizzles[3][key[1]]) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); out[0] = v[swizzles[3][key[0]] - 1]; out[1] = v[swizzles[3][key[1]] - 1]; return 1; } else if (length == 3 && swizzles[3][key[0]] && swizzles[3][key[1]] && swizzles[3][key[2]]) { - float* out = luax_newtempvector(L, V_VEC3); + float* out = luax_newvector(L, V_VEC3); out[0] = v[swizzles[3][key[0]] - 1]; out[1] = v[swizzles[3][key[1]] - 1]; out[2] = v[swizzles[3][key[2]] - 1]; return 1; } else if (length == 4 && swizzles[3][key[0]] && swizzles[3][key[1]] && swizzles[3][key[2]] && swizzles[3][key[3]]) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); out[0] = v[swizzles[3][key[0]] - 1]; out[1] = v[swizzles[3][key[1]] - 1]; out[2] = v[swizzles[3][key[2]] - 1]; @@ -889,7 +889,7 @@ int l_lovrVec3__metaindex(lua_State* L) { for (uint32_t i = 0; i < COUNTOF(properties); i++) { if (length == properties[i].name.length && !memcmp(key, properties[i].name.string, length)) { - float* v = luax_newtempvector(L, V_VEC3); + float* v = luax_newvector(L, V_VEC3); vec3_set(v, properties[i].x, properties[i].y, properties[i].z); return 1; } @@ -964,8 +964,8 @@ static int l_lovrVec4Add(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); float u[4]; luax_readvec4(L, 2, u, NULL); - vec4_add(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + vec4_add(vec4_init(out, v), u); return 1; } @@ -973,8 +973,8 @@ static int l_lovrVec4Sub(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); float u[4]; luax_readvec4(L, 2, u, NULL); - vec4_sub(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + vec4_sub(vec4_init(out, v), u); return 1; } @@ -982,8 +982,8 @@ static int l_lovrVec4Mul(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); float u[4]; luax_readvec4(L, 2, u, NULL); - vec4_mul(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + vec4_mul(vec4_init(out, v), u); return 1; } @@ -991,8 +991,8 @@ static int l_lovrVec4Div(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); float u[4]; luax_readvec4(L, 2, u, NULL); - vec4_div(v, u); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + vec4_div(vec4_init(out, v), u); return 1; } @@ -1004,7 +1004,8 @@ static int l_lovrVec4Length(lua_State* L) { static int l_lovrVec4Normalize(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); - vec4_normalize(v); + float* out = luax_newvector(L, V_VEC4); + vec4_normalize(vec4_init(out, v)); lua_settop(L, 1); return 1; } @@ -1030,8 +1031,8 @@ static int l_lovrVec4Lerp(lua_State* L) { float u[4]; int index = luax_readvec4(L, 2, u, NULL); float t = luax_checkfloat(L, index); - vec4_lerp(v, u, t); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + vec4_lerp(vec4_init(out, v), u, t); return 1; } @@ -1047,13 +1048,13 @@ static int l_lovrVec4Transform(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); float m[16]; luax_readmat4(L, 2, m, 1); - mat4_mulVec4(m, v); - lua_settop(L, 1); + float* out = luax_newvector(L, V_VEC4); + mat4_mulVec4(m, vec4_init(out, v)); return 1; } static int l_lovrVec4__add(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC4, NULL); @@ -1077,7 +1078,7 @@ static int l_lovrVec4__add(lua_State* L) { } static int l_lovrVec4__sub(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC4, NULL); @@ -1101,7 +1102,7 @@ static int l_lovrVec4__sub(lua_State* L) { } static int l_lovrVec4__mul(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC4, NULL); @@ -1125,7 +1126,7 @@ static int l_lovrVec4__mul(lua_State* L) { } static int l_lovrVec4__div(lua_State* L) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); if (lua_type(L, 1) == LUA_TNUMBER) { float x = lua_tonumber(L, 1); float* u = luax_checkvector(L, 2, V_VEC4, NULL); @@ -1150,7 +1151,7 @@ static int l_lovrVec4__div(lua_State* L) { static int l_lovrVec4__unm(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); vec4_scale(vec4_init(out, v), -1.f); return 1; } @@ -1239,18 +1240,18 @@ static int l_lovrVec4__index(lua_State* L) { lua_pushnumber(L, v[swizzles[4][key[0]] - 1]); return 1; } else if (length == 2 && swizzles[4][key[0]] && swizzles[4][key[1]]) { - float* out = luax_newtempvector(L, V_VEC2); + float* out = luax_newvector(L, V_VEC2); out[0] = v[swizzles[4][key[0]] - 1]; out[1] = v[swizzles[4][key[1]] - 1]; return 1; } else if (length == 3 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]]) { - float* out = luax_newtempvector(L, V_VEC3); + float* out = luax_newvector(L, V_VEC3); out[0] = v[swizzles[4][key[0]] - 1]; out[1] = v[swizzles[4][key[1]] - 1]; out[2] = v[swizzles[4][key[2]] - 1]; return 1; } else if (length == 4 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]] && swizzles[4][key[3]]) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); out[0] = v[swizzles[4][key[0]] - 1]; out[1] = v[swizzles[4][key[1]] - 1]; out[2] = v[swizzles[4][key[2]] - 1]; @@ -1279,7 +1280,7 @@ int l_lovrVec4__metaindex(lua_State* L) { for (uint32_t i = 0; i < COUNTOF(properties); i++) { if (length == properties[i].name.length && !memcmp(key, properties[i].name.string, length)) { - float* v = luax_newtempvector(L, V_VEC4); + float* v = luax_newvector(L, V_VEC4); v[0] = properties[i].x; v[1] = properties[i].y; v[2] = properties[i].z; @@ -1370,7 +1371,7 @@ int l_lovrQuatSet(lua_State* L) { quat_fromAngleAxis(q, x, y, z, w); } } else { - VectorType type; + int type; float* p = luax_tovector(L, 2, &type); if (!p) return luax_typeerror(L, 2, "vec3, quat, or number"); @@ -1396,17 +1397,17 @@ int l_lovrQuatSet(lua_State* L) { static int l_lovrQuatMul(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); - VectorType type; + int type; float* r = luax_tovector(L, 2, &type); if (r && type == V_VEC3) { - vec3 v = luax_newtempvector(L, V_VEC3); + vec3 v = luax_newvector(L, V_VEC3); quat_rotate(q, vec3_init(v, r)); } else if (r && type == V_QUAT) { - quat_mul(q, q, r); - lua_settop(L, 1); + float* out = luax_newvector(L, V_QUAT); + quat_mul(out, q, r); } else if (lua_type(L, 2) == LUA_TNUMBER) { lua_settop(L, 4); - vec3 v = luax_newtempvector(L, V_VEC3); + vec3 v = luax_newvector(L, V_VEC3); v[0] = luax_tofloat(L, 2); v[1] = luax_checkfloat(L, 3); v[2] = luax_checkfloat(L, 4); @@ -1425,22 +1426,22 @@ static int l_lovrQuatLength(lua_State* L) { static int l_lovrQuatNormalize(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); - quat_normalize(q); - lua_settop(L, 1); + float* out = luax_newvector(L, V_QUAT); + quat_normalize(quat_init(out, q)); return 1; } static int l_lovrQuatDirection(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); - vec3 v = luax_newtempvector(L, V_VEC3); + vec3 v = luax_newvector(L, V_VEC3); quat_getDirection(q, v); return 1; } static int l_lovrQuatConjugate(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); - quat_conjugate(q); - lua_settop(L, 1); + float* out = luax_newvector(L, V_QUAT); + quat_conjugate(quat_init(out, q)); return 1; } @@ -1448,8 +1449,8 @@ static int l_lovrQuatSlerp(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); quat r = luax_checkvector(L, 2, V_QUAT, NULL); float t = luax_checkfloat(L, 3); - quat_slerp(q, r, t); - lua_settop(L, 1); + float* out = luax_newvector(L, V_QUAT); + quat_slerp(quat_init(out, q), r, t); return 1; } @@ -1475,14 +1476,14 @@ static int l_lovrQuatSetEuler(lua_State* L) { static int l_lovrQuat__mul(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); - VectorType type; + int type; float* r = luax_tovector(L, 2, &type); if (!r) return luax_typeerror(L, 2, "quat or vec3"); if (type == V_VEC3) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); quat_rotate(q, vec3_init(out, r)); } else { - quat out = luax_newtempvector(L, V_QUAT); + quat out = luax_newvector(L, V_QUAT); quat_mul(out, q, r); } return 1; @@ -1574,7 +1575,7 @@ int l_lovrQuat__metaindex(lua_State* L) { for (uint32_t i = 0; i < COUNTOF(properties); i++) { if (length == properties[i].name.length && !memcmp(key, properties[i].name.string, length)) { - float* q = luax_newtempvector(L, V_QUAT); + float* q = luax_newvector(L, V_QUAT); quat_set(q, properties[i].x, properties[i].y, properties[i].z, properties[i].w); return 1; } @@ -1714,7 +1715,7 @@ int l_lovrMat4Set(lua_State* L) { *m++ = luax_checkfloat(L, i); } } else { - VectorType vectorType; + int vectorType; float* n = luax_tovector(L, 2, &vectorType); if (vectorType == V_MAT4) { mat4_init(m, n); @@ -1766,20 +1767,20 @@ int l_lovrMat4Set(lua_State* L) { static int l_lovrMat4Mul(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - VectorType type; + int type; float* n = luax_tovector(L, 2, &type); if (n && type == V_MAT4) { - mat4_mul(m, n); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_mul(mat4_init(out, m), n); } else if (n && type == V_VEC3) { - vec3 v = luax_newtempvector(L, V_VEC3); + vec3 v = luax_newvector(L, V_VEC3); mat4_mulPoint(m, vec3_init(v, n)); } else if (n && type == V_VEC4) { - vec4 v = luax_newtempvector(L, V_VEC4); + vec4 v = luax_newvector(L, V_VEC4); mat4_mulVec4(m, vec4_init(v, n)); } else if (lua_type(L, 2) == LUA_TNUMBER) { lua_settop(L, 4); - vec3 v = luax_newtempvector(L, V_VEC3); + vec3 v = luax_newvector(L, V_VEC3); v[0] = luax_tofloat(L, 2); v[1] = luax_checkfloat(L, 3); v[2] = luax_checkfloat(L, 4); @@ -1792,46 +1793,55 @@ static int l_lovrMat4Mul(lua_State* L) { static int l_lovrMat4Identity(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - mat4_identity(m); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_identity(mat4_init(out, m)); return 1; } static int l_lovrMat4Invert(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - mat4_invert(m); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_invert(mat4_init(out, m)); return 1; } static int l_lovrMat4Transpose(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - mat4_transpose(m); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_transpose(mat4_init(out, m)); return 1; } static int l_lovrMat4Translate(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); if (lua_type(L, 2) == LUA_TNUMBER) { - mat4_translate(m, luax_checkfloat(L, 2), luax_checkfloat(L, 3), luax_checkfloat(L, 4)); + float x = luax_checkfloat(L, 2); + float y = luax_checkfloat(L, 3); + float z = luax_checkfloat(L, 4); + float* out = luax_newvector(L, V_MAT4); + mat4_translate(mat4_init(out, m), x, y, z); } else { float* v = luax_checkvector(L, 2, V_VEC3, "vec3 or number"); - mat4_translate(m, v[0], v[1], v[2]); + float* out = luax_newvector(L, V_MAT4); + mat4_translate(mat4_init(out, m), v[0], v[1], v[2]); } - lua_settop(L, 1); return 1; } static int l_lovrMat4Rotate(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); if (lua_type(L, 2) == LUA_TNUMBER) { - mat4_rotate(m, luax_checkfloat(L, 2), luax_optfloat(L, 3, 0.f), luax_optfloat(L, 4, 1.f), luax_optfloat(L, 5, 0.f)); + float angle = luax_checkfloat(L, 2); + float ax = luax_optfloat(L, 3, 0.f); + float ay = luax_optfloat(L, 4, 1.f); + float az = luax_optfloat(L, 5, 0.f); + float* out = luax_newvector(L, V_MAT4); + mat4_rotate(mat4_init(out, m), angle, ax, ay, az); } else { float* q = luax_checkvector(L, 2, V_QUAT, "quat or number"); - mat4_rotateQuat(m, q); + float* out = luax_newvector(L, V_MAT4); + mat4_rotateQuat(mat4_init(out, m), q); } - lua_settop(L, 1); return 1; } @@ -1839,23 +1849,27 @@ static int l_lovrMat4Scale(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); if (lua_type(L, 2) == LUA_TNUMBER) { float x = luax_checkfloat(L, 2); - mat4_scale(m, x, luax_optfloat(L, 3, x), luax_optfloat(L, 4, x)); + float y = luax_optfloat(L, 3, x); + float z = luax_optfloat(L, 4, x); + float* out = luax_newvector(L, V_MAT4); + mat4_scale(mat4_init(out, m), x, y, z); } else { float* s = luax_checkvector(L, 2, V_VEC3, "vec3 or number"); - mat4_scale(m, s[0], s[1], s[2]); + float* out = luax_newvector(L, V_MAT4); + mat4_scale(mat4_init(out, m), s[0], s[1], s[2]); } - lua_settop(L, 1); return 1; } static int l_lovrMat4Orthographic(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); if (lua_gettop(L) <= 5) { float width = luax_checkfloat(L, 2); float height = luax_checkfloat(L, 3); float n = luax_optfloat(L, 4, -1.f); float f = luax_optfloat(L, 5, 1.f); - mat4_orthographic(m, 0.f, width, 0.f, height, n, f); + float* out = luax_newvector(L, V_MAT4); + mat4_orthographic(out, 0.f, width, 0.f, height, n, f); } else { float left = luax_checkfloat(L, 2); float right = luax_checkfloat(L, 3); @@ -1863,79 +1877,80 @@ static int l_lovrMat4Orthographic(lua_State* L) { float top = luax_checkfloat(L, 5); float n = luax_checkfloat(L, 6); float f = luax_checkfloat(L, 7); - mat4_orthographic(m, left, right, bottom, top, n, f); + float* out = luax_newvector(L, V_MAT4); + mat4_orthographic(out, left, right, bottom, top, n, f); } - lua_settop(L, 1); return 1; } static int l_lovrMat4Perspective(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); float fovy = luax_checkfloat(L, 2); float aspect = luax_checkfloat(L, 3); float n = luax_checkfloat(L, 4); float f = luax_optfloat(L, 5, 0.); - mat4_perspective(m, fovy, aspect, n, f); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_perspective(out, fovy, aspect, n, f); return 1; } static int l_lovrMat4Fov(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); float left = luax_checkfloat(L, 2); float right = luax_checkfloat(L, 3); float up = luax_checkfloat(L, 4); float down = luax_checkfloat(L, 5); float n = luax_checkfloat(L, 6); float f = luax_optfloat(L, 7, 0.); - mat4_fov(m, left, right, up, down, n, f); + float* out = luax_newvector(L, V_MAT4); + mat4_fov(out, left, right, up, down, n, f); lua_settop(L, 1); return 1; } static int l_lovrMat4LookAt(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); vec3 from = luax_checkvector(L, 2, V_VEC3, NULL); vec3 to = luax_checkvector(L, 3, V_VEC3, NULL); vec3 up = lua_isnoneornil(L, 4) ? (float[3]) { 0.f, 1.f, 0.f } : luax_checkvector(L, 4, V_VEC3, NULL); - mat4_lookAt(m, from, to, up); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_lookAt(out, from, to, up); return 1; } static int l_lovrMat4Target(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); vec3 from = luax_checkvector(L, 2, V_VEC3, NULL); vec3 to = luax_checkvector(L, 3, V_VEC3, NULL); vec3 up = lua_isnoneornil(L, 4) ? (float[3]) { 0.f, 1.f, 0.f } : luax_checkvector(L, 4, V_VEC3, NULL); - mat4_target(m, from, to, up); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_target(out, from, to, up); return 1; } static int l_lovrMat4Reflect(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); + luax_checkvector(L, 1, V_MAT4, NULL); vec3 position = luax_checkvector(L, 2, V_VEC3, NULL); vec3 normal = luax_checkvector(L, 3, V_VEC3, NULL); - mat4_reflect(m, position, normal); - lua_settop(L, 1); + float* out = luax_newvector(L, V_MAT4); + mat4_reflect(out, position, normal); return 1; } static int l_lovrMat4__mul(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - VectorType type; + int type; float* n = luax_tovector(L, 2, &type); if (!n || (type == V_VEC2 || type == V_QUAT)) return luax_typeerror(L, 2, "mat4, vec3, or vec4"); if (type == V_MAT4) { - mat4 out = luax_newtempvector(L, V_MAT4); + mat4 out = luax_newvector(L, V_MAT4); mat4_mul(mat4_init(out, m), n); } else if (type == V_VEC3) { - vec3 out = luax_newtempvector(L, V_VEC3); + vec3 out = luax_newvector(L, V_VEC3); vec3_init(out, n); mat4_mulPoint(m, out); } else if (type == V_VEC4) { - float* out = luax_newtempvector(L, V_VEC4); + float* out = luax_newvector(L, V_VEC4); memcpy(out, n, 4 * sizeof(float)); mat4_mulVec4(m, out); } else { diff --git a/src/modules/math/math.c b/src/modules/math/math.c index e10cb970..5f453bb9 100644 --- a/src/modules/math/math.c +++ b/src/modules/math/math.c @@ -216,70 +216,6 @@ void lovrCurveRemovePoint(Curve* curve, size_t index) { arr_splice(&curve->points, index * 4, 4); } -// Pool - -static const size_t vectorComponents[] = { - [V_VEC2] = 2, - [V_VEC3] = 4, - [V_VEC4] = 4, - [V_QUAT] = 4, - [V_MAT4] = 16 -}; - -Pool* lovrPoolCreate(void) { - Pool* pool = calloc(1, sizeof(Pool)); - lovrAssert(pool, "Out of memory"); - pool->ref = 1; - pool->data = os_vm_init((1 << 24) * sizeof(float)); - lovrPoolGrow(pool, 1 << 12); - return pool; -} - -void lovrPoolDestroy(void* ref) { - Pool* pool = ref; - os_vm_free(pool->data, (1 << 24) * sizeof(float)); - free(pool); -} - -void lovrPoolGrow(Pool* pool, size_t count) { - lovrAssert(count <= (1 << 24), "Temporary vector space exhausted. Try using lovr.math.drain to drain the vector pool periodically."); - pool->count = (uint32_t) count; // Assert guarantees safe - bool result = os_vm_commit(pool->data, count * sizeof(float)); - lovrAssert(result, "Out of memory"); -} - -Vector lovrPoolAllocate(Pool* pool, VectorType type, float** data) { - lovrCheck(pool, "The math module must be initialized to create vectors"); - - size_t count = vectorComponents[type]; - - if (pool->cursor + count > pool->count) { - lovrPoolGrow(pool, pool->count * 2); - } - - Vector v = { - .handle = { - .type = type, - .generation = pool->generation, - .index = pool->cursor - } - }; - - *data = pool->data + pool->cursor; - pool->cursor += (uint32_t) count; // Cast safe because vectorComponents members are known - return v; -} - -float* lovrPoolResolve(Pool* pool, Vector vector) { - lovrAssert(vector.handle.generation == pool->generation, "Attempt to use a temporary vector from a previous frame"); - return pool->data + vector.handle.index; -} - -void lovrPoolDrain(Pool* pool) { - pool->cursor = 0; - pool->generation = (pool->generation + 1) & 0xf; -} - // RandomGenerator (compatible with LÖVE's) // Thomas Wang's 64-bit integer hashing function: diff --git a/src/modules/math/math.h b/src/modules/math/math.h index 56990ee6..693b66e4 100644 --- a/src/modules/math/math.h +++ b/src/modules/math/math.h @@ -5,7 +5,6 @@ #pragma once typedef struct Curve Curve; -typedef struct Pool Pool; typedef struct RandomGenerator RandomGenerator; bool lovrMathInit(void); @@ -31,35 +30,6 @@ void lovrCurveSetPoint(Curve* curve, size_t index, float* point); void lovrCurveAddPoint(Curve* curve, float* point, size_t index); void lovrCurveRemovePoint(Curve* curve, size_t index); -// Pool - -typedef enum { - V_NONE, - V_VEC2, - V_VEC3, - V_VEC4, - V_QUAT, - V_MAT4, - MAX_VECTOR_TYPES -} VectorType; - -typedef union { - void* pointer; - struct { - unsigned type : 4; - unsigned generation : 4; - unsigned index : 24; - unsigned padding : 32; - } handle; -} Vector; - -Pool* lovrPoolCreate(void); -void lovrPoolDestroy(void* ref); -void lovrPoolGrow(Pool* pool, size_t count); -Vector lovrPoolAllocate(Pool* pool, VectorType type, float** data); -float* lovrPoolResolve(Pool* pool, Vector vector); -void lovrPoolDrain(Pool* pool); - // RandomGenerator typedef union { From c7d4801ba2db7f9a31fa6e00621a88d79a66f2da Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 24 Dec 2023 13:01:42 -0800 Subject: [PATCH 2/6] lovr.math.push/lovr.math.pop experiment; --- src/api/l_math.c | 70 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/src/api/l_math.c b/src/api/l_math.c index 7a2c7f43..2308ab77 100644 --- a/src/api/l_math.c +++ b/src/api/l_math.c @@ -31,12 +31,12 @@ extern const luaL_Reg lovrVec4[]; extern const luaL_Reg lovrQuat[]; extern const luaL_Reg lovrMat4[]; -static struct { size_t components; const char* name; lua_CFunction metacall, metaindex; const luaL_Reg* api; int metaref; } lovrVectorInfo[] = { - [V_VEC2] = { 2, "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL }, - [V_VEC3] = { 3, "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL }, - [V_VEC4] = { 4, "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL }, - [V_QUAT] = { 4, "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL }, - [V_MAT4] = { 16, "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL } +static struct { size_t components; const char* name; lua_CFunction metacall, metaindex; const luaL_Reg* api; int metaref, poolref, cursor; } lovrVectorInfo[] = { + [V_VEC2] = { 2, "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL, LUA_REFNIL, 1 }, + [V_VEC3] = { 3, "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL, LUA_REFNIL, 1 }, + [V_VEC4] = { 4, "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL, LUA_REFNIL, 1 }, + [V_QUAT] = { 4, "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL, LUA_REFNIL, 1 }, + [V_MAT4] = { 16, "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL, LUA_REFNIL, 1 } }; float* luax_tovector(lua_State* L, int index, int* type) { @@ -61,12 +61,34 @@ float* luax_checkvector(lua_State* L, int index, int type, const char* expected) return p; } +static bool pushed; + float* luax_newvector(lua_State* L, int type) { - void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); - *((int*) p) = type; - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); - lua_setmetatable(L, -2); - return (float*) ((char*) p + sizeof(int)); + if (pushed) { + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].poolref); + lua_rawgeti(L, -1, lovrVectorInfo[type].cursor); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); + *((int*) p) = type; + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); + lua_setmetatable(L, -2); + lua_pushvalue(L, -1); + lua_rawseti(L, -3, lovrVectorInfo[type].cursor++); + lua_remove(L, -2); + return (float*) ((char*) p + sizeof(int)); + } else { + lua_remove(L, -2); + lovrVectorInfo[type].cursor++; + return (float*) ((char*) lua_topointer(L, -1) + sizeof(int)); + } + } else { + void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); + *((int*) p) = type; + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); + lua_setmetatable(L, -2); + return (float*) ((char*) p + sizeof(int)); + } } static int l_lovrMathNewCurve(lua_State* L) { @@ -251,6 +273,19 @@ static int l_lovrMathMat4(lua_State* L) { return l_lovrMat4Set(L); } +static int l_lovrMathPush(lua_State* L) { + for (int i = V_VEC2; i <= V_MAT4; i++) { + lovrVectorInfo[i].cursor = 1; + } + pushed = true; + return 0; +} + +static int l_lovrMathPop(lua_State* L) { + pushed = false; + return 0; +} + static const luaL_Reg lovrMath[] = { { "newCurve", l_lovrMathNewCurve }, { "newRandomGenerator", l_lovrMathNewRandomGenerator }, @@ -266,6 +301,8 @@ static const luaL_Reg lovrMath[] = { { "newVec4", l_lovrMathNewVec4 }, { "newQuat", l_lovrMathNewQuat }, { "newMat4", l_lovrMathNewMat4 }, + { "push", l_lovrMathPush }, + { "pop", l_lovrMathPop }, { NULL, NULL } }; @@ -295,6 +332,17 @@ int luaopen_lovr_math(lua_State* L) { luax_register(L, lovrVectorInfo[i].api); lovrVectorInfo[i].metaref = luaL_ref(L, LUA_REGISTRYINDEX); + + // pool + lua_newtable(L); + + // __mode = v + lua_newtable(L); + lua_pushliteral(L, "v"); + lua_setfield(L, -2, "__mode"); + lua_setmetatable(L, -2); + + lovrVectorInfo[i].poolref = luaL_ref(L, LUA_REGISTRYINDEX); } // Module From a30a00818b7e17c897c9be27c789bf464d99cb6a Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 24 Dec 2023 13:25:59 -0800 Subject: [PATCH 3/6] No need to check for userdata type in __index; --- src/api/l_math_vectors.c | 80 ++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/src/api/l_math_vectors.c b/src/api/l_math_vectors.c index 5e5d873b..c50c0cdc 100644 --- a/src/api/l_math_vectors.c +++ b/src/api/l_math_vectors.c @@ -423,15 +423,13 @@ static int l_lovrVec2__newindex(lua_State* L) { } static int l_lovrVec2__index(lua_State* L) { - if (lua_type(L, 1) == LUA_TUSERDATA) { - lua_getmetatable(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - return 1; - } else { - lua_pop(L, 2); - } + lua_getmetatable(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + return 1; + } else { + lua_pop(L, 2); } float* v = luax_checkvector(L, 1, V_VEC2, NULL); @@ -815,15 +813,13 @@ static int l_lovrVec3__newindex(lua_State* L) { } static int l_lovrVec3__index(lua_State* L) { - if (lua_type(L, 1) == LUA_TUSERDATA) { - lua_getmetatable(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - return 1; - } else { - lua_pop(L, 2); - } + lua_getmetatable(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + return 1; + } else { + lua_pop(L, 2); } float* v = luax_checkvector(L, 1, V_VEC3, NULL); @@ -1212,15 +1208,13 @@ static int l_lovrVec4__newindex(lua_State* L) { } static int l_lovrVec4__index(lua_State* L) { - if (lua_type(L, 1) == LUA_TUSERDATA) { - lua_getmetatable(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - return 1; - } else { - lua_pop(L, 2); - } + lua_getmetatable(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + return 1; + } else { + lua_pop(L, 2); } float* v = luax_checkvector(L, 1, V_VEC4, NULL); @@ -1527,15 +1521,13 @@ static int l_lovrQuat__newindex(lua_State* L) { } static int l_lovrQuat__index(lua_State* L) { - if (lua_type(L, 1) == LUA_TUSERDATA) { - lua_getmetatable(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - return 1; - } else { - lua_pop(L, 2); - } + lua_getmetatable(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + return 1; + } else { + lua_pop(L, 2); } float* q = luax_checkvector(L, 1, V_QUAT, NULL); @@ -1986,15 +1978,13 @@ static int l_lovrMat4__newindex(lua_State* L) { } static int l_lovrMat4__index(lua_State* L) { - if (lua_type(L, 1) == LUA_TUSERDATA) { - lua_getmetatable(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - if (!lua_isnil(L, -1)) { - return 1; - } else { - lua_pop(L, 2); - } + lua_getmetatable(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + return 1; + } else { + lua_pop(L, 2); } float* m = luax_checkvector(L, 1, V_MAT4, NULL); From e0a7d442d052a85a2bff3e03f8cbee2a22cd5f1a Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 19 Jan 2024 18:33:30 -0800 Subject: [PATCH 4/6] Vector stack supports nesting and has error messages; --- src/api/l_math.c | 84 ++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/src/api/l_math.c b/src/api/l_math.c index 2308ab77..3fa855e3 100644 --- a/src/api/l_math.c +++ b/src/api/l_math.c @@ -31,12 +31,28 @@ extern const luaL_Reg lovrVec4[]; extern const luaL_Reg lovrQuat[]; extern const luaL_Reg lovrMat4[]; -static struct { size_t components; const char* name; lua_CFunction metacall, metaindex; const luaL_Reg* api; int metaref, poolref, cursor; } lovrVectorInfo[] = { - [V_VEC2] = { 2, "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL, LUA_REFNIL, 1 }, - [V_VEC3] = { 3, "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL, LUA_REFNIL, 1 }, - [V_VEC4] = { 4, "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL, LUA_REFNIL, 1 }, - [V_QUAT] = { 4, "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL, LUA_REFNIL, 1 }, - [V_MAT4] = { 16, "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL, LUA_REFNIL, 1 } +#define VECTOR_STACK_MAX 16 + +typedef struct { + size_t components; + const char* name; + lua_CFunction metacall; + lua_CFunction metaindex; + const luaL_Reg* api; + int metatableRef; + int poolRef; + int poolCursor; + int stackPointers[VECTOR_STACK_MAX]; +} VectorInfo; + +static uint32_t stackIndex; + +static VectorInfo lovrVectorInfo[] = { + [V_VEC2] = { 2, "vec2", l_lovrMathVec2, l_lovrVec2__metaindex, lovrVec2, LUA_REFNIL, LUA_REFNIL, 1, { 0 } }, + [V_VEC3] = { 3, "vec3", l_lovrMathVec3, l_lovrVec3__metaindex, lovrVec3, LUA_REFNIL, LUA_REFNIL, 1, { 0 } }, + [V_VEC4] = { 4, "vec4", l_lovrMathVec4, l_lovrVec4__metaindex, lovrVec4, LUA_REFNIL, LUA_REFNIL, 1, { 0 } }, + [V_QUAT] = { 4, "quat", l_lovrMathQuat, l_lovrQuat__metaindex, lovrQuat, LUA_REFNIL, LUA_REFNIL, 1, { 0 } }, + [V_MAT4] = { 16, "mat4", l_lovrMathMat4, l_lovrMat4__metaindex, lovrMat4, LUA_REFNIL, LUA_REFNIL, 1, { 0 } } }; float* luax_tovector(lua_State* L, int index, int* type) { @@ -61,34 +77,31 @@ float* luax_checkvector(lua_State* L, int index, int type, const char* expected) return p; } -static bool pushed; - float* luax_newvector(lua_State* L, int type) { - if (pushed) { - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].poolref); - lua_rawgeti(L, -1, lovrVectorInfo[type].cursor); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); - *((int*) p) = type; - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); - lua_setmetatable(L, -2); - lua_pushvalue(L, -1); - lua_rawseti(L, -3, lovrVectorInfo[type].cursor++); + if (stackIndex > 0) { + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].poolRef); + lua_rawgeti(L, -1, lovrVectorInfo[type].poolCursor); + if (!lua_isnil(L, -1)) { lua_remove(L, -2); - return (float*) ((char*) p + sizeof(int)); - } else { - lua_remove(L, -2); - lovrVectorInfo[type].cursor++; + lovrVectorInfo[type].poolCursor++; return (float*) ((char*) lua_topointer(L, -1) + sizeof(int)); + } else { + lua_pop(L, 1); } - } else { - void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); - *((int*) p) = type; - lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref); - lua_setmetatable(L, -2); - return (float*) ((char*) p + sizeof(int)); } + + void* p = lua_newuserdata(L, sizeof(int) + lovrVectorInfo[type].components * sizeof(float)); + *((int*) p) = type; + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metatableRef); + lua_setmetatable(L, -2); + + if (stackIndex > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, -3, lovrVectorInfo[type].poolCursor++); + lua_remove(L, -2); + } + + return (float*) ((char*) p + sizeof(int)); } static int l_lovrMathNewCurve(lua_State* L) { @@ -275,14 +288,17 @@ static int l_lovrMathMat4(lua_State* L) { static int l_lovrMathPush(lua_State* L) { for (int i = V_VEC2; i <= V_MAT4; i++) { - lovrVectorInfo[i].cursor = 1; + lovrVectorInfo[i].stackPointers[stackIndex] = lovrVectorInfo[i].poolCursor; } - pushed = true; + lovrAssert(++stackIndex < VECTOR_STACK_MAX, "Vector stack overflow (more pushes than pops?)"); return 0; } static int l_lovrMathPop(lua_State* L) { - pushed = false; + lovrAssert(--stackIndex >= 0, "Vector stack underflow (more pops than pushes?)"); + for (int i = V_VEC2; i <= V_MAT4; i++) { + lovrVectorInfo[i].poolCursor = lovrVectorInfo[i].stackPointers[stackIndex]; + } return 0; } @@ -331,7 +347,7 @@ int luaopen_lovr_math(lua_State* L) { lua_settable(L, -4); luax_register(L, lovrVectorInfo[i].api); - lovrVectorInfo[i].metaref = luaL_ref(L, LUA_REGISTRYINDEX); + lovrVectorInfo[i].metatableRef = luaL_ref(L, LUA_REGISTRYINDEX); // pool lua_newtable(L); @@ -342,7 +358,7 @@ int luaopen_lovr_math(lua_State* L) { lua_setfield(L, -2, "__mode"); lua_setmetatable(L, -2); - lovrVectorInfo[i].poolref = luaL_ref(L, LUA_REGISTRYINDEX); + lovrVectorInfo[i].poolRef = luaL_ref(L, LUA_REGISTRYINDEX); } // Module From 072f712ef11cae453e1a99044353ec46ec9a8f3b Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 19 Jan 2024 18:38:46 -0800 Subject: [PATCH 5/6] rm add/sub/mul/div mutating methods; --- src/api/l_math_vectors.c | 200 ++++----------------------------------- 1 file changed, 20 insertions(+), 180 deletions(-) diff --git a/src/api/l_math_vectors.c b/src/api/l_math_vectors.c index c50c0cdc..41240e5e 100644 --- a/src/api/l_math_vectors.c +++ b/src/api/l_math_vectors.c @@ -209,42 +209,6 @@ int l_lovrVec2Set(lua_State* L) { return 1; } -static int l_lovrVec2Add(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC2, NULL); - float u[2]; - luax_readvec2(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC2); - vec2_add(vec2_init(out, v), u); - return 1; -} - -static int l_lovrVec2Sub(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC2, NULL); - float u[2]; - luax_readvec2(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC2); - vec2_sub(vec2_init(out, v), u); - return 1; -} - -static int l_lovrVec2Mul(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC2, NULL); - float u[2]; - luax_readvec2(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC2); - vec2_mul(vec2_init(out, v), u); - return 1; -} - -static int l_lovrVec2Div(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC2, NULL); - float u[2]; - luax_readvec2(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC2); - vec2_div(vec2_init(out, v), u); - return 1; -} - static int l_lovrVec2Length(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC2, NULL); lua_pushnumber(L, vec2_length(v)); @@ -504,10 +468,6 @@ const luaL_Reg lovrVec2[] = { { "equals", l_lovrVec2Equals }, { "unpack", l_lovrVec2Unpack }, { "set", l_lovrVec2Set }, - { "add", l_lovrVec2Add }, - { "sub", l_lovrVec2Sub }, - { "mul", l_lovrVec2Mul }, - { "div", l_lovrVec2Div }, { "length", l_lovrVec2Length }, { "normalize", l_lovrVec2Normalize }, { "distance", l_lovrVec2Distance }, @@ -570,42 +530,6 @@ int l_lovrVec3Set(lua_State* L) { return 1; } -static int l_lovrVec3Add(lua_State* L) { - vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - float u[3]; - luax_readvec3(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC3); - vec3_add(vec3_init(out, v), u); - return 1; -} - -static int l_lovrVec3Sub(lua_State* L) { - vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - float u[3]; - luax_readvec3(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC3); - vec3_sub(vec3_init(out, v), u); - return 1; -} - -static int l_lovrVec3Mul(lua_State* L) { - vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - float u[3]; - luax_readvec3(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC3); - vec3_mul(vec3_init(out, v), u); - return 1; -} - -static int l_lovrVec3Div(lua_State* L) { - vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); - float u[3]; - luax_readvec3(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC3); - vec3_div(vec3_init(out, v), u); - return 1; -} - static int l_lovrVec3Length(lua_State* L) { vec3 v = luax_checkvector(L, 1, V_VEC3, NULL); lua_pushnumber(L, vec3_length(v)); @@ -899,10 +823,6 @@ const luaL_Reg lovrVec3[] = { { "equals", l_lovrVec3Equals }, { "unpack", l_lovrVec3Unpack }, { "set", l_lovrVec3Set }, - { "add", l_lovrVec3Add }, - { "sub", l_lovrVec3Sub }, - { "mul", l_lovrVec3Mul }, - { "div", l_lovrVec3Div }, { "length", l_lovrVec3Length }, { "normalize", l_lovrVec3Normalize }, { "distance", l_lovrVec3Distance }, @@ -956,42 +876,6 @@ int l_lovrVec4Set(lua_State* L) { return 1; } -static int l_lovrVec4Add(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC4, NULL); - float u[4]; - luax_readvec4(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC4); - vec4_add(vec4_init(out, v), u); - return 1; -} - -static int l_lovrVec4Sub(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC4, NULL); - float u[4]; - luax_readvec4(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC4); - vec4_sub(vec4_init(out, v), u); - return 1; -} - -static int l_lovrVec4Mul(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC4, NULL); - float u[4]; - luax_readvec4(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC4); - vec4_mul(vec4_init(out, v), u); - return 1; -} - -static int l_lovrVec4Div(lua_State* L) { - float* v = luax_checkvector(L, 1, V_VEC4, NULL); - float u[4]; - luax_readvec4(L, 2, u, NULL); - float* out = luax_newvector(L, V_VEC4); - vec4_div(vec4_init(out, v), u); - return 1; -} - static int l_lovrVec4Length(lua_State* L) { float* v = luax_checkvector(L, 1, V_VEC4, NULL); lua_pushnumber(L, vec4_length(v)); @@ -1291,10 +1175,6 @@ const luaL_Reg lovrVec4[] = { { "equals", l_lovrVec4Equals }, { "unpack", l_lovrVec4Unpack }, { "set", l_lovrVec4Set }, - { "add", l_lovrVec4Add }, - { "sub", l_lovrVec4Sub }, - { "mul", l_lovrVec4Mul }, - { "div", l_lovrVec4Div }, { "length", l_lovrVec4Length }, { "normalize", l_lovrVec4Normalize }, { "distance", l_lovrVec4Distance }, @@ -1389,29 +1269,6 @@ int l_lovrQuatSet(lua_State* L) { return 1; } -static int l_lovrQuatMul(lua_State* L) { - quat q = luax_checkvector(L, 1, V_QUAT, NULL); - int type; - float* r = luax_tovector(L, 2, &type); - if (r && type == V_VEC3) { - vec3 v = luax_newvector(L, V_VEC3); - quat_rotate(q, vec3_init(v, r)); - } else if (r && type == V_QUAT) { - float* out = luax_newvector(L, V_QUAT); - quat_mul(out, q, r); - } else if (lua_type(L, 2) == LUA_TNUMBER) { - lua_settop(L, 4); - vec3 v = luax_newvector(L, V_VEC3); - v[0] = luax_tofloat(L, 2); - v[1] = luax_checkfloat(L, 3); - v[2] = luax_checkfloat(L, 4); - quat_rotate(q, v); - } else { - return luax_typeerror(L, 2, "number, vec3, or quat"); - } - return 1; -} - static int l_lovrQuatLength(lua_State* L) { quat q = luax_checkvector(L, 1, V_QUAT, NULL); lua_pushnumber(L, quat_length(q)); @@ -1581,7 +1438,6 @@ const luaL_Reg lovrQuat[] = { { "equals", l_lovrQuatEquals }, { "unpack", l_lovrQuatUnpack }, { "set", l_lovrQuatSet }, - { "mul", l_lovrQuatMul }, { "length", l_lovrQuatLength }, { "normalize", l_lovrQuatNormalize }, { "direction", l_lovrQuatDirection }, @@ -1757,39 +1613,6 @@ int l_lovrMat4Set(lua_State* L) { return 1; } -static int l_lovrMat4Mul(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - int type; - float* n = luax_tovector(L, 2, &type); - if (n && type == V_MAT4) { - float* out = luax_newvector(L, V_MAT4); - mat4_mul(mat4_init(out, m), n); - } else if (n && type == V_VEC3) { - vec3 v = luax_newvector(L, V_VEC3); - mat4_mulPoint(m, vec3_init(v, n)); - } else if (n && type == V_VEC4) { - vec4 v = luax_newvector(L, V_VEC4); - mat4_mulVec4(m, vec4_init(v, n)); - } else if (lua_type(L, 2) == LUA_TNUMBER) { - lua_settop(L, 4); - vec3 v = luax_newvector(L, V_VEC3); - v[0] = luax_tofloat(L, 2); - v[1] = luax_checkfloat(L, 3); - v[2] = luax_checkfloat(L, 4); - mat4_mulPoint(m, v); - } else { - return luax_typeerror(L, 2, "mat4, vec3, vec4, or number"); - } - return 1; -} - -static int l_lovrMat4Identity(lua_State* L) { - mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); - float* out = luax_newvector(L, V_MAT4); - mat4_identity(mat4_init(out, m)); - return 1; -} - static int l_lovrMat4Invert(lua_State* L) { mat4 m = luax_checkvector(L, 1, V_MAT4, NULL); float* out = luax_newvector(L, V_MAT4); @@ -2002,7 +1825,26 @@ static int l_lovrMat4__index(lua_State* L) { } int l_lovrMat4__metaindex(lua_State* L) { - return 0; // No properties currently, 'identity' is already taken + if (lua_type(L, 2) != LUA_TSTRING) { + return 0; + } + + size_t length; + const char* key = lua_tolstring(L, 2, &length); + + static struct { StringEntry name; float m[16]; } properties[] = { + { ENTRY("identity"), MAT4_IDENTITY } + }; + + for (uint32_t i = 0; i < COUNTOF(properties); i++) { + if (length == properties[i].name.length && !memcmp(key, properties[i].name.string, length)) { + float* m = luax_newvector(L, V_MAT4); + mat4_set(m, properties[i].m); + return 1; + } + } + + return 0; } const luaL_Reg lovrMat4[] = { @@ -2014,8 +1856,6 @@ const luaL_Reg lovrMat4[] = { { "getScale", l_lovrMat4GetScale }, { "getPose", l_lovrMat4GetPose }, { "set", l_lovrMat4Set }, - { "mul", l_lovrMat4Mul }, - { "identity", l_lovrMat4Identity }, { "invert", l_lovrMat4Invert }, { "transpose", l_lovrMat4Transpose }, { "translate", l_lovrMat4Translate }, From f9f627c7107e66a36b5432ff1531eba8776cc8af Mon Sep 17 00:00:00 2001 From: bjorn Date: Sat, 20 Jan 2024 16:48:03 -0800 Subject: [PATCH 6/6] rm unused Pool struct; --- src/modules/math/math.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/modules/math/math.c b/src/modules/math/math.c index 5f453bb9..7f29a9d8 100644 --- a/src/modules/math/math.c +++ b/src/modules/math/math.c @@ -16,14 +16,6 @@ struct Curve { arr_t(float) points; }; -struct Pool { - uint32_t ref; - float* data; - uint32_t count; - uint32_t cursor; - uint32_t generation; -}; - struct RandomGenerator { uint32_t ref; Seed seed;