diff options
-rw-r--r-- | demo/Node.lua | 5 | ||||
-rw-r--r-- | demo/main.lua | 11 | ||||
-rw-r--r-- | src/glm_bindings.c | 219 | ||||
-rw-r--r-- | src/glm_bindings.h | 12 | ||||
-rw-r--r-- | src/glm_mat3_bindings.c | 9 | ||||
-rw-r--r-- | src/glm_mat4_bindings.c | 37 | ||||
-rw-r--r-- | src/glm_vec3_bindings.c | 9 | ||||
-rw-r--r-- | src/glm_vec4_bindings.c | 9 | ||||
-rw-r--r-- | src/honey_lua.c | 2 |
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)) |