mirror of https://github.com/bjornbytes/lovr.git
Compare commits
8 Commits
9237514a1e
...
be21b145ff
Author | SHA1 | Date |
---|---|---|
Bjorn | be21b145ff | |
bjorn | aa79822edb | |
bjorn | f9f627c710 | |
bjorn | 072f712ef1 | |
bjorn | e0a7d442d0 | |
bjorn | a30a00818b | |
bjorn | c7d4801ba2 | |
bjorn | cc426d0453 |
|
@ -177,7 +177,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
|
||||
|
||||
|
@ -273,8 +272,6 @@ function lovr.errhand(message)
|
|||
lovr.graphics.present()
|
||||
end
|
||||
end
|
||||
|
||||
lovr.math.drain()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -177,10 +177,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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
@ -870,7 +870,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.);
|
||||
|
|
213
src/api/l_math.c
213
src/api/l_math.c
|
@ -31,36 +31,38 @@ extern const luaL_Reg lovrVec4[];
|
|||
extern const luaL_Reg lovrQuat[];
|
||||
extern const luaL_Reg lovrMat4[];
|
||||
|
||||
static LOVR_THREAD_LOCAL Pool* pool;
|
||||
#define VECTOR_STACK_MAX 16
|
||||
|
||||
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 }
|
||||
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 } }
|
||||
};
|
||||
|
||||
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 +70,38 @@ 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;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lovrVectorInfo[type].metaref);
|
||||
lua_setmetatable(L, -2);
|
||||
return (float*) (p + 1);
|
||||
}
|
||||
float* luax_newvector(lua_State* L, int type) {
|
||||
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);
|
||||
lovrVectorInfo[type].poolCursor++;
|
||||
return (float*) ((char*) lua_topointer(L, -1) + sizeof(int));
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
float* luax_newtempvector(lua_State* L, VectorType type) {
|
||||
float* data;
|
||||
Vector vector = lovrPoolAllocate(pool, type, &data);
|
||||
lua_pushlightuserdata(L, vector.pointer);
|
||||
return data;
|
||||
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) {
|
||||
|
@ -213,67 +227,78 @@ 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);
|
||||
static int l_lovrMathPush(lua_State* L) {
|
||||
for (int i = V_VEC2; i <= V_MAT4; i++) {
|
||||
lovrVectorInfo[i].stackPointers[stackIndex] = lovrVectorInfo[i].poolCursor;
|
||||
}
|
||||
lovrAssert(++stackIndex < VECTOR_STACK_MAX, "Vector stack overflow (more pushes than pops?)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrMathPop(lua_State* L) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -292,71 +317,24 @@ static const luaL_Reg lovrMath[] = {
|
|||
{ "newVec4", l_lovrMathNewVec4 },
|
||||
{ "newQuat", l_lovrMathNewQuat },
|
||||
{ "newMat4", l_lovrMathNewMat4 },
|
||||
{ "drain", l_lovrMathDrain },
|
||||
{ "push", l_lovrMathPush },
|
||||
{ "pop", l_lovrMathPop },
|
||||
{ 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);
|
||||
|
||||
|
@ -369,31 +347,24 @@ 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);
|
||||
|
||||
// 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]);
|
||||
// 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);
|
||||
}
|
||||
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 +372,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);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "api.h"
|
||||
#include "math/math.h"
|
||||
#include "util.h"
|
||||
|
||||
static int l_lovrCurveEvaluate(lua_State* L) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "api.h"
|
||||
#include "math/math.h"
|
||||
#include "util.h"
|
||||
#include <math.h>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
vec2_add(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec2_sub(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec2_mul(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec2_div(v, u);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec2Length(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC2, NULL);
|
||||
lua_pushnumber(L, vec2_length(v));
|
||||
|
@ -253,8 +217,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 +243,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 +257,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 +277,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 +297,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 +317,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 +338,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;
|
||||
}
|
||||
|
@ -423,15 +387,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);
|
||||
|
@ -451,18 +413,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 +453,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;
|
||||
|
@ -506,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 },
|
||||
|
@ -556,7 +514,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);
|
||||
|
@ -572,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);
|
||||
vec3_add(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec3_sub(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec3_mul(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec3_div(v, u);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec3Length(lua_State* L) {
|
||||
vec3 v = luax_checkvector(L, 1, V_VEC3, NULL);
|
||||
lua_pushnumber(L, vec3_length(v));
|
||||
|
@ -616,8 +538,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 +563,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 +573,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 +590,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 +599,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 +627,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 +649,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 +665,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 +682,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;
|
||||
}
|
||||
|
@ -815,15 +737,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);
|
||||
|
@ -843,18 +763,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 +809,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;
|
||||
}
|
||||
|
@ -903,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 },
|
||||
|
@ -960,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);
|
||||
vec4_add(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec4_sub(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec4_mul(v, u);
|
||||
lua_settop(L, 1);
|
||||
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);
|
||||
vec4_div(v, u);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Length(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
lua_pushnumber(L, vec4_length(v));
|
||||
|
@ -1004,7 +884,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 +911,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 +928,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 +958,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 +982,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 +1006,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 +1031,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;
|
||||
}
|
||||
|
@ -1211,15 +1092,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);
|
||||
|
@ -1239,18 +1118,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 +1158,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;
|
||||
|
@ -1296,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 },
|
||||
|
@ -1370,7 +1245,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");
|
||||
|
||||
|
@ -1394,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);
|
||||
VectorType type;
|
||||
float* r = luax_tovector(L, 2, &type);
|
||||
if (r && type == V_VEC3) {
|
||||
vec3 v = luax_newtempvector(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);
|
||||
} else if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
lua_settop(L, 4);
|
||||
vec3 v = luax_newtempvector(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));
|
||||
|
@ -1425,22 +1277,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 +1300,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 +1327,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;
|
||||
|
@ -1526,15 +1378,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);
|
||||
|
@ -1574,7 +1424,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;
|
||||
}
|
||||
|
@ -1588,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 },
|
||||
|
@ -1714,7 +1563,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);
|
||||
|
@ -1764,74 +1613,50 @@ int l_lovrMat4Set(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrMat4Mul(lua_State* L) {
|
||||
mat4 m = luax_checkvector(L, 1, V_MAT4, NULL);
|
||||
VectorType type;
|
||||
float* n = luax_tovector(L, 2, &type);
|
||||
if (n && type == V_MAT4) {
|
||||
mat4_mul(m, n);
|
||||
lua_settop(L, 1);
|
||||
} else if (n && type == V_VEC3) {
|
||||
vec3 v = luax_newtempvector(L, V_VEC3);
|
||||
mat4_mulPoint(m, vec3_init(v, n));
|
||||
} else if (n && type == V_VEC4) {
|
||||
vec4 v = luax_newtempvector(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);
|
||||
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);
|
||||
mat4_identity(m);
|
||||
lua_settop(L, 1);
|
||||
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 +1664,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 +1692,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 {
|
||||
|
@ -1971,15 +1801,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);
|
||||
|
@ -1997,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[] = {
|
||||
|
@ -2009,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 },
|
||||
|
|
|
@ -373,6 +373,7 @@ typedef struct {
|
|||
uint64_t hash;
|
||||
uint32_t start;
|
||||
uint32_t baseVertex;
|
||||
uint32_t vertexBufferOffset;
|
||||
gpu_buffer* vertexBuffer;
|
||||
gpu_buffer* indexBuffer;
|
||||
} CachedShape;
|
||||
|
@ -479,6 +480,7 @@ typedef struct {
|
|||
gpu_buffer* vertexBuffer;
|
||||
gpu_buffer* indexBuffer;
|
||||
gpu_buffer* uniformBuffer;
|
||||
uint32_t vertexBufferOffset;
|
||||
uint32_t uniformOffset;
|
||||
union {
|
||||
struct {
|
||||
|
@ -1388,6 +1390,7 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
|||
gpu_bundle* bundle = NULL;
|
||||
Material* material = NULL;
|
||||
gpu_buffer* vertexBuffer = NULL;
|
||||
uint32_t vertexBufferOffset = 0;
|
||||
gpu_buffer* indexBuffer = NULL;
|
||||
gpu_buffer* uniformBuffer = NULL;
|
||||
uint32_t uniformOffset = 0;
|
||||
|
@ -1440,9 +1443,10 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
|||
uniformOffset = draw->uniformOffset;
|
||||
}
|
||||
|
||||
if (draw->vertexBuffer && draw->vertexBuffer != vertexBuffer) {
|
||||
gpu_bind_vertex_buffers(stream, &draw->vertexBuffer, NULL, 0, 1);
|
||||
if (draw->vertexBuffer && (draw->vertexBuffer != vertexBuffer || draw->vertexBufferOffset != vertexBufferOffset)) {
|
||||
gpu_bind_vertex_buffers(stream, &draw->vertexBuffer, &draw->vertexBufferOffset, 0, 1);
|
||||
vertexBuffer = draw->vertexBuffer;
|
||||
vertexBufferOffset = draw->vertexBufferOffset;
|
||||
}
|
||||
|
||||
if (draw->indexBuffer && draw->indexBuffer != indexBuffer) {
|
||||
|
@ -1451,8 +1455,8 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
|||
indexBuffer = draw->indexBuffer;
|
||||
}
|
||||
|
||||
uint32_t drawId = i & 0xff;
|
||||
gpu_push_constants(stream, draw->shader->gpu, &drawId, sizeof(drawId));
|
||||
uint32_t DrawID = i & 0xff;
|
||||
gpu_push_constants(stream, draw->shader->gpu, &DrawID, sizeof(DrawID));
|
||||
|
||||
if (draw->flags & DRAW_INDIRECT) {
|
||||
if (draw->indexBuffer) {
|
||||
|
@ -6017,6 +6021,7 @@ static void lovrPassResolveVertices(Pass* pass, DrawInfo* info, Draw* draw) {
|
|||
draw->indexBuffer = cached->indexBuffer;
|
||||
draw->start = cached->start;
|
||||
draw->baseVertex = cached->baseVertex;
|
||||
draw->vertexBufferOffset = cached->vertexBufferOffset;
|
||||
*info->vertex.pointer = NULL;
|
||||
*info->index.pointer = NULL;
|
||||
return;
|
||||
|
@ -6028,24 +6033,17 @@ static void lovrPassResolveVertices(Pass* pass, DrawInfo* info, Draw* draw) {
|
|||
BufferView view = lovrPassGetBuffer(pass, info->vertex.count * stride, stride);
|
||||
*info->vertex.pointer = view.pointer;
|
||||
draw->vertexBuffer = view.buffer;
|
||||
if (info->index.buffer || info->index.count > 0) {
|
||||
draw->baseVertex = view.offset / stride;
|
||||
} else {
|
||||
draw->start = view.offset / stride;
|
||||
}
|
||||
draw->vertexBufferOffset = view.offset;
|
||||
} else if (info->vertex.buffer) {
|
||||
Buffer* buffer = info->vertex.buffer;
|
||||
uint32_t stride = buffer->info.format->stride;
|
||||
lovrCheck(stride <= state.limits.vertexBufferStride, "Vertex buffer stride exceeds vertexBufferStride limit");
|
||||
trackBuffer(pass, buffer, GPU_PHASE_INPUT_VERTEX, GPU_CACHE_VERTEX);
|
||||
draw->vertexBuffer = buffer->gpu;
|
||||
if (info->index.buffer || info->index.count > 0) {
|
||||
draw->baseVertex += buffer->base / stride;
|
||||
} else {
|
||||
draw->start += buffer->base / stride;
|
||||
}
|
||||
draw->vertexBufferOffset = buffer->base;
|
||||
} else {
|
||||
draw->vertexBuffer = state.defaultBuffer->gpu;
|
||||
draw->vertexBufferOffset = state.defaultBuffer->base;
|
||||
}
|
||||
|
||||
if (!info->index.buffer && info->index.count > 0) {
|
||||
|
@ -6068,6 +6066,7 @@ static void lovrPassResolveVertices(Pass* pass, DrawInfo* info, Draw* draw) {
|
|||
cached->indexBuffer = draw->indexBuffer;
|
||||
cached->start = draw->start;
|
||||
cached->baseVertex = draw->baseVertex;
|
||||
cached->vertexBufferOffset = draw->vertexBufferOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -216,70 +208,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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue