Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table Vectors #789

Open
wants to merge 28 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
57b43f8
WIP;
bjornbytes May 11, 2024
e5cb811
vec2;
bjornbytes May 12, 2024
70f80b9
vec4;
bjornbytes May 12, 2024
da2818d
vec3;
bjornbytes May 14, 2024
40e2d2b
quat;
bjornbytes Jun 6, 2024
cdf6063
Mat4;
bjornbytes Jun 7, 2024
c6971ee
Fix newMaterial;
bjornbytes Jun 7, 2024
a85936b
Fix luax_readmat4;
bjornbytes Jun 7, 2024
bef9ea3
Add lovr.math.mat4 for compatibility;
bjornbytes Jun 7, 2024
4a249b8
Fix sending Mat4 to Buffer data;
bjornbytes Jun 7, 2024
d709e85
Vector metamethod uses rawget/rawset;
bjornbytes Jun 8, 2024
d941e55
Mat4 methods that return vec4 set metatable;
bjornbytes Jun 8, 2024
bcf0421
Fix -2 scale components;
bjornbytes Jun 8, 2024
d1ea3d7
Use helpers for quat multiplication;
bjornbytes Jun 10, 2024
6ef4e26
Details;
bjornbytes Jun 10, 2024
3fcccd3
Pass:points/Pass:line work with table vectors;
bjornbytes Jun 16, 2024
39b4b81
Fix Buffer:setData error messages;
bjornbytes Jun 16, 2024
326b0d2
Make readscale consume 1 arg when nil;
bjornbytes Jun 16, 2024
19bb936
luax_readmat4 uses mat4_fromPose;
bjornbytes Jun 16, 2024
2af1b07
rm some unused maf methods;
bjornbytes Jun 16, 2024
dc508c4
Clean up vector constructors;
bjornbytes Jun 16, 2024
5eafd30
Mat4 is a plain userdata instead of a refcounted object;
bjornbytes Jun 17, 2024
f4bb0c4
Details;
bjornbytes Jun 17, 2024
3fb293d
Details;
bjornbytes Jun 20, 2024
98f4c24
quat:direction returns vec3;
bjornbytes Jun 21, 2024
73025ca
Add vec3:transform/rotate;
bjornbytes Jun 21, 2024
9da77e9
Adjust __index/__newindex;
bjornbytes Jun 21, 2024
ce14955
Add limited swizzling;
bjornbytes Jun 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ if(LOVR_ENABLE_MATH)
src/api/l_math.c
src/api/l_math_curve.c
src/api/l_math_randomGenerator.c
src/api/l_math_vectors.c
src/api/l_math_mat4.c
src/lib/noise/simplexnoise1234.c
)
else()
Expand Down Expand Up @@ -629,7 +629,7 @@ if(NOT EMSCRIPTEN)
endif()

# Resources
file(GLOB LOVR_RESOURCES "etc/*.ttf" "etc/*.lua" "etc/shaders/*.glsl")
file(GLOB LOVR_RESOURCES "etc/*.ttf" "etc/*.lua" "etc/shaders/*.glsl" "src/api/l_math.lua")
foreach(path ${LOVR_RESOURCES})

# Turn the absolute path into a C variable like etc_boot_lua
Expand Down
2 changes: 1 addition & 1 deletion Tupfile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ src += config.modules.thread and 'src/core/job.c' or nil

-- embed resource files with xxd

res = { 'etc/boot.lua', 'etc/*.ttf', 'etc/shaders/*.glsl' }
res = { 'etc/boot.lua', 'etc/*.ttf', 'etc/shaders/*.glsl', 'src/api/l_math.lua' }
tup.foreach_rule(res, '^ XD %b^ xxd -i %f > %o', '%f.h')

for i, pattern in ipairs(res) do
Expand Down
3 changes: 0 additions & 3 deletions etc/boot.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -273,8 +272,6 @@ function lovr.errhand(message)
lovr.graphics.present()
end
end

lovr.math.drain()
end
end

Expand Down
155 changes: 140 additions & 15 deletions src/api/api.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "api.h"
#include "core/maf.h"
#include "math/math.h"
#include "util.h"
#include "lib/lua/lutf8lib.h"
#include <stdlib.h>
Expand Down Expand Up @@ -489,7 +491,7 @@ void luax_readcolor(lua_State* L, int index, float color[4]) {
}
}

// Like readcolor, but only consumes 1 argument (nil, hex, table, vec3, vec4), useful for table keys
// Like readcolor, but only consumes 1 argument (nil, hex, table), useful for table keys
void luax_optcolor(lua_State* L, int index, float color[4]) {
switch (lua_type(L, index)) {
case LUA_TNONE:
Expand All @@ -515,20 +517,7 @@ void luax_optcolor(lua_State* L, int index, float color[4]) {
color[3] = luax_optfloat(L, -1, 1.);
lua_pop(L, 4);
break;
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA: {
VectorType type;
float* v = luax_tovector(L, index, &type);
if (type == V_VEC3) {
memcpy(color, v, 3 * sizeof(float));
color[3] = 1.f;
break;
} else if (type == V_VEC4) {
memcpy(color, v, 4 * sizeof(float));
break;
}
} /* fallthrough */
default: lovrThrow("Expected nil, number, table, vec3, or vec4 for color value");
default: lovrThrow("Expected nil, number, or table for color value");
}
}

Expand Down Expand Up @@ -613,3 +602,139 @@ int luax_readmesh(lua_State* L, int index, float** vertices, uint32_t* vertexCou
#endif
return 0;
}

int luax_pushvec3(lua_State* L, float* v) {
lua_createtable(L, 3, 0);
lua_pushnumber(L, v[0]);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, v[1]);
lua_rawseti(L, -2, 2);
lua_pushnumber(L, v[2]);
lua_rawseti(L, -2, 3);
luaL_newmetatable(L, "Vec3");
return lua_setmetatable(L, -2);
}

int luax_readvec3(lua_State* L, int index, vec3 v, const char* expected) {
switch (lua_type(L, index)) {
case LUA_TNIL:
case LUA_TNONE:
v[0] = v[1] = v[2] = 0.f;
return index + 1;
case LUA_TNUMBER:
v[0] = luax_tofloat(L, index);
v[1] = luax_optfloat(L, index + 1, v[0]);
v[2] = luax_optfloat(L, index + 2, v[0]);
return index + 3;
case LUA_TTABLE:
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, index, i + 1);
v[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
}
return index + 1;
default: return luax_typeerror(L, index, "number or table");
}
}

int luax_readscale(lua_State* L, int index, vec3 v, int components, const char* expected) {
switch (lua_type(L, index)) {
case LUA_TNIL:
case LUA_TNONE:
v[0] = v[1] = v[2] = 1.f;
return index + 1;
case LUA_TNUMBER:
if (components == 1) {
v[0] = v[1] = v[2] = luax_tofloat(L, index);
} else if (components == -2) { // -2 is special and means "2 components: xy and z"
v[0] = v[1] = luax_tofloat(L, index);
v[2] = luax_optfloat(L, index, 1.f);
return index + 2;
} else {
v[0] = v[1] = v[2] = 1.f;
for (int i = 0; i < components; i++) {
v[i] = luax_optfloat(L, index + i, v[0]);
}
}
return index + components;
case LUA_TTABLE:
v[0] = 1.f;
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, index, i + 1);
v[i] = luax_optfloat(L, -1, v[0]);
lua_pop(L, 1);
}
return index + 1;
default: return luax_typeerror(L, index, "number or table");
}
}

int luax_readquat(lua_State* L, int index, quat q, const char* expected) {
float angle, ax, ay, az;
switch (lua_type(L, index)) {
case LUA_TNIL:
case LUA_TNONE:
quat_identity(q);
return index + 1;
case LUA_TNUMBER:
angle = luax_optfloat(L, index, 0.f);
ax = luax_optfloat(L, index + 1, 0.f);
ay = luax_optfloat(L, index + 2, 1.f);
az = luax_optfloat(L, index + 3, 0.f);
quat_fromAngleAxis(q, angle, ax, ay, az);
return index + 4;
case LUA_TTABLE:
for (int i = 0; i < 4; i++) {
lua_rawgeti(L, index, i + 1);
q[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
}
return index + 1;
default: return luax_typeerror(L, index, "number or table");
}
}

float* luax_newmat4(lua_State* L) {
float* p = lua_newuserdata(L, 4 * 4 * sizeof(float));
luaL_newmetatable(L, "Mat4");
lua_setmetatable(L, -2);
return p;
}

bool luax_ismat4(lua_State* L, int index) {
return lua_type(L, index) == LUA_TUSERDATA && luax_len(L, index) == 64;
}

float* luax_checkmat4(lua_State* L, int index) {
if (luax_ismat4(L, index)) {
return lua_touserdata(L, index);
} else {
luax_typeerror(L, index, "Mat4");
return NULL;
}
}

int luax_readmat4(lua_State* L, int index, mat4 m, int scaleComponents) {
switch (lua_type(L, index)) {
case LUA_TNIL:
case LUA_TNONE:
mat4_identity(m);
return index + 1;
case LUA_TNUMBER:
case LUA_TTABLE: {
float T[3], R[4], S[3];
index = luax_readvec3(L, index, T, "number, table, or Mat4");
index = luax_readscale(L, index, S, scaleComponents, NULL);
index = luax_readquat(L, index, R, NULL);
mat4_fromPose(m, T, R);
mat4_scale(m, S[0], S[1], S[2]);
return index;
}
default:
if (luax_ismat4(L, index)) {
mat4_init(m, lua_touserdata(L, index));
return index + 1;
}
return luax_typeerror(L, index, "number, table, or Mat4");
}
}
20 changes: 9 additions & 11 deletions src/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ uint32_t _luax_optu32(lua_State* L, int index, uint32_t fallback);
void luax_readcolor(lua_State* L, int index, float color[4]);
void luax_optcolor(lua_State* L, int index, float color[4]);
int luax_readmesh(lua_State* L, int index, float** vertices, uint32_t* vertexCount, uint32_t** indices, uint32_t* indexCount, bool* shouldFree);
int luax_pushvec3(lua_State* L, float* v);
int luax_readvec3(lua_State* L, int index, float* v, const char* expected);
int luax_readscale(lua_State* L, int index, float* v, int components, const char* expected);
int luax_readquat(lua_State* L, int index, float* q, const char* expected);
float* luax_newmat4(lua_State* L);
bool luax_ismat4(lua_State* L, int index);
float* luax_checkmat4(lua_State* L, int index);
int luax_readmat4(lua_State* L, int index, float* m, int scaleComponents);

// Module helpers

Expand Down Expand Up @@ -163,7 +171,7 @@ bool luax_writefile(const char* filename, const void* data, size_t size);
struct DataField;
struct Material;
struct ColoredString;
void luax_checkbufferdata(lua_State* L, int index, const struct DataField* format, char* data);
void luax_checkbufferdata(lua_State* L, int index, const struct DataField* format, char* data, bool single);
int luax_pushbufferdata(lua_State* L, const struct DataField* format, uint32_t count, char* data);
void luax_pushbufferformat(lua_State* L, const struct DataField* fields, uint32_t count);
int luax_gettablestride(lua_State* L, int type);
Expand All @@ -173,16 +181,6 @@ 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);
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);
int luax_readscale(lua_State* L, int index, float* v, int components, const char* expected);
int luax_readquat(lua_State* L, int index, float* q, const char* expected);
int luax_readmat4(lua_State* L, int index, float* m, int scaleComponents);
uint64_t luax_checkrandomseed(lua_State* L, int index);
#endif

Expand Down
41 changes: 14 additions & 27 deletions src/api/l_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) {
}

case LUA_TUSERDATA:
if (luax_ismat4(L, index)) {
variant->type = TYPE_MATRIX;
variant->value.matrix.data = lovrMalloc(64);
memcpy(variant->value.matrix.data, lua_touserdata(L, index), 64);
break;
}

variant->type = TYPE_OBJECT;
Proxy* proxy = lua_touserdata(L, index);
lua_getmetatable(L, index);
Expand All @@ -83,32 +90,13 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) {
lua_pop(L, 1);
break;
} else {
lua_pop(L, 2);
}
/* fallthrough */

case LUA_TLIGHTUSERDATA: {
VectorType type;
float* v = luax_tovector(L, index, &type);
if (v) {
if (type == V_MAT4) {
variant->type = TYPE_MATRIX;
variant->value.matrix.data = lovrMalloc(16 * sizeof(float));
memcpy(variant->value.matrix.data, v, 16 * sizeof(float));
break;
} else {
variant->type = TYPE_VECTOR;
variant->value.vector.type = type;
memcpy(variant->value.vector.data, v, (type == V_VEC2 ? 2 : 4) * sizeof(float));
break;
}
} else if (lua_type(L, index) == LUA_TLIGHTUSERDATA) {
variant->type = TYPE_POINTER;
variant->value.pointer = lua_touserdata(L, index);
break;
lovrThrow("Variant userdata is not a LÖVR object!");
}
lovrThrow("Bad userdata variant for argument %d (expected object, vector, or lightuserdata)", index);
}

case LUA_TLIGHTUSERDATA:
variant->type = TYPE_POINTER;
variant->value.pointer = lua_touserdata(L, index);
break;

default:
lovrThrow("Bad variant type for argument %d: %s", index, lua_typename(L, type));
Expand All @@ -125,8 +113,7 @@ 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_MATRIX: memcpy(luax_newmat4(L), variant->value.matrix.data, 64); return 1;
default: return 0;
}
}
Expand Down
22 changes: 8 additions & 14 deletions src/api/l_graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,12 +736,12 @@ static int l_lovrGraphicsNewBuffer(lua_State* L) {
info.size = (uint32_t) blob->size;
format->length = info.size / format->stride;
break;
} else if (luax_tovector(L, 2, NULL)) {
} else if (luax_ismat4(L, 2)) {
format->length = 0;
hasData = true;
break;
}
return luax_typeerror(L, 2, "nil, number, vector, table, or Blob");
return luax_typeerror(L, 2, "nil, number, table, Mat4, or Blob");
}
}
}
Expand All @@ -753,7 +753,7 @@ static int l_lovrGraphicsNewBuffer(lua_State* L) {
if (blob) {
memcpy(data, blob->data, info.size);
} else if (hasData) {
luax_checkbufferdata(L, 2, format, data);
luax_checkbufferdata(L, 2, format, data, true);
}

luax_pushtype(L, Buffer, buffer);
Expand Down Expand Up @@ -1208,16 +1208,13 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
float shift = lua_tonumber(L, -1);
info.data.uvShift[0] = shift;
info.data.uvShift[1] = shift;
} else if (lua_type(L, -1) == LUA_TTABLE) {
} else if (!lua_isnil(L, -1)) {
lovrCheck(lua_istable(L, -1), "Expected number or table for uvShift");
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
info.data.uvShift[0] = luax_optfloat(L, -2, 0.f);
info.data.uvShift[1] = luax_optfloat(L, -1, 0.f);
lua_pop(L, 2);
} else if (!lua_isnil(L, -1)) {
float* v = luax_checkvector(L, -1, V_VEC2, "vec2, table, or nil");
info.data.uvShift[0] = v[0];
info.data.uvShift[1] = v[1];
}
lua_pop(L, 1);

Expand All @@ -1229,16 +1226,13 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
float scale = lua_tonumber(L, -1);
info.data.uvScale[0] = scale;
info.data.uvScale[1] = scale;
} else if (lua_type(L, -1) == LUA_TTABLE) {
} else {
lovrCheck(lua_istable(L, -1), "Expected number or table for uvScale");
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
info.data.uvScale[0] = luax_optfloat(L, -2, 1.f);
info.data.uvScale[1] = luax_optfloat(L, -1, 1.f);
lua_pop(L, 2);
} else {
float* v = luax_checkvector(L, -1, V_VEC2, "vec2, table, or nil");
info.data.uvScale[0] = v[0];
info.data.uvScale[1] = v[1];
}
lua_pop(L, 1);

Expand Down Expand Up @@ -1435,7 +1429,7 @@ static int l_lovrGraphicsNewMesh(lua_State* L) {
if (blob) {
memcpy(vertices, blob->data, blob->size);
} else if (hasData) {
luax_checkbufferdata(L, index, lovrMeshGetVertexFormat(mesh), vertices);
luax_checkbufferdata(L, index, lovrMeshGetVertexFormat(mesh), vertices, true);
}

luax_pushtype(L, Mesh, mesh);
Expand Down
Loading
Loading