summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glm_bindings.c90
-rw-r--r--src/glm_bindings.h102
-rw-r--r--src/glm_vec3_bindings.c390
-rw-r--r--src/glm_vec4_bindings.c343
-rw-r--r--src/honey.c1
5 files changed, 919 insertions, 7 deletions
diff --git a/src/glm_bindings.c b/src/glm_bindings.c
index 9fdd7f2..1eb3df1 100644
--- a/src/glm_bindings.c
+++ b/src/glm_bindings.c
@@ -7,12 +7,77 @@ int honey_glm_mat4_mt_ref = LUA_NOREF;
void honey_setup_glm(lua_State* L)
{
- lua_pushnil(L);
+ /* vec3 metatable */
+ honey_lua_create_table
+ (L, 2,
+ HONEY_TABLE, "__index", 21,
+ HONEY_FUNCTION, "copyTo", honey_glm_vec3_copy,
+ HONEY_FUNCTION, "zero", honey_glm_vec3_zero,
+ HONEY_FUNCTION, "eye", honey_glm_vec3_eye,
+ HONEY_FUNCTION, "dot", honey_glm_vec3_dot,
+ HONEY_FUNCTION, "cross", honey_glm_vec3_cross,
+ HONEY_FUNCTION, "crossn", honey_glm_vec3_crossn,
+ HONEY_FUNCTION, "norm2", honey_glm_vec3_norm2,
+ HONEY_FUNCTION, "norm", honey_glm_vec3_norm,
+ HONEY_FUNCTION, "add", honey_glm_vec3_add,
+ HONEY_FUNCTION, "adds", honey_glm_vec3_adds,
+ HONEY_FUNCTION, "sub", honey_glm_vec3_sub,
+ HONEY_FUNCTION, "subs", honey_glm_vec3_subs,
+ HONEY_FUNCTION, "mul", honey_glm_vec3_mul,
+ HONEY_FUNCTION, "scale", honey_glm_vec3_scale,
+ HONEY_FUNCTION, "scaleAs", honey_glm_vec3_scale_as,
+ HONEY_FUNCTION, "div", honey_glm_vec3_div,
+ HONEY_FUNCTION, "negate", honey_glm_vec3_negate,
+ HONEY_FUNCTION, "normalize", honey_glm_vec3_normalize,
+ HONEY_FUNCTION, "angleTo", honey_glm_vec3_angle,
+ HONEY_FUNCTION, "clamp", honey_glm_vec3_clamp,
+ HONEY_FUNCTION, "lerpTo", honey_glm_vec3_lerp,
+
+
+ HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
+ honey_glm_vec3_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+
+ /* vec4 metatable */
+ honey_lua_create_table
+ (L, 2,
+ HONEY_TABLE, "__index", 18,
+ HONEY_FUNCTION, "copyTo", honey_glm_vec4_copy,
+ HONEY_FUNCTION, "zero", honey_glm_vec4_zero,
+ HONEY_FUNCTION, "eye", honey_glm_vec4_eye,
+ HONEY_FUNCTION, "dot", honey_glm_vec4_dot,
+ HONEY_FUNCTION, "norm2", honey_glm_vec4_norm2,
+ HONEY_FUNCTION, "norm", honey_glm_vec4_norm,
+ HONEY_FUNCTION, "add", honey_glm_vec4_add,
+ HONEY_FUNCTION, "adds", honey_glm_vec4_adds,
+ HONEY_FUNCTION, "sub", honey_glm_vec4_sub,
+ HONEY_FUNCTION, "subs", honey_glm_vec4_subs,
+ HONEY_FUNCTION, "mul", honey_glm_vec4_mul,
+ HONEY_FUNCTION, "scale", honey_glm_vec4_scale,
+ HONEY_FUNCTION, "scaleAs", honey_glm_vec4_scale_as,
+ HONEY_FUNCTION, "div", honey_glm_vec4_div,
+ HONEY_FUNCTION, "negate", honey_glm_vec4_negate,
+ HONEY_FUNCTION, "normalize", honey_glm_vec4_normalize,
+ HONEY_FUNCTION, "clamp", honey_glm_vec4_clamp,
+ HONEY_FUNCTION, "lerpTo", honey_glm_vec4_lerp,
+
+
+ HONEY_FUNCTION, "__gc", honey_glm_array_destroy);
+ honey_glm_vec4_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ /* glm table */
+ honey_lua_create_table
+ (L, 4,
+ HONEY_FUNCTION, "vec3", honey_glm_new_vec3,
+ HONEY_FUNCTION, "vec4", honey_glm_new_vec4,
+ HONEY_FUNCTION, "mat3", honey_glm_new_mat3,
+ HONEY_FUNCTION, "mat4", honey_glm_new_mat4);
+ lua_setfield(L, -2, "glm");
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
- * GLM Array Setup Functions
+ * GLM Array Basic Functions
*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@@ -57,7 +122,7 @@ static void setup_new_array(lua_State* L,
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-static int honey_glm_new_vec3(lua_State* L)
+int honey_glm_new_vec3(lua_State* L)
{
honey_glm_array* vec3 = lua_newuserdata(L, sizeof(honey_glm_array));
setup_new_array(L, vec3, VEC3);
@@ -66,7 +131,7 @@ static int honey_glm_new_vec3(lua_State* L)
return 1;
}
-static int honey_glm_new_vec4(lua_State* L)
+int honey_glm_new_vec4(lua_State* L)
{
honey_glm_array* vec4 = lua_newuserdata(L, sizeof(honey_glm_array));
setup_new_array(L, vec4, VEC4);
@@ -75,7 +140,7 @@ static int honey_glm_new_vec4(lua_State* L)
return 1;
}
-static int honey_glm_new_mat3(lua_State* L)
+int honey_glm_new_mat3(lua_State* L)
{
honey_glm_array* mat3 = lua_newuserdata(L, sizeof(honey_glm_array));
setup_new_array(L, mat3, MAT3);
@@ -84,7 +149,7 @@ static int honey_glm_new_mat3(lua_State* L)
return 1;
}
-static int honey_glm_new_mat4(lua_State* L)
+int honey_glm_new_mat4(lua_State* L)
{
honey_glm_array* mat4 = lua_newuserdata(L, sizeof(honey_glm_array));
setup_new_array(L, mat4, MAT4);
@@ -92,3 +157,16 @@ static int honey_glm_new_mat4(lua_State* L)
lua_setmetatable(L, -2);
return 1;
}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_array_destroy(lua_State* L)
+{
+ honey_glm_array* array;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &array);
+ free(array->data);
+ return 0;
+}
+
+
+
diff --git a/src/glm_bindings.h b/src/glm_bindings.h
index f6ec104..45424ee 100644
--- a/src/glm_bindings.h
+++ b/src/glm_bindings.h
@@ -18,4 +18,106 @@ extern int honey_glm_mat4_mt_ref;
*/
void honey_setup_glm(lua_State* L);
+int honey_glm_new_vec3(lua_State* L);
+
+int honey_glm_new_vec4(lua_State* L);
+
+int honey_glm_new_mat3(lua_State* L);
+
+int honey_glm_new_mat4(lua_State* L);
+
+int honey_glm_array_destroy(lua_State* L);
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Vec3 Functions
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+int honey_glm_vec3_copy(lua_State* L);
+
+int honey_glm_vec3_zero(lua_State* L);
+
+int honey_glm_vec3_eye(lua_State* L);
+
+int honey_glm_vec3_dot(lua_State* L);
+
+int honey_glm_vec3_cross(lua_State* L);
+
+int honey_glm_vec3_crossn(lua_State* L);
+
+int honey_glm_vec3_norm2(lua_State* L);
+
+int honey_glm_vec3_norm(lua_State* L);
+
+int honey_glm_vec3_add(lua_State* L);
+
+int honey_glm_vec3_adds(lua_State* L);
+
+int honey_glm_vec3_sub(lua_State* L);
+
+int honey_glm_vec3_subs(lua_State* L);
+
+int honey_glm_vec3_mul(lua_State* L);
+
+int honey_glm_vec3_scale(lua_State* L);
+
+int honey_glm_vec3_scale_as(lua_State* L);
+
+int honey_glm_vec3_div(lua_State* L);
+
+int honey_glm_vec3_negate(lua_State* L);
+
+int honey_glm_vec3_normalize(lua_State* L);
+
+int honey_glm_vec3_angle(lua_State* L);
+
+int honey_glm_vec3_clamp(lua_State* L);
+
+int honey_glm_vec3_lerp(lua_State* L);
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Vec4 Functions
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+int honey_glm_vec4_copy(lua_State* L);
+
+int honey_glm_vec4_zero(lua_State* L);
+
+int honey_glm_vec4_eye(lua_State* L);
+
+int honey_glm_vec4_dot(lua_State* L);
+
+int honey_glm_vec4_norm2(lua_State* L);
+
+int honey_glm_vec4_norm(lua_State* L);
+
+int honey_glm_vec4_add(lua_State* L);
+
+int honey_glm_vec4_adds(lua_State* L);
+
+int honey_glm_vec4_sub(lua_State* L);
+
+int honey_glm_vec4_subs(lua_State* L);
+
+int honey_glm_vec4_mul(lua_State* L);
+
+int honey_glm_vec4_scale(lua_State* L);
+
+int honey_glm_vec4_scale_as(lua_State* L);
+
+int honey_glm_vec4_div(lua_State* L);
+
+int honey_glm_vec4_negate(lua_State* L);
+
+int honey_glm_vec4_normalize(lua_State* L);
+
+int honey_glm_vec4_clamp(lua_State* L);
+
+int honey_glm_vec4_lerp(lua_State* L);
+
#endif
diff --git a/src/glm_vec3_bindings.c b/src/glm_vec3_bindings.c
new file mode 100644
index 0000000..774bab0
--- /dev/null
+++ b/src/glm_vec3_bindings.c
@@ -0,0 +1,390 @@
+#include "glm_bindings.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Vec3 Functions
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+int honey_glm_vec3_copy(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ honey_lua_parse_arguments
+ (L, 1, 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (dest->type != VEC3)
+ honey_lua_throw_error(L, "destination must be VEC3 (%d); got %d instead",
+ dest->type);
+
+ glm_vec3_copy(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_zero(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+
+ glm_vec3_zero(self->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_eye(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+
+ glm_vec3_one(self->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_dot(lua_State* L)
+{
+ honey_glm_array *a, *b;
+ honey_lua_parse_arguments
+ (L, 1, 2,
+ HONEY_USERDATA, &a,
+ HONEY_USERDATA, &b);
+
+ if (b->type != VEC3)
+ honey_lua_throw_error(L, "destination must be VEC3 (%d); got %d instead",
+ VEC3, b->type);
+
+ float result = glm_vec3_dot(a->data, b->data);
+
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static bool get_vec3_arrays(lua_State* L,
+ honey_glm_array** a,
+ honey_glm_array** b,
+ honey_glm_array** dest)
+{
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 2, HONEY_USERDATA, a, HONEY_USERDATA, b,
+ 3, HONEY_USERDATA, a, HONEY_USERDATA, b, HONEY_USERDATA, dest);
+
+ if ((*b)->type != VEC3)
+ honey_lua_throw_error
+ (L, "second argument must be VEC3 (%d); got %d instead",
+ VEC3, (*b)->type);
+
+ if (choice == 1) {
+ if ((*dest)->type != VEC3)
+ honey_lua_throw_error
+ (L, "third argument must be VEC3 (%d); got %d instead",
+ VEC3, (*dest)->type);
+ }
+ else {
+ honey_glm_new_vec3(L);
+ *dest = lua_touserdata(L, -1);
+ }
+
+ return choice == 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static bool get_vec3_scalars(lua_State* L,
+ honey_glm_array** a,
+ float* s,
+ honey_glm_array** dest)
+{
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 2, HONEY_USERDATA, a, HONEY_NUMBER, s,
+ 3, HONEY_USERDATA, a, HONEY_NUMBER, s, HONEY_USERDATA, dest);
+
+ if (choice == 1) {
+ if ((*dest)->type != VEC3)
+ honey_lua_throw_error
+ (L, "third argument must be VEC3 (%d); got %d instead",
+ VEC3, (*dest)->type);
+ }
+ else {
+ honey_glm_new_vec3(L);
+ *dest = lua_touserdata(L, -1);
+ }
+
+ return choice == 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_cross(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_cross(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_crossn(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_crossn(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_norm2(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+ float result = glm_vec3_norm2(self->data);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_norm(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+ float result = glm_vec3_norm(self->data);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_add(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_add(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_adds(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec3_scalars(L, &self, &s, &dest);
+
+ glm_vec3_adds(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_sub(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_sub(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_subs(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec3_scalars(L, &self, &s, &dest);
+
+ glm_vec3_subs(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_mul(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_mul(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_scale(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec3_scalars(L, &self, &s, &dest);
+
+ glm_vec3_scale(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_scale_as(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec3_scalars(L, &self, &s, &dest);
+
+ glm_vec3_scale_as(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_div(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec3_arrays(L, &a, &b, &dest);
+
+ glm_vec3_div(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_negate(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 1, HONEY_USERDATA, &self,
+ 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (choice == 0)
+ glm_vec3_negate(self->data);
+ else
+ glm_vec3_negate_to(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_normalize(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 1, HONEY_USERDATA, &self,
+ 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (choice == 0)
+ glm_vec3_normalize(self->data);
+ else
+ glm_vec3_normalize_to(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_angle(lua_State* L)
+{
+ honey_glm_array *a, *b;
+ honey_lua_parse_arguments
+ (L, 1, 2,
+ HONEY_USERDATA, &a, HONEY_USERDATA, &b);
+
+ if (b->type != VEC3)
+ honey_lua_throw_error
+ (L, "second argument must be VEC3 (%d); got %d instead",
+ VEC3, b->type);
+
+ float angle = glm_vec3_angle(a->data, b->data);
+ lua_pushnumber(L, angle);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_clamp(lua_State* L)
+{
+ honey_glm_array* self;
+ float min, max;
+ honey_lua_parse_arguments(L, 1, 3,
+ HONEY_USERDATA, &self,
+ HONEY_NUMBER, &min,
+ HONEY_NUMBER, &max);
+
+ glm_vec3_clamp(self->data, min, max);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec3_lerp(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ float s;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 3, HONEY_USERDATA, &a, HONEY_USERDATA, &b, HONEY_NUMBER, &s,
+ 4, HONEY_USERDATA, &a, HONEY_USERDATA, &b, HONEY_NUMBER, &s, HONEY_USERDATA, &dest);
+
+ if (b->type != VEC3)
+ honey_lua_throw_error
+ (L, "second argument must be VEC3 (%d); got %d instead",
+ VEC3, b->type);
+
+ if (choice == 1) {
+ if (dest->type != VEC3)
+ honey_lua_throw_error
+ (L, "fourth argument must be VEC3 (%d); got %d instead",
+ VEC3, dest->type);
+ }
+ else {
+ honey_glm_new_vec3(L);
+ dest = lua_touserdata(L, -1);
+ }
+
+ glm_vec3_lerp(a->data, b->data, s, dest->data);
+
+ if (choice == 0)
+ return 1;
+ return 0;
+}
diff --git a/src/glm_vec4_bindings.c b/src/glm_vec4_bindings.c
new file mode 100644
index 0000000..878473f
--- /dev/null
+++ b/src/glm_vec4_bindings.c
@@ -0,0 +1,343 @@
+#include "glm_bindings.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Vec4 Functions
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+int honey_glm_vec4_copy(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ honey_lua_parse_arguments
+ (L, 1, 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (dest->type != VEC4)
+ honey_lua_throw_error(L, "destination must be VEC4 (%d); got %d instead",
+ dest->type);
+
+ glm_vec4_copy(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_zero(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+
+ glm_vec4_zero(self->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_eye(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+
+ glm_vec4_one(self->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_dot(lua_State* L)
+{
+ honey_glm_array *a, *b;
+ honey_lua_parse_arguments
+ (L, 1, 2,
+ HONEY_USERDATA, &a,
+ HONEY_USERDATA, &b);
+
+ if (b->type != VEC4)
+ honey_lua_throw_error(L, "destination must be VEC4 (%d); got %d instead",
+ VEC4, b->type);
+
+ float result = glm_vec4_dot(a->data, b->data);
+
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static bool get_vec4_arrays(lua_State* L,
+ honey_glm_array** a,
+ honey_glm_array** b,
+ honey_glm_array** dest)
+{
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 2, HONEY_USERDATA, a, HONEY_USERDATA, b,
+ 3, HONEY_USERDATA, a, HONEY_USERDATA, b, HONEY_USERDATA, dest);
+
+ if ((*b)->type != VEC4)
+ honey_lua_throw_error
+ (L, "second argument must be VEC4 (%d); got %d instead",
+ VEC4, (*b)->type);
+
+ if (choice == 1) {
+ if ((*dest)->type != VEC4)
+ honey_lua_throw_error
+ (L, "third argument must be VEC4 (%d); got %d instead",
+ VEC4, (*dest)->type);
+ }
+ else {
+ honey_glm_new_vec4(L);
+ *dest = lua_touserdata(L, -1);
+ }
+
+ return choice == 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static bool get_vec4_scalars(lua_State* L,
+ honey_glm_array** a,
+ float* s,
+ honey_glm_array** dest)
+{
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 2, HONEY_USERDATA, a, HONEY_NUMBER, s,
+ 3, HONEY_USERDATA, a, HONEY_NUMBER, s, HONEY_USERDATA, dest);
+
+ if (choice == 1) {
+ if ((*dest)->type != VEC4)
+ honey_lua_throw_error
+ (L, "third argument must be VEC4 (%d); got %d instead",
+ VEC4, (*dest)->type);
+ }
+ else {
+ honey_glm_new_vec4(L);
+ *dest = lua_touserdata(L, -1);
+ }
+
+ return choice == 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_norm2(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+ float result = glm_vec4_norm2(self->data);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_norm(lua_State* L)
+{
+ honey_glm_array *self;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &self);
+ float result = glm_vec4_norm(self->data);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_add(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec4_arrays(L, &a, &b, &dest);
+
+ glm_vec4_add(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_adds(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec4_scalars(L, &self, &s, &dest);
+
+ glm_vec4_adds(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_sub(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec4_arrays(L, &a, &b, &dest);
+
+ glm_vec4_sub(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_subs(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec4_scalars(L, &self, &s, &dest);
+
+ glm_vec4_subs(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_mul(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec4_arrays(L, &a, &b, &dest);
+
+ glm_vec4_mul(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_scale(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec4_scalars(L, &self, &s, &dest);
+
+ glm_vec4_scale(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_scale_as(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ float s;
+ bool new_dest = get_vec4_scalars(L, &self, &s, &dest);
+
+ glm_vec4_scale_as(self->data, s, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_div(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ bool new_dest = get_vec4_arrays(L, &a, &b, &dest);
+
+ glm_vec4_div(a->data, b->data, dest->data);
+
+ if (new_dest)
+ return 1;
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_negate(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 1, HONEY_USERDATA, &self,
+ 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (choice == 0)
+ glm_vec4_negate(self->data);
+ else
+ glm_vec4_negate_to(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_normalize(lua_State* L)
+{
+ honey_glm_array *self, *dest;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 1, HONEY_USERDATA, &self,
+ 2, HONEY_USERDATA, &self, HONEY_USERDATA, &dest);
+
+ if (choice == 0)
+ glm_vec4_normalize(self->data);
+ else
+ glm_vec4_normalize_to(self->data, dest->data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_clamp(lua_State* L)
+{
+ honey_glm_array* self;
+ float min, max;
+ honey_lua_parse_arguments(L, 1, 3,
+ HONEY_USERDATA, &self,
+ HONEY_NUMBER, &min,
+ HONEY_NUMBER, &max);
+
+ glm_vec4_clamp(self->data, min, max);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_glm_vec4_lerp(lua_State* L)
+{
+ honey_glm_array *a, *b, *dest;
+ float s;
+ int choice = honey_lua_parse_arguments
+ (L, 2,
+ 3, HONEY_USERDATA, &a, HONEY_USERDATA, &b, HONEY_NUMBER, &s,
+ 4, HONEY_USERDATA, &a, HONEY_USERDATA, &b, HONEY_NUMBER, &s, HONEY_USERDATA, &dest);
+
+ if (b->type != VEC4)
+ honey_lua_throw_error
+ (L, "second argument must be VEC4 (%d); got %d instead",
+ VEC4, b->type);
+
+ if (choice == 1) {
+ if (dest->type != VEC4)
+ honey_lua_throw_error
+ (L, "fourth argument must be VEC4 (%d); got %d instead",
+ VEC4, dest->type);
+ }
+ else {
+ honey_glm_new_vec4(L);
+ dest = lua_touserdata(L, -1);
+ }
+
+ glm_vec4_lerp(a->data, b->data, s, dest->data);
+
+ if (choice == 0)
+ return 1;
+ return 0;
+}
diff --git a/src/honey.c b/src/honey.c
index 122c736..4757f53 100644
--- a/src/honey.c
+++ b/src/honey.c
@@ -122,7 +122,6 @@ bool honey_setup(lua_State** L)
lua_setfield(*L, -2, "input");
honey_setup_glm(*L);
- lua_setfield(*L, -2, "glm");
honey_setup_shader(*L);