summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demo/Node.lua5
-rw-r--r--demo/main.lua11
-rw-r--r--src/glm_bindings.c219
-rw-r--r--src/glm_bindings.h12
-rw-r--r--src/glm_mat3_bindings.c9
-rw-r--r--src/glm_mat4_bindings.c37
-rw-r--r--src/glm_vec3_bindings.c9
-rw-r--r--src/glm_vec4_bindings.c9
-rw-r--r--src/honey_lua.c2
9 files changed, 269 insertions, 44 deletions
diff --git a/demo/Node.lua b/demo/Node.lua
index 300679c..5af745b 100644
--- a/demo/Node.lua
+++ b/demo/Node.lua
@@ -6,7 +6,7 @@ local Node = {}
Node.prototype = {}
Node.prototype.updateTransform = function(self)
- honey.cglm.mat4.identity(self.transform.array)
+ self.transform:eye()
self.transform:translate(self.position)
@@ -87,7 +87,8 @@ Node.new = function(parent, position, rotation, scale)
parent.children[index + 1] = node
end
- node.transform = Matrix.Mat4.eye()
+ node.transform = honey.glm.mat4()
+ node.transform:eye()
node:updateTransform()
return node
diff --git a/demo/main.lua b/demo/main.lua
index ec5746a..3fabe00 100644
--- a/demo/main.lua
+++ b/demo/main.lua
@@ -1,3 +1,12 @@
-local v = honey.glm.vec3()
+local v = honey.glm.vec3{1, 2, 3}
+
+local M = honey.glm.mat3()
+M:set(1,3, 1)
+
+print(M:mulv(v))
+
+print(v)
+print(honey.glm.vec3{2, 0.001, 0})
+print(honey.glm.vec4{100, 0, 0, 20.44})
v.dot(v, v)
diff --git a/src/glm_bindings.c b/src/glm_bindings.c
index b9652b5..173e2eb 100644
--- a/src/glm_bindings.c
+++ b/src/glm_bindings.c
@@ -9,8 +9,10 @@ void honey_setup_glm(lua_State* L)
{
/* vec3 metatable */
honey_lua_create_table
- (L, 2,
- HONEY_TABLE, "__index", 21,
+ (L, 3,
+ HONEY_TABLE, "__index", 23,
+ HONEY_FUNCTION, "get", honey_glm_array_vec_get,
+ HONEY_FUNCTION, "set", honey_glm_array_vec_set,
HONEY_FUNCTION, "copyTo", honey_glm_vec3_copy,
HONEY_FUNCTION, "zero", honey_glm_vec3_zero,
HONEY_FUNCTION, "eye", honey_glm_vec3_eye,
@@ -33,6 +35,7 @@ void honey_setup_glm(lua_State* L)
HONEY_FUNCTION, "clamp", honey_glm_vec3_clamp,
HONEY_FUNCTION, "lerpTo", honey_glm_vec3_lerp,
+ HONEY_FUNCTION, "__tostring", honey_glm_vector_to_string,
HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
honey_glm_vec3_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
@@ -40,8 +43,10 @@ void honey_setup_glm(lua_State* L)
/* vec4 metatable */
honey_lua_create_table
- (L, 2,
- HONEY_TABLE, "__index", 18,
+ (L, 3,
+ HONEY_TABLE, "__index", 20,
+ HONEY_FUNCTION, "get", honey_glm_array_vec_get,
+ HONEY_FUNCTION, "set", honey_glm_array_vec_set,
HONEY_FUNCTION, "copyTo", honey_glm_vec4_copy,
HONEY_FUNCTION, "zero", honey_glm_vec4_zero,
HONEY_FUNCTION, "eye", honey_glm_vec4_eye,
@@ -60,16 +65,19 @@ void honey_setup_glm(lua_State* L)
HONEY_FUNCTION, "normalize", honey_glm_vec4_normalize,
HONEY_FUNCTION, "clamp", honey_glm_vec4_clamp,
HONEY_FUNCTION, "lerpTo", honey_glm_vec4_lerp,
-
+
+ HONEY_FUNCTION, "__tostring", honey_glm_vector_to_string,
HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
honey_glm_vec4_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
/* mat3 metatable */
honey_lua_create_table
- (L, 2,
+ (L, 3,
- HONEY_TABLE, "__index", 9,
+ HONEY_TABLE, "__index", 11,
+ HONEY_FUNCTION, "get", honey_glm_array_mat_get,
+ HONEY_FUNCTION, "set", honey_glm_array_mat_set,
HONEY_FUNCTION, "copyTo", honey_glm_mat3_copy,
HONEY_FUNCTION, "eye", honey_glm_mat3_eye,
HONEY_FUNCTION, "zero", honey_glm_mat3_zero,
@@ -80,15 +88,19 @@ void honey_setup_glm(lua_State* L)
HONEY_FUNCTION, "det", honey_glm_mat3_det,
HONEY_FUNCTION, "inv", honey_glm_mat3_inv,
+ HONEY_FUNCTION, "__tostring", honey_glm_matrix_to_string,
+
HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
honey_glm_mat3_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
/* mat4 metatable */
honey_lua_create_table
- (L, 2,
+ (L, 3,
- HONEY_TABLE, "__index", 22,
- HONEY_FUNCTION, "copy", honey_glm_mat4_copy,
+ HONEY_TABLE, "__index", 24,
+ HONEY_FUNCTION, "get", honey_glm_array_mat_get,
+ HONEY_FUNCTION, "set", honey_glm_array_mat_set,
+ HONEY_FUNCTION, "copyTo", honey_glm_mat4_copy,
HONEY_FUNCTION, "eye", honey_glm_mat4_eye,
HONEY_FUNCTION, "zero", honey_glm_mat4_zero,
HONEY_FUNCTION, "mul", honey_glm_mat4_mul,
@@ -111,6 +123,8 @@ void honey_setup_glm(lua_State* L)
HONEY_FUNCTION, "lookAt", honey_glm_lookat,
HONEY_FUNCTION, "look", honey_glm_look,
+ HONEY_FUNCTION, "__tostring", honey_glm_matrix_to_string,
+
HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
honey_glm_mat4_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
@@ -133,7 +147,8 @@ void honey_setup_glm(lua_State* L)
static void setup_new_array(lua_State* L,
honey_glm_array* array,
- honey_glm_array_type type)
+ honey_glm_array_type type,
+ int choice)
{
unsigned int size;
switch(type) {
@@ -167,14 +182,49 @@ static void setup_new_array(lua_State* L,
honey_lua_throw_error(L,
"failed to allocate memory for array of type %d",
type);
+
+ if (choice == 1) {
+ size_t length = lua_objlen(L, 1);
+ if (length != size)
+ honey_lua_throw_error
+ (L, "initialization table must contain %d elements; got %d elements instead",
+ size, length);
+
+ for (int i=0; i<size; i++) {
+ lua_rawgeti(L, 1, i+1);
+ if (!lua_isnumber(L, -1))
+ honey_lua_throw_error(L, "initialization table must contain only numbers");
+ array->data[i] = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static int glm_matrix_dim(honey_glm_array_type type)
+{
+ switch (type) {
+ case MAT3:
+ return 3;
+
+ case MAT4:
+ return 4;
+
+ default:
+ return 0;
+ }
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int honey_glm_new_vec3(lua_State* L)
{
+ int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE);
+
honey_glm_array* vec3 = lua_newuserdata(L, sizeof(honey_glm_array));
- setup_new_array(L, vec3, VEC3);
+ setup_new_array(L, vec3, VEC3, choice);
+
lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_vec3_mt_ref);
lua_setmetatable(L, -2);
return 1;
@@ -182,8 +232,9 @@ int honey_glm_new_vec3(lua_State* L)
int honey_glm_new_vec4(lua_State* L)
{
+ int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE);
honey_glm_array* vec4 = lua_newuserdata(L, sizeof(honey_glm_array));
- setup_new_array(L, vec4, VEC4);
+ setup_new_array(L, vec4, VEC4, choice);
lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_vec4_mt_ref);
lua_setmetatable(L, -2);
return 1;
@@ -191,8 +242,9 @@ int honey_glm_new_vec4(lua_State* L)
int honey_glm_new_mat3(lua_State* L)
{
+ int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE);
honey_glm_array* mat3 = lua_newuserdata(L, sizeof(honey_glm_array));
- setup_new_array(L, mat3, MAT3);
+ setup_new_array(L, mat3, MAT3, choice);
lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_mat3_mt_ref);
lua_setmetatable(L, -2);
return 1;
@@ -200,8 +252,9 @@ int honey_glm_new_mat3(lua_State* L)
int honey_glm_new_mat4(lua_State* L)
{
+ int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE);
honey_glm_array* mat4 = lua_newuserdata(L, sizeof(honey_glm_array));
- setup_new_array(L, mat4, MAT4);
+ setup_new_array(L, mat4, MAT4, choice);
lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_mat4_mt_ref);
lua_setmetatable(L, -2);
return 1;
@@ -209,10 +262,146 @@ int honey_glm_new_mat4(lua_State* L)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+int honey_glm_array_vec_get(lua_State* L)
+{
+ honey_glm_array* self;
+ int index;
+ honey_lua_parse_arguments
+ (L, 1, 2, HONEY_USERDATA, &self, HONEY_INTEGER, &index);
+
+ if (index < 0 || index >= self->size)
+ honey_lua_throw_error(L, "index %d is out of range", index);
+
+ lua_pushnumber(L, self->data[index]);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_array_vec_set(lua_State* L)
+{
+ honey_glm_array* self;
+ int index;
+ float value;
+ honey_lua_parse_arguments
+ (L, 1, 3, HONEY_USERDATA, &self, HONEY_INTEGER, &index, HONEY_NUMBER, &value);
+
+ if (index < 0 || index >= self->size)
+ honey_lua_throw_error(L, "index %d is out of range", index);
+
+ self->data[index] = value;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_array_mat_set(lua_State* L)
+{
+ honey_glm_array* self;
+ int column, row;
+ float value;
+ honey_lua_parse_arguments
+ (L, 1, 4,
+ HONEY_USERDATA, &self,
+ HONEY_INTEGER, &row,
+ HONEY_INTEGER, &column,
+ HONEY_NUMBER, &value);
+
+ int dim = glm_matrix_dim(self->type);
+
+ int index = (row - 1) + dim * (column - 1);
+ self->data[index] = value;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_array_mat_get(lua_State* L)
+{
+ honey_glm_array* self;
+ int column, row;
+ float value;
+ honey_lua_parse_arguments
+ (L, 1, 3,
+ HONEY_USERDATA, &self,
+ HONEY_INTEGER, &row,
+ HONEY_INTEGER, &column);
+
+ int dim = glm_matrix_dim(self->type);
+
+ int index = (row - 1) + dim * (column - 1);
+ lua_pushnumber(L, self->data[index]);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vector_to_string(lua_State* L)
+{
+ honey_glm_array* self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+
+ char string[256];
+ string[0] = '['; string[1] = ' '; string[2] = 0;
+ int index = 2;
+ for (int i=0; i<self->size; i++) {
+ index += snprintf(string + index, 256-index, "%7.3f ", self->data[i]);
+ if (i != self->size-1) {
+ string[index] = ' ';
+ index++;
+ }
+ }
+
+ snprintf(string + index, 256-index, "]");
+
+ lua_pushstring(L, string);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_matrix_to_string(lua_State* L)
+{
+ honey_glm_array* self;
+ int column, row;
+ float value;
+ honey_lua_parse_arguments
+ (L, 1, 1, HONEY_USERDATA, &self);
+
+ int dim = glm_matrix_dim(self->type);
+
+ char string[512];
+ string[0] = 0;
+ int index = 0;
+
+ for (int row=0; row<dim; row++) {
+ if (row == 0)
+ index += snprintf(string+index, 512-index, "/ ");
+ else if (row == dim-1)
+ index += snprintf(string+index, 512-index, "\\ ");
+ else
+ index += snprintf(string+index, 512-index, "| ");
+ for (int col=0; col<dim; col++)
+ index += snprintf(string+index, 512-index, "%7.3f ", self->data[row + dim*col]);
+ if (row == 0)
+ index += snprintf(string+index, 512-index, "\\\n");
+ else if (row == dim-1)
+ index += snprintf(string+index, 512-index, "/\n");
+ else
+ index += snprintf(string+index, 512-index, "|\n");
+ }
+
+ lua_pushstring(L, string);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
int honey_glm_array_destroy(lua_State* L)
{
honey_glm_array* array;
honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &array);
+ printf("DESTROY GLM ARRAY %d", array->type);
free(array->data);
return 0;
}
diff --git a/src/glm_bindings.h b/src/glm_bindings.h
index 6c1898f..1b86de2 100644
--- a/src/glm_bindings.h
+++ b/src/glm_bindings.h
@@ -26,6 +26,18 @@ int honey_glm_new_mat3(lua_State* L);
int honey_glm_new_mat4(lua_State* L);
+int honey_glm_array_vec_get(lua_State* L);
+
+int honey_glm_array_vec_set(lua_State* L);
+
+int honey_glm_array_mat_get(lua_State* L);
+
+int honey_glm_array_mat_set(lua_State* L);
+
+int honey_glm_vector_to_string(lua_State* L);
+
+int honey_glm_matrix_to_string(lua_State* L);
+
int honey_glm_array_destroy(lua_State* L);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/glm_mat3_bindings.c b/src/glm_mat3_bindings.c
index 0222e47..a789cce 100644
--- a/src/glm_mat3_bindings.c
+++ b/src/glm_mat3_bindings.c
@@ -71,7 +71,8 @@ int honey_glm_mat3_mul(lua_State* L)
MAT3, dest->type);
}
else {
- honey_glm_new_mat3(L);
+ lua_pushcfunction(L, honey_glm_new_mat3);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
@@ -122,7 +123,8 @@ int honey_glm_mat3_mulv(lua_State* L)
VEC3, v->type);
if (choice == 0) {
- honey_glm_new_vec3(L);
+ lua_pushcfunction(L, honey_glm_new_vec3);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
else {
@@ -177,7 +179,8 @@ int honey_glm_mat3_inv(lua_State* L)
2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
if (choice == 0) {
- honey_glm_new_mat3(L);
+ lua_pushcfunction(L, honey_glm_new_mat3);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
else {
diff --git a/src/glm_mat4_bindings.c b/src/glm_mat4_bindings.c
index 460cde2..b082a4b 100644
--- a/src/glm_mat4_bindings.c
+++ b/src/glm_mat4_bindings.c
@@ -71,7 +71,8 @@ int honey_glm_mat4_mul(lua_State* L)
MAT4, dest->type);
}
else {
- honey_glm_new_mat4(L);
+ lua_pushcfunction(L, honey_glm_new_mat4);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
@@ -122,7 +123,8 @@ int honey_glm_mat4_mulv(lua_State* L)
VEC4, v->type);
if (choice == 0) {
- honey_glm_new_vec4(L);
+ lua_pushcfunction(L, honey_glm_new_vec4);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
else {
@@ -177,7 +179,8 @@ int honey_glm_mat4_inv(lua_State* L)
2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
if (choice == 0) {
- honey_glm_new_mat4(L);
+ lua_pushcfunction(L, honey_glm_new_mat4);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
else {
@@ -211,8 +214,8 @@ int honey_glm_translate(lua_State* L)
if (v->type != VEC3)
honey_lua_throw_error
- (L, "translation vector must be of type VEC3 (%d); got %d instead",
- VEC3, v->type);
+ (L, "translation vector must be of type VEC3 (%d); got %d instead",
+ VEC3, v->type);
if (choice == 0) {
glm_translate(self->data, v->data);
@@ -286,9 +289,9 @@ int honey_glm_scalev(lua_State* L)
glm_scale(self->data, v->data);
else {
if (dest->type != MAT4)
- honey_lua_throw_error
- (L, "destination matrix must be of type MAT4 (%d); got %d instead",
- MAT4, dest->type);
+ honey_lua_throw_error
+ (L, "destination matrix must be of type MAT4 (%d); got %d instead",
+ MAT4, dest->type);
glm_scale_to(self->data, v->data, dest->data);
}
@@ -311,9 +314,9 @@ int honey_glm_rotate_x(lua_State* L)
dest = self;
else {
if (dest->type != MAT4)
- honey_lua_throw_error
- (L, "destination matrix must be of type MAT4 (%d); got %d instead",
- MAT4, dest->type);
+ honey_lua_throw_error
+ (L, "destination matrix must be of type MAT4 (%d); got %d instead",
+ MAT4, dest->type);
}
glm_rotate_x(self->data, angle, dest->data);
@@ -336,9 +339,9 @@ int honey_glm_rotate_y(lua_State* L)
dest = self;
else {
if (dest->type != MAT4)
- honey_lua_throw_error
- (L, "destination matrix must be of type MAT4 (%d); got %d instead",
- MAT4, dest->type);
+ honey_lua_throw_error
+ (L, "destination matrix must be of type MAT4 (%d); got %d instead",
+ MAT4, dest->type);
}
glm_rotate_y(self->data, angle, dest->data);
@@ -361,9 +364,9 @@ int honey_glm_rotate_z(lua_State* L)
dest = self;
else {
if (dest->type != MAT4)
- honey_lua_throw_error
- (L, "destination matrix must be of type MAT4 (%d); got %d instead",
- MAT4, dest->type);
+ honey_lua_throw_error
+ (L, "destination matrix must be of type MAT4 (%d); got %d instead",
+ MAT4, dest->type);
}
glm_rotate_z(self->data, angle, dest->data);
diff --git a/src/glm_vec3_bindings.c b/src/glm_vec3_bindings.c
index 774bab0..a8157f2 100644
--- a/src/glm_vec3_bindings.c
+++ b/src/glm_vec3_bindings.c
@@ -88,7 +88,8 @@ static bool get_vec3_arrays(lua_State* L,
VEC3, (*dest)->type);
}
else {
- honey_glm_new_vec3(L);
+ lua_pushcfunction(L, honey_glm_new_vec3);
+ honey_lua_pcall(L, 0, 1);
*dest = lua_touserdata(L, -1);
}
@@ -114,7 +115,8 @@ static bool get_vec3_scalars(lua_State* L,
VEC3, (*dest)->type);
}
else {
- honey_glm_new_vec3(L);
+ lua_pushcfunction(L, honey_glm_new_vec3);
+ honey_lua_pcall(L, 0, 1);
*dest = lua_touserdata(L, -1);
}
@@ -378,7 +380,8 @@ int honey_glm_vec3_lerp(lua_State* L)
VEC3, dest->type);
}
else {
- honey_glm_new_vec3(L);
+ lua_pushcfunction(L, honey_glm_new_vec3);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
diff --git a/src/glm_vec4_bindings.c b/src/glm_vec4_bindings.c
index 878473f..0a18c5b 100644
--- a/src/glm_vec4_bindings.c
+++ b/src/glm_vec4_bindings.c
@@ -88,7 +88,8 @@ static bool get_vec4_arrays(lua_State* L,
VEC4, (*dest)->type);
}
else {
- honey_glm_new_vec4(L);
+ lua_pushcfunction(L, honey_glm_new_vec4);
+ honey_lua_pcall(L, 0, 1);
*dest = lua_touserdata(L, -1);
}
@@ -114,7 +115,8 @@ static bool get_vec4_scalars(lua_State* L,
VEC4, (*dest)->type);
}
else {
- honey_glm_new_vec4(L);
+ lua_pushcfunction(L, honey_glm_new_vec4);
+ honey_lua_pcall(L, 0, 1);
*dest = lua_touserdata(L, -1);
}
@@ -331,7 +333,8 @@ int honey_glm_vec4_lerp(lua_State* L)
VEC4, dest->type);
}
else {
- honey_glm_new_vec4(L);
+ lua_pushcfunction(L, honey_glm_new_vec4);
+ honey_lua_pcall(L, 0, 1);
dest = lua_touserdata(L, -1);
}
diff --git a/src/honey_lua.c b/src/honey_lua.c
index 72624be..f3ca0a5 100644
--- a/src/honey_lua.c
+++ b/src/honey_lua.c
@@ -102,6 +102,8 @@ void honey_lua_throw_error(lua_State* L,
static bool check_arg_list(lua_State* L,
struct argument_list arg_list)
{
+ if (arg_list.length != lua_gettop(L))
+ return false;
struct argument_pair* args = arg_list.args;
for (int i=0; i<arg_list.length; i++) {
if (!check_argument(L, args[i].type, i+1))