summaryrefslogtreecommitdiff
path: root/src/glm
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-02-22 23:52:43 -0600
committersanine <sanine.not@pm.me>2023-02-22 23:52:43 -0600
commit26af60e0e9dfc4ecdf6b1c6f9a2dc5818f4ad8d7 (patch)
treef17d7d5dd5ba3263dab1960b28bc40c3e6059da6 /src/glm
parentb5f0a45d9b10ebab8610ba235bc46f69fd58e2a2 (diff)
refactor: bind all basic matrix & vector functions from cglm
Diffstat (limited to 'src/glm')
-rw-r--r--src/glm/CMakeLists.txt10
-rw-r--r--src/glm/affine2d.c115
-rw-r--r--src/glm/camera.c261
-rw-r--r--src/glm/glm.h226
-rw-r--r--src/glm/mat2.c162
-rw-r--r--src/glm/mat3.c171
-rw-r--r--src/glm/mat4.c244
-rw-r--r--src/glm/quaternion.c352
-rw-r--r--src/glm/setup.c1
-rw-r--r--src/glm/vec2.c359
-rw-r--r--src/glm/vec4.c383
11 files changed, 2283 insertions, 1 deletions
diff --git a/src/glm/CMakeLists.txt b/src/glm/CMakeLists.txt
index 3c5fb32..d1ead47 100644
--- a/src/glm/CMakeLists.txt
+++ b/src/glm/CMakeLists.txt
@@ -2,6 +2,14 @@ project(honey_engine)
target_sources(honey PUBLIC
${CMAKE_CURRENT_LIST_DIR}/setup.c
- ${CMAKE_CURRENT_LIST_DIR}/vec3.c
${CMAKE_CURRENT_LIST_DIR}/affine3d.c
+ ${CMAKE_CURRENT_LIST_DIR}/affine2d.c
+ ${CMAKE_CURRENT_LIST_DIR}/camera.c
+ ${CMAKE_CURRENT_LIST_DIR}/quaternion.c
+ ${CMAKE_CURRENT_LIST_DIR}/mat2.c
+ ${CMAKE_CURRENT_LIST_DIR}/mat3.c
+ ${CMAKE_CURRENT_LIST_DIR}/mat4.c
+ ${CMAKE_CURRENT_LIST_DIR}/vec2.c
+ ${CMAKE_CURRENT_LIST_DIR}/vec3.c
+ ${CMAKE_CURRENT_LIST_DIR}/vec4.c
)
diff --git a/src/glm/affine2d.c b/src/glm/affine2d.c
new file mode 100644
index 0000000..34601df
--- /dev/null
+++ b/src/glm/affine2d.c
@@ -0,0 +1,115 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_translate2d_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_translate2d(*m, *v);
+ return 0;
+}
+
+
+int glm_translate2d_to_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ mat3 *dest = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_translate2d_to(*m, *v, *dest);
+ return 0;
+}
+
+
+int glm_translate2d_x_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float x = luaL_checknumber(L, 2);
+ glm_translate2d_x(*m, x);
+ return 0;
+}
+
+
+int glm_translate2d_y_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float y = luaL_checknumber(L, 2);
+ glm_translate2d_y(*m, y);
+ return 0;
+}
+
+
+int glm_translate2d_make_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_translate2d_make(*m, *v);
+ return 0;
+}
+
+
+int glm_scale2d_to_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ mat3 *dest = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_scale2d_to(*m, *v, *dest);
+ return 0;
+}
+
+
+int glm_scale2d_make_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_scale2d_make(*m, *v);
+ return 0;
+}
+
+
+int glm_scale2d_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_scale2d(*m, *v);
+ return 0;
+}
+
+
+int glm_scale2d_uni_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float s = luaL_checknumber(L, 2);
+ glm_scale2d_uni(*m, s);
+ return 0;
+}
+
+
+int glm_rotate2d_make_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float angle = luaL_checknumber(L, 2);
+ glm_rotate2d_make(*m, angle);
+ return 0;
+}
+
+
+int glm_rotate2d_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float angle = luaL_checknumber(L, 2);
+ glm_rotate2d(*m, angle);
+ return 0;
+}
+
+
+int glm_rotate2d_to_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float angle = luaL_checknumber(L, 2);
+ mat3 *dest = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_rotate2d_to(*m, angle, *dest);
+ return 0;
+}
diff --git a/src/glm/camera.c b/src/glm/camera.c
new file mode 100644
index 0000000..abc5f4d
--- /dev/null
+++ b/src/glm/camera.c
@@ -0,0 +1,261 @@
+#include <string.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_frustum_bind(lua_State *L)
+{
+ float left = luaL_checknumber(L, 1);
+ float right = luaL_checknumber(L, 2);
+ float bottom = luaL_checknumber(L, 3);
+ float top = luaL_checknumber(L, 4);
+ float nearVal = luaL_checknumber(L, 5);
+ float farVal = luaL_checknumber(L, 6);
+ mat4 *dest = luaL_checkudata(L, 7, glm_mat4_tname);
+ glm_frustum(left, right, bottom, top, nearVal, farVal, *dest);
+ return 0;
+}
+
+
+int glm_ortho_bind(lua_State *L)
+{
+ float left = luaL_checknumber(L, 1);
+ float right = luaL_checknumber(L, 2);
+ float bottom = luaL_checknumber(L, 3);
+ float top = luaL_checknumber(L, 4);
+ float nearVal = luaL_checknumber(L, 5);
+ float farVal = luaL_checknumber(L, 6);
+ mat4 *dest = luaL_checkudata(L, 7, glm_mat4_tname);
+ glm_ortho(left, right, bottom, top, nearVal, farVal, *dest);
+ return 0;
+}
+
+
+int glm_ortho_aabb_bind(lua_State *L)
+{
+ vec3 *aa = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *bb = luaL_checkudata(L, 2, glm_vec3_tname);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ vec3 box[2];
+ memcpy(box, *aa, sizeof(vec3));
+ memcpy(box+1, *bb, sizeof(vec3));
+ glm_ortho_aabb(box, *dest);
+ return 0;
+}
+
+
+int glm_ortho_aabb_p_bind(lua_State *L)
+{
+ vec3 *aa = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *bb = luaL_checkudata(L, 2, glm_vec3_tname);
+ float padding = luaL_checknumber(L, 3);
+ mat4 *dest = luaL_checkudata(L, 4, glm_mat4_tname);
+ vec3 box[2];
+ memcpy(box, *aa, sizeof(vec3));
+ memcpy(box+1, *bb, sizeof(vec3));
+ glm_ortho_aabb_p(box, padding, *dest);
+ return 0;
+}
+
+
+int glm_ortho_aabb_pz_bind(lua_State *L)
+{
+ vec3 *aa = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *bb = luaL_checkudata(L, 2, glm_vec3_tname);
+ float padding = luaL_checknumber(L, 3);
+ mat4 *dest = luaL_checkudata(L, 4, glm_mat4_tname);
+ vec3 box[2];
+ memcpy(box, *aa, sizeof(vec3));
+ memcpy(box+1, *bb, sizeof(vec3));
+ glm_ortho_aabb_pz(box, padding, *dest);
+ return 0;
+}
+
+
+int glm_ortho_default_bind(lua_State *L)
+{
+ float aspect = luaL_checknumber(L, 1);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_ortho_default(aspect, *dest);
+ return 0;
+}
+
+
+int glm_ortho_default_s_bind(lua_State *L)
+{
+ float aspect = luaL_checknumber(L, 1);
+ float size = luaL_checknumber(L, 2);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ glm_ortho_default_s(aspect, size, *dest);
+ return 0;
+}
+
+
+int glm_perspective_bind(lua_State *L)
+{
+ float fovy = luaL_checknumber(L, 1);
+ float aspect = luaL_checknumber(L, 2);
+ float nearVal = luaL_checknumber(L, 3);
+ float farVal = luaL_checknumber(L, 4);
+ mat4 *dest = luaL_checkudata(L, 5, glm_mat4_tname);
+ glm_perspective(fovy, aspect, nearVal, farVal, *dest);
+ return 0;
+}
+
+
+int glm_persp_move_far_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float deltaFar = luaL_checknumber(L, 2);
+ glm_persp_move_far(*proj, deltaFar);
+ return 0;
+}
+
+
+int glm_perspective_default_bind(lua_State *L)
+{
+ float aspect = luaL_checknumber(L, 1);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_perspective_default(aspect, *dest);
+ return 0;
+}
+
+
+int glm_perspective_resize_bind(lua_State *L)
+{
+ float aspect = luaL_checknumber(L, 1);
+ mat4 *proj = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_perspective_resize(aspect, *proj);
+ return 0;
+}
+
+
+int glm_lookat_bind(lua_State *L)
+{
+ vec3 *eye = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *center = luaL_checkudata(L, 2, glm_vec3_tname);
+ vec3 *up = luaL_checkudata(L, 3, glm_vec3_tname);
+ mat4 *dest = luaL_checkudata(L, 4, glm_mat4_tname);
+ glm_lookat(*eye, *center, *up, *dest);
+ return 0;
+}
+
+
+int glm_look_bind(lua_State *L)
+{
+ vec3 *eye = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *dir = luaL_checkudata(L, 2, glm_vec3_tname);
+ vec3 *up = luaL_checkudata(L, 3, glm_vec3_tname);
+ mat4 *dest = luaL_checkudata(L, 4, glm_mat4_tname);
+ glm_look(*eye, *dir, *up, *dest);
+ return 0;
+}
+
+
+int glm_look_anyup_bind(lua_State *L)
+{
+ vec3 *eye = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *dir = luaL_checkudata(L, 2, glm_vec3_tname);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ glm_look_anyup(*eye, *dir, *dest);
+ return 0;
+}
+
+
+int glm_persp_decomp_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float nearVal, farVal, top, bottom, left, right;
+ glm_persp_decomp(*proj, &nearVal, &farVal, &top, &bottom, &left, &right);
+ lua_pushnumber(L, nearVal);
+ lua_pushnumber(L, farVal);
+ lua_pushnumber(L, top);
+ lua_pushnumber(L, bottom);
+ lua_pushnumber(L, left);
+ lua_pushnumber(L, right);
+ return 6;
+}
+
+
+/* glm_persp_decompv would provide an identical interface to glm_persp_decomp, so it's not bound */
+
+
+int glm_persp_decomp_x_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float left, right;
+ glm_persp_decomp_x(*proj, &left, &right);
+ lua_pushnumber(L, left);
+ lua_pushnumber(L, right);
+ return 2;
+}
+
+
+int glm_persp_decomp_y_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float top, bottom;
+ glm_persp_decomp_y(*proj, &top, &bottom);
+ lua_pushnumber(L, top);
+ lua_pushnumber(L, bottom);
+ return 2;
+}
+
+
+int glm_persp_decomp_z_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float nearVal, farVal;
+ glm_persp_decomp_z(*proj, &nearVal, &farVal);
+ lua_pushnumber(L, nearVal);
+ lua_pushnumber(L, farVal);
+ return 2;
+}
+
+
+int glm_persp_decomp_far_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float farVal;
+ glm_persp_decomp_far(*proj, &farVal);
+ return 0;
+}
+
+
+int glm_persp_decomp_near_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float nearVal;
+ glm_persp_decomp_near(*proj, &nearVal);
+ return 0;
+}
+
+
+int glm_persp_fovy_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float bind_result = glm_persp_fovy(*proj);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_persp_aspect_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float bind_result = glm_persp_aspect(*proj);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_persp_sizes_bind(lua_State *L)
+{
+ mat4 *proj = luaL_checkudata(L, 1, glm_mat4_tname);
+ float fovy = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_persp_sizes(*proj, fovy, *dest);
+ return 0;
+}
diff --git a/src/glm/glm.h b/src/glm/glm.h
index b331d37..57bc78c 100644
--- a/src/glm/glm.h
+++ b/src/glm/glm.h
@@ -10,6 +10,7 @@ extern const char *glm_mat4_tname;
extern const char *glm_vec2_tname;
extern const char *glm_vec3_tname;
extern const char *glm_vec4_tname;
+extern const char *glm_versor_tname;
#define GLM_FUNCTIONS \
@@ -36,6 +37,189 @@ extern const char *glm_vec4_tname;
X("translate_z", glm_translate_z_bind) \
X("uniscaled", glm_uniscaled_bind) \
\
+ /* 2d affine transforms */ \
+ X("translate2d", glm_translate2d_bind) \
+ X("translate2d_to", glm_translate2d_to_bind) \
+ X("translate2d_x", glm_translate2d_x_bind) \
+ X("translate2d_y", glm_translate2d_y_bind) \
+ X("translate2d_make", glm_translate2d_make_bind) \
+ X("scale2d_to", glm_scale2d_to_bind) \
+ X("scale2d_make", glm_scale2d_make_bind) \
+ X("scale2d", glm_scale2d_bind) \
+ X("scale2d_uni", glm_scale2d_uni_bind) \
+ X("rotate2d_make", glm_rotate2d_make_bind) \
+ X("rotate2d", glm_rotate2d_bind) \
+ X("rotate2d_to", glm_rotate2d_to_bind) \
+\
+ /* camera */ \
+ X("frustum", glm_frustum_bind) \
+ X("ortho", glm_ortho_bind) \
+ X("ortho_aabb", glm_ortho_aabb_bind) \
+ X("ortho_aabb_p", glm_ortho_aabb_p_bind) \
+ X("ortho_aabb_pz", glm_ortho_aabb_pz_bind) \
+ X("ortho_default", glm_ortho_default_bind) \
+ X("ortho_default_s", glm_ortho_default_s_bind) \
+ X("perspective", glm_perspective_bind) \
+ X("persp_move_far", glm_persp_move_far_bind) \
+ X("perspective_default", glm_perspective_default_bind) \
+ X("perspective_resize", glm_perspective_resize_bind) \
+ X("lookat", glm_lookat_bind) \
+ X("look", glm_look_bind) \
+ X("look_anyup", glm_look_anyup_bind) \
+ X("persp_decomp", glm_persp_decomp_bind) \
+ X("persp_decomp_x", glm_persp_decomp_x_bind) \
+ X("persp_decomp_y", glm_persp_decomp_y_bind) \
+ X("persp_decomp_z", glm_persp_decomp_z_bind) \
+ X("persp_decomp_far", glm_persp_decomp_far_bind) \
+ X("persp_decomp_near", glm_persp_decomp_near_bind) \
+ X("persp_fovy", glm_persp_fovy_bind) \
+ X("persp_aspect", glm_persp_aspect_bind) \
+ X("persp_sizes", glm_persp_sizes_bind) \
+\
+ /* quaternions */ \
+ X("quat_create", glm_quat_create) \
+ X("quat_identity", glm_quat_identity_bind) \
+ X("quat_init", glm_quat_init_bind) \
+ X("quat", glm_quat_bind) \
+ X("quatv", glm_quatv_bind) \
+ X("quat_copy", glm_quat_copy_bind) \
+ X("quat_from_vecs", glm_quat_from_vecs_bind) \
+ X("quat_norm", glm_quat_norm_bind) \
+ X("quat_normalize_to", glm_quat_normalize_to_bind) \
+ X("quat_normalize", glm_quat_normalize_bind) \
+ X("quat_dot", glm_quat_dot_bind) \
+ X("quat_conjugate", glm_quat_conjugate_bind) \
+ X("quat_inv", glm_quat_inv_bind) \
+ X("quat_add", glm_quat_add_bind) \
+ X("quat_sub", glm_quat_sub_bind) \
+ X("quat_real", glm_quat_real_bind) \
+ X("quat_imag", glm_quat_imag_bind) \
+ X("quat_imagn", glm_quat_imagn_bind) \
+ X("quat_imaglen", glm_quat_imaglen_bind) \
+ X("quat_angle", glm_quat_angle_bind) \
+ X("quat_axis", glm_quat_axis_bind) \
+ X("quat_mul", glm_quat_mul_bind) \
+ X("quat_mat4", glm_quat_mat4_bind) \
+ X("quat_mat4t", glm_quat_mat4t_bind) \
+ X("quat_mat3", glm_quat_mat3_bind) \
+ X("quat_mat3t", glm_quat_mat3t_bind) \
+ X("quat_lerp", glm_quat_lerp_bind) \
+ X("quat_nlerp", glm_quat_nlerp_bind) \
+ X("quat_slerp", glm_quat_slerp_bind) \
+ X("quat_look", glm_quat_look_bind) \
+ X("quat_for", glm_quat_for_bind) \
+ X("quat_forp", glm_quat_forp_bind) \
+ X("quat_rotatev", glm_quat_rotatev_bind) \
+ X("quat_rotate", glm_quat_rotate_bind) \
+ X("quat_rotate_at", glm_quat_rotate_at_bind) \
+ X("quat_rotate_atm", glm_quat_rotate_atm_bind) \
+\
+ /* mat2 */ \
+ X("mat2_create", glm_mat2_create) \
+ X("mat2_set", glm_mat2_set) \
+ X("mat2_get", glm_mat2_get) \
+ X("mat2_copy", glm_mat2_copy_bind) \
+ X("mat2_identity", glm_mat2_identity_bind) \
+ X("mat2_zero", glm_mat2_zero_bind) \
+ X("mat2_mul", glm_mat2_mul_bind) \
+ X("mat2_transpose_to", glm_mat2_transpose_to_bind) \
+ X("mat2_transpose", glm_mat2_transpose_bind) \
+ X("mat2_mulv", glm_mat2_mulv_bind) \
+ X("mat2_scale", glm_mat2_scale_bind) \
+ X("mat2_det", glm_mat2_det_bind) \
+ X("mat2_inv", glm_mat2_inv_bind) \
+ X("mat2_trace", glm_mat2_trace_bind) \
+ X("mat2_swap_col", glm_mat2_swap_col_bind) \
+ X("mat2_swap_row", glm_mat2_swap_row_bind) \
+ X("mat2_rmc", glm_mat2_rmc_bind) \
+\
+ /* mat3 */ \
+ X("mat3_create", glm_mat3_create) \
+ X("mat3_set", glm_mat3_set) \
+ X("mat3_get", glm_mat3_get) \
+ X("mat3_copy", glm_mat3_copy_bind) \
+ X("mat3_identity", glm_mat3_identity_bind) \
+ X("mat3_zero", glm_mat3_zero_bind) \
+ X("mat3_mul", glm_mat3_mul_bind) \
+ X("mat3_transpose_to", glm_mat3_transpose_to_bind) \
+ X("mat3_transpose", glm_mat3_transpose_bind) \
+ X("mat3_mulv", glm_mat3_mulv_bind) \
+ X("mat3_quat", glm_mat3_quat_bind) \
+ X("mat3_scale", glm_mat3_scale_bind) \
+ X("mat3_det", glm_mat3_det_bind) \
+ X("mat3_inv", glm_mat3_inv_bind) \
+ X("mat3_trace", glm_mat3_trace_bind) \
+ X("mat3_swap_col", glm_mat3_swap_col_bind) \
+ X("mat3_swap_row", glm_mat3_swap_row_bind) \
+ X("mat3_rmc", glm_mat3_rmc_bind) \
+\
+ /* mat4 */ \
+ X("mat4_create", glm_mat4_create) \
+ X("mat4_set", glm_mat4_set) \
+ X("mat4_get", glm_mat4_get) \
+ X("mat4_ucopy", glm_mat4_ucopy_bind) \
+ X("mat4_copy", glm_mat4_copy_bind) \
+ X("mat4_identity", glm_mat4_identity_bind) \
+ X("mat4_zero", glm_mat4_zero_bind) \
+ X("mat4_pick3", glm_mat4_pick3_bind) \
+ X("mat4_pick3t", glm_mat4_pick3t_bind) \
+ X("mat4_ins3", glm_mat4_ins3_bind) \
+ X("mat4_mul", glm_mat4_mul_bind) \
+ X("mat4_mulv", glm_mat4_mulv_bind) \
+ X("mat4_mulv3", glm_mat4_mulv3_bind) \
+ X("mat4_trace", glm_mat4_trace_bind) \
+ X("mat4_trace3", glm_mat4_trace3_bind) \
+ X("mat4_quat", glm_mat4_quat_bind) \
+ X("mat4_transpose_to", glm_mat4_transpose_to_bind) \
+ X("mat4_transpose", glm_mat4_transpose_bind) \
+ X("mat4_scale_p", glm_mat4_scale_p_bind) \
+ X("mat4_scale", glm_mat4_scale_bind) \
+ X("mat4_det", glm_mat4_det_bind) \
+ X("mat4_inv", glm_mat4_inv_bind) \
+ X("mat4_inv_fast", glm_mat4_inv_fast_bind) \
+ X("mat4_swap_col", glm_mat4_swap_col_bind) \
+ X("mat4_swap_row", glm_mat4_swap_row_bind) \
+ X("mat4_rmc", glm_mat4_rmc_bind) \
+\
+ /* vec2 */ \
+ X("vec2_create", glm_vec2_create) \
+ X("vec2_set", glm_vec2_set) \
+ X("vec2_get", glm_vec2_get) \
+ X("vec2", glm_vec2_bind) \
+ X("vec2_copy", glm_vec2_copy_bind) \
+ X("vec2_zero", glm_vec2_zero_bind) \
+ X("vec2_one", glm_vec2_one_bind) \
+ X("vec2_dot", glm_vec2_dot_bind) \
+ X("vec2_cross", glm_vec2_cross_bind) \
+ X("vec2_norm2", glm_vec2_norm2_bind) \
+ X("vec2_norm", glm_vec2_norm_bind) \
+ X("vec2_add", glm_vec2_add_bind) \
+ X("vec2_adds", glm_vec2_adds_bind) \
+ X("vec2_sub", glm_vec2_sub_bind) \
+ X("vec2_subs", glm_vec2_subs_bind) \
+ X("vec2_mul", glm_vec2_mul_bind) \
+ X("vec2_scale", glm_vec2_scale_bind) \
+ X("vec2_scale_as", glm_vec2_scale_as_bind) \
+ X("vec2_div", glm_vec2_div_bind) \
+ X("vec2_divs", glm_vec2_divs_bind) \
+ X("vec2_addadd", glm_vec2_addadd_bind) \
+ X("vec2_subadd", glm_vec2_subadd_bind) \
+ X("vec2_muladd", glm_vec2_muladd_bind) \
+ X("vec2_muladds", glm_vec2_muladds_bind) \
+ X("vec2_maxadd", glm_vec2_maxadd_bind) \
+ X("vec2_minadd", glm_vec2_minadd_bind) \
+ X("vec2_negate", glm_vec2_negate_bind) \
+ X("vec2_negate_to", glm_vec2_negate_to_bind) \
+ X("vec2_normalize", glm_vec2_normalize_bind) \
+ X("vec2_normalize_to", glm_vec2_normalize_to_bind) \
+ X("vec2_rotate", glm_vec2_rotate_bind) \
+ X("vec2_distance2", glm_vec2_distance2_bind) \
+ X("vec2_distance", glm_vec2_distance_bind) \
+ X("vec2_maxv", glm_vec2_maxv_bind) \
+ X("vec2_minv", glm_vec2_minv_bind) \
+ X("vec2_clamp", glm_vec2_clamp_bind) \
+ X("vec2_lerp", glm_vec2_lerp_bind) \
+\
/* vec3 */ \
X("vec3_create", glm_vec3_create) \
X("vec3_set", glm_vec3_set) \
@@ -85,6 +269,48 @@ extern const char *glm_vec4_tname;
X("vec3_ortho", glm_vec3_ortho_bind) \
X("vec3_clamp", glm_vec3_clamp_bind) \
X("vec3_lerp", glm_vec3_lerp_bind) \
+\
+ /* vec4 */ \
+ X("vec4_create", glm_vec4_create) \
+ X("vec4_set", glm_vec4_set) \
+ X("vec4_get", glm_vec4_get) \
+ X("vec4", glm_vec4_bind) \
+ X("vec4_copy3", glm_vec4_copy3_bind) \
+ X("vec4_copy", glm_vec4_copy_bind) \
+ X("vec4_ucopy", glm_vec4_ucopy_bind) \
+ X("vec4_zero", glm_vec4_zero_bind) \
+ X("vec4_dot", glm_vec4_dot_bind) \
+ X("vec4_norm2", glm_vec4_norm2_bind) \
+ X("vec4_norm", glm_vec4_norm_bind) \
+ X("vec4_add", glm_vec4_add_bind) \
+ X("vec4_adds", glm_vec4_adds_bind) \
+ X("vec4_sub", glm_vec4_sub_bind) \
+ X("vec4_subs", glm_vec4_subs_bind) \
+ X("vec4_mul", glm_vec4_mul_bind) \
+ X("vec4_scale", glm_vec4_scale_bind) \
+ X("vec4_scale_as", glm_vec4_scale_as_bind) \
+ X("vec4_div", glm_vec4_div_bind) \
+ X("vec4_divs", glm_vec4_divs_bind) \
+ X("vec4_addadd", glm_vec4_addadd_bind) \
+ X("vec4_subadd", glm_vec4_subadd_bind) \
+ X("vec4_muladd", glm_vec4_muladd_bind) \
+ X("vec4_muladds", glm_vec4_muladds_bind) \
+ X("vec4_maxadd", glm_vec4_maxadd_bind) \
+ X("vec4_minadd", glm_vec4_minadd_bind) \
+ X("vec4_flipsign", glm_vec4_flipsign_bind) \
+ X("vec4_flipsign_to", glm_vec4_flipsign_to_bind) \
+ X("vec4_inv", glm_vec4_inv_bind) \
+ X("vec4_inv_to", glm_vec4_inv_to_bind) \
+ X("vec4_negate", glm_vec4_negate_bind) \
+ X("vec4_negate_to", glm_vec4_negate_to_bind) \
+ X("vec4_normalize", glm_vec4_normalize_bind) \
+ X("vec4_normalize_to", glm_vec4_normalize_to_bind) \
+ X("vec4_distance", glm_vec4_distance_bind) \
+ X("vec4_maxv", glm_vec4_maxv_bind) \
+ X("vec4_minv", glm_vec4_minv_bind) \
+ X("vec4_clamp", glm_vec4_clamp_bind) \
+ X("vec4_lerp", glm_vec4_lerp_bind) \
+ X("vec4_cubic", glm_vec4_cubic_bind) \
#define X(name, func) int func(lua_State *L);
diff --git a/src/glm/mat2.c b/src/glm/mat2.c
new file mode 100644
index 0000000..c963b18
--- /dev/null
+++ b/src/glm/mat2.c
@@ -0,0 +1,162 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_mat2_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(mat2));
+ luaL_getmetatable(L, glm_mat2_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_mat2_set(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ float value = luaL_checknumber(L, 4);
+ (*m)[col][row] = value;
+ return 0;
+}
+
+
+int glm_mat2_get(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ lua_pushnumber(L, (*m)[col][row]);
+ return 1;
+}
+
+
+int glm_mat2_copy_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ mat2 *dest = luaL_checkudata(L, 2, glm_mat2_tname);
+ glm_mat2_copy(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat2_identity_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ glm_mat2_identity(*mat);
+ return 0;
+}
+
+
+int glm_mat2_zero_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ glm_mat2_zero(*mat);
+ return 0;
+}
+
+
+int glm_mat2_mul_bind(lua_State *L)
+{
+ mat2 *m1 = luaL_checkudata(L, 1, glm_mat2_tname);
+ mat2 *m2 = luaL_checkudata(L, 2, glm_mat2_tname);
+ mat2 *dest = luaL_checkudata(L, 3, glm_mat2_tname);
+ glm_mat2_mul(*m1, *m2, *dest);
+ return 0;
+}
+
+
+int glm_mat2_transpose_to_bind(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ mat2 *dest = luaL_checkudata(L, 2, glm_mat2_tname);
+ glm_mat2_transpose_to(*m, *dest);
+ return 0;
+}
+
+
+int glm_mat2_transpose_bind(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ glm_mat2_transpose(*m);
+ return 0;
+}
+
+
+int glm_mat2_mulv_bind(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ vec2 *v = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_mat2_mulv(*m, *v, *dest);
+ return 0;
+}
+
+
+int glm_mat2_scale_bind(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ float s = luaL_checknumber(L, 2);
+ glm_mat2_scale(*m, s);
+ return 0;
+}
+
+
+int glm_mat2_det_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ float bind_result = glm_mat2_det(*mat);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_mat2_inv_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ mat2 *dest = luaL_checkudata(L, 2, glm_mat2_tname);
+ glm_mat2_inv(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat2_trace_bind(lua_State *L)
+{
+ mat2 *m = luaL_checkudata(L, 1, glm_mat2_tname);
+ glm_mat2_trace(*m);
+ return 0;
+}
+
+
+int glm_mat2_swap_col_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ int col1 = luaL_checkinteger(L, 2);
+ int col2 = luaL_checkinteger(L, 3);
+ glm_mat2_swap_col(*mat, col1, col2);
+ return 0;
+}
+
+
+int glm_mat2_swap_row_bind(lua_State *L)
+{
+ mat2 *mat = luaL_checkudata(L, 1, glm_mat2_tname);
+ int row1 = luaL_checkinteger(L, 2);
+ int row2 = luaL_checkinteger(L, 3);
+ glm_mat2_swap_row(*mat, row1, row2);
+ return 0;
+}
+
+
+int glm_mat2_rmc_bind(lua_State *L)
+{
+ vec2 *r = luaL_checkudata(L, 1, glm_vec2_tname);
+ mat2 *m = luaL_checkudata(L, 2, glm_mat2_tname);
+ vec2 *c = luaL_checkudata(L, 3, glm_vec2_tname);
+ float bind_result = glm_mat2_rmc(*r, *m, *c);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
diff --git a/src/glm/mat3.c b/src/glm/mat3.c
new file mode 100644
index 0000000..be5abdd
--- /dev/null
+++ b/src/glm/mat3.c
@@ -0,0 +1,171 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_mat3_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(mat3));
+ luaL_getmetatable(L, glm_mat3_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_mat3_set(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ float value = luaL_checknumber(L, 4);
+ (*m)[col][row] = value;
+ return 0;
+}
+
+
+int glm_mat3_get(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ lua_pushnumber(L, (*m)[col][row]);
+ return 1;
+}
+
+
+int glm_mat3_copy_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_mat3_copy(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat3_identity_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_mat3_identity(*mat);
+ return 0;
+}
+
+
+int glm_mat3_zero_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_mat3_zero(*mat);
+ return 0;
+}
+
+
+int glm_mat3_mul_bind(lua_State *L)
+{
+ mat3 *m1 = luaL_checkudata(L, 1, glm_mat3_tname);
+ mat3 *m2 = luaL_checkudata(L, 2, glm_mat3_tname);
+ mat3 *dest = luaL_checkudata(L, 3, glm_mat3_tname);
+ glm_mat3_mul(*m1, *m2, *dest);
+ return 0;
+}
+
+
+int glm_mat3_transpose_to_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_mat3_transpose_to(*m, *dest);
+ return 0;
+}
+
+
+int glm_mat3_transpose_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_mat3_transpose(*m);
+ return 0;
+}
+
+
+int glm_mat3_mulv_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ vec3 *v = luaL_checkudata(L, 2, glm_vec3_tname);
+ vec3 *dest = luaL_checkudata(L, 3, glm_vec3_tname);
+ glm_mat3_mulv(*m, *v, *dest);
+ return 0;
+}
+
+
+int glm_mat3_quat_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_mat3_quat(*m, *dest);
+ return 0;
+}
+
+
+int glm_mat3_scale_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ float s = luaL_checknumber(L, 2);
+ glm_mat3_scale(*m, s);
+ return 0;
+}
+
+
+int glm_mat3_det_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ float bind_result = glm_mat3_det(*mat);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_mat3_inv_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_mat3_inv(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat3_trace_bind(lua_State *L)
+{
+ mat3 *m = luaL_checkudata(L, 1, glm_mat3_tname);
+ glm_mat3_trace(*m);
+ return 0;
+}
+
+
+int glm_mat3_swap_col_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ int col1 = luaL_checkinteger(L, 2);
+ int col2 = luaL_checkinteger(L, 3);
+ glm_mat3_swap_col(*mat, col1, col2);
+ return 0;
+}
+
+
+int glm_mat3_swap_row_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ int row1 = luaL_checkinteger(L, 2);
+ int row2 = luaL_checkinteger(L, 3);
+ glm_mat3_swap_row(*mat, row1, row2);
+ return 0;
+}
+
+
+int glm_mat3_rmc_bind(lua_State *L)
+{
+ vec3 *r = luaL_checkudata(L, 1, glm_vec3_tname);
+ mat3 *m = luaL_checkudata(L, 2, glm_mat3_tname);
+ vec3 *c = luaL_checkudata(L, 3, glm_vec3_tname);
+ float bind_result = glm_mat3_rmc(*r, *m, *c);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
diff --git a/src/glm/mat4.c b/src/glm/mat4.c
new file mode 100644
index 0000000..3083e5f
--- /dev/null
+++ b/src/glm/mat4.c
@@ -0,0 +1,244 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_mat4_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(mat4));
+ luaL_getmetatable(L, glm_mat4_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_mat4_set(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ float value = luaL_checknumber(L, 4);
+ (*m)[col][row] = value;
+ return 0;
+}
+
+
+int glm_mat4_get(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ int col = luaL_checkinteger(L, 2);
+ int row = luaL_checkinteger(L, 3);
+ lua_pushnumber(L, (*m)[col][row]);
+ return 1;
+}
+
+
+int glm_mat4_ucopy_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_ucopy(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_copy_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_copy(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_identity_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ glm_mat4_identity(*mat);
+ return 0;
+}
+
+
+int glm_mat4_zero_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ glm_mat4_zero(*mat);
+ return 0;
+}
+
+
+int glm_mat4_pick3_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_mat4_pick3(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_pick3t_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_mat4_pick3t(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_ins3_bind(lua_State *L)
+{
+ mat3 *mat = luaL_checkudata(L, 1, glm_mat3_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_ins3(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_mul_bind(lua_State *L)
+{
+ mat4 *m1 = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *m2 = luaL_checkudata(L, 2, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ glm_mat4_mul(*m1, *m2, *dest);
+ return 0;
+}
+
+
+int glm_mat4_mulv_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ vec4 *v = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_mat4_mulv(*m, *v, *dest);
+ return 0;
+}
+
+
+int glm_mat4_mulv3_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ vec3 *v = luaL_checkudata(L, 2, glm_vec3_tname);
+ float last = luaL_checknumber(L, 3);
+ vec3 *dest = luaL_checkudata(L, 4, glm_vec3_tname);
+ glm_mat4_mulv3(*m, *v, last, *dest);
+ return 0;
+}
+
+
+int glm_mat4_trace_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ glm_mat4_trace(*m);
+ return 0;
+}
+
+
+int glm_mat4_trace3_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ glm_mat4_trace3(*m);
+ return 0;
+}
+
+
+int glm_mat4_quat_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_mat4_quat(*m, *dest);
+ return 0;
+}
+
+
+int glm_mat4_transpose_to_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_transpose_to(*m, *dest);
+ return 0;
+}
+
+
+int glm_mat4_transpose_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ glm_mat4_transpose(*m);
+ return 0;
+}
+
+
+int glm_mat4_scale_p_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ float s = luaL_checknumber(L, 2);
+ glm_mat4_scale_p(*m, s);
+ return 0;
+}
+
+
+int glm_mat4_scale_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ float s = luaL_checknumber(L, 2);
+ glm_mat4_scale(*m, s);
+ return 0;
+}
+
+
+int glm_mat4_det_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ float bind_result = glm_mat4_det(*mat);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_mat4_inv_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_inv(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_inv_fast_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_mat4_inv_fast(*mat, *dest);
+ return 0;
+}
+
+
+int glm_mat4_swap_col_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ int col1 = luaL_checkinteger(L, 2);
+ int col2 = luaL_checkinteger(L, 3);
+ glm_mat4_swap_col(*mat, col1, col2);
+ return 0;
+}
+
+
+int glm_mat4_swap_row_bind(lua_State *L)
+{
+ mat4 *mat = luaL_checkudata(L, 1, glm_mat4_tname);
+ int row1 = luaL_checkinteger(L, 2);
+ int row2 = luaL_checkinteger(L, 3);
+ glm_mat4_swap_row(*mat, row1, row2);
+ return 0;
+}
+
+
+int glm_mat4_rmc_bind(lua_State *L)
+{
+ vec4 *r = luaL_checkudata(L, 1, glm_vec4_tname);
+ mat4 *m = luaL_checkudata(L, 2, glm_mat4_tname);
+ vec4 *c = luaL_checkudata(L, 3, glm_vec4_tname);
+ float bind_result = glm_mat4_rmc(*r, *m, *c);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
diff --git a/src/glm/quaternion.c b/src/glm/quaternion.c
new file mode 100644
index 0000000..408c3ca
--- /dev/null
+++ b/src/glm/quaternion.c
@@ -0,0 +1,352 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_quat_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(versor));
+ luaL_getmetatable(L, glm_versor_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_quat_identity_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ glm_quat_identity(*q);
+ return 0;
+}
+
+
+int glm_quat_init_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float x = luaL_checknumber(L, 2);
+ float y = luaL_checknumber(L, 3);
+ float z = luaL_checknumber(L, 4);
+ float w = luaL_checknumber(L, 5);
+ glm_quat_init(*q, x, y, z, w);
+ return 0;
+}
+
+
+int glm_quat_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float angle = luaL_checknumber(L, 2);
+ float x = luaL_checknumber(L, 3);
+ float y = luaL_checknumber(L, 4);
+ float z = luaL_checknumber(L, 5);
+ glm_quat(*q, angle, x, y, z);
+ return 0;
+}
+
+
+int glm_quatv_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float angle = luaL_checknumber(L, 2);
+ vec3 *axis = luaL_checkudata(L, 3, glm_vec3_tname);
+ glm_quatv(*q, angle, *axis);
+ return 0;
+}
+
+
+int glm_quat_copy_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_quat_copy(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_from_vecs_bind(lua_State *L)
+{
+ vec3 *a = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *b = luaL_checkudata(L, 2, glm_vec3_tname);
+ versor *dest = luaL_checkudata(L, 3, glm_versor_tname);
+ glm_quat_from_vecs(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_quat_norm_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float bind_result = glm_quat_norm(*q);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_quat_normalize_to_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_quat_normalize_to(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_normalize_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ glm_quat_normalize(*q);
+ return 0;
+}
+
+
+int glm_quat_dot_bind(lua_State *L)
+{
+ versor *p = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ float bind_result = glm_quat_dot(*p, *q);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_quat_conjugate_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_quat_conjugate(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_inv_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_quat_inv(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_add_bind(lua_State *L)
+{
+ versor *p = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 3, glm_versor_tname);
+ glm_quat_add(*p, *q, *dest);
+ return 0;
+}
+
+
+int glm_quat_sub_bind(lua_State *L)
+{
+ versor *p = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 3, glm_versor_tname);
+ glm_quat_sub(*p, *q, *dest);
+ return 0;
+}
+
+
+int glm_quat_real_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float bind_result = glm_quat_real(*q);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_quat_imag_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ vec3 *dest = luaL_checkudata(L, 2, glm_vec3_tname);
+ glm_quat_imag(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_imagn_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ vec3 *dest = luaL_checkudata(L, 2, glm_vec3_tname);
+ glm_quat_imagn(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_imaglen_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float bind_result = glm_quat_imaglen(*q);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_quat_angle_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ float bind_result = glm_quat_angle(*q);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_quat_axis_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 2, glm_versor_tname);
+ glm_quat_axis(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_mul_bind(lua_State *L)
+{
+ versor *p = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ versor *dest = luaL_checkudata(L, 3, glm_versor_tname);
+ glm_quat_mul(*p, *q, *dest);
+ return 0;
+}
+
+
+int glm_quat_mat4_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_quat_mat4(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_mat4t_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ mat4 *dest = luaL_checkudata(L, 2, glm_mat4_tname);
+ glm_quat_mat4t(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_mat3_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_quat_mat3(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_mat3t_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ mat3 *dest = luaL_checkudata(L, 2, glm_mat3_tname);
+ glm_quat_mat3t(*q, *dest);
+ return 0;
+}
+
+
+int glm_quat_lerp_bind(lua_State *L)
+{
+ versor *from = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *to = luaL_checkudata(L, 2, glm_versor_tname);
+ float t = luaL_checknumber(L, 3);
+ versor *dest = luaL_checkudata(L, 4, glm_versor_tname);
+ glm_quat_lerp(*from, *to, t, *dest);
+ return 0;
+}
+
+
+int glm_quat_nlerp_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *r = luaL_checkudata(L, 2, glm_versor_tname);
+ float t = luaL_checknumber(L, 3);
+ versor *dest = luaL_checkudata(L, 4, glm_versor_tname);
+ glm_quat_nlerp(*q, *r, t, *dest);
+ return 0;
+}
+
+
+int glm_quat_slerp_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ versor *r = luaL_checkudata(L, 2, glm_versor_tname);
+ float t = luaL_checknumber(L, 3);
+ versor *dest = luaL_checkudata(L, 4, glm_versor_tname);
+ glm_quat_slerp(*q, *r, t, *dest);
+ return 0;
+}
+
+
+int glm_quat_look_bind(lua_State *L)
+{
+ vec3 *eye = luaL_checkudata(L, 1, glm_vec3_tname);
+ versor *ori = luaL_checkudata(L, 2, glm_versor_tname);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ glm_quat_look(*eye, *ori, *dest);
+ return 0;
+}
+
+
+int glm_quat_for_bind(lua_State *L)
+{
+ vec3 *dir = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *up = luaL_checkudata(L, 2, glm_vec3_tname);
+ versor *dest = luaL_checkudata(L, 3, glm_versor_tname);
+ glm_quat_for(*dir, *up, *dest);
+ return 0;
+}
+
+
+int glm_quat_forp_bind(lua_State *L)
+{
+ vec3 *from = luaL_checkudata(L, 1, glm_vec3_tname);
+ vec3 *to = luaL_checkudata(L, 2, glm_vec3_tname);
+ vec3 *up = luaL_checkudata(L, 3, glm_vec3_tname);
+ versor *dest = luaL_checkudata(L, 4, glm_versor_tname);
+ glm_quat_forp(*from, *to, *up, *dest);
+ return 0;
+}
+
+
+int glm_quat_rotatev_bind(lua_State *L)
+{
+ versor *q = luaL_checkudata(L, 1, glm_versor_tname);
+ vec3 *v = luaL_checkudata(L, 2, glm_vec3_tname);
+ vec3 *dest = luaL_checkudata(L, 3, glm_vec3_tname);
+ glm_quat_rotatev(*q, *v, *dest);
+ return 0;
+}
+
+
+int glm_quat_rotate_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ mat4 *dest = luaL_checkudata(L, 3, glm_mat4_tname);
+ glm_quat_rotate(*m, *q, *dest);
+ return 0;
+}
+
+
+int glm_quat_rotate_at_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ vec3 *pivot = luaL_checkudata(L, 3, glm_vec3_tname);
+ glm_quat_rotate_at(*m, *q, *pivot);
+ return 0;
+}
+
+
+int glm_quat_rotate_atm_bind(lua_State *L)
+{
+ mat4 *m = luaL_checkudata(L, 1, glm_mat4_tname);
+ versor *q = luaL_checkudata(L, 2, glm_versor_tname);
+ vec3 *pivot = luaL_checkudata(L, 3, glm_vec3_tname);
+ glm_quat_rotate_atm(*m, *q, *pivot);
+ return 0;
+}
diff --git a/src/glm/setup.c b/src/glm/setup.c
index a36eeb1..6b91f0b 100644
--- a/src/glm/setup.c
+++ b/src/glm/setup.c
@@ -10,6 +10,7 @@ const char *glm_mat4_tname = "glm.mat4";
const char *glm_vec2_tname = "glm.vec2";
const char *glm_vec3_tname = "glm.vec3";
const char *glm_vec4_tname = "glm.vec4";
+const char *glm_versor_tname = "glm.versor";
void setup_glm(lua_State *L, int honey_index)
diff --git a/src/glm/vec2.c b/src/glm/vec2.c
new file mode 100644
index 0000000..dfba960
--- /dev/null
+++ b/src/glm/vec2.c
@@ -0,0 +1,359 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_vec2_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(vec2));
+ luaL_getmetatable(L, glm_vec2_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_vec2_set(lua_State *L)
+{
+ vec2 *vec = luaL_checkudata(L, 1, glm_vec2_tname);
+ int index = luaL_checkinteger(L, 2);
+ double value = luaL_checknumber(L, 3);
+ (*vec)[index] = value;
+ return 0;
+}
+
+
+int glm_vec2_get(lua_State *L)
+{
+ vec2 *vec = luaL_checkudata(L, 1, glm_vec2_tname);
+ int index = luaL_checkinteger(L, 2);
+ lua_pushnumber(L, (*vec)[index]);
+ return 1;
+}
+
+
+int glm_vec2_bind(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TUSERDATA);
+ float **v = lua_touserdata(L, 1);
+ vec2 *dest = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec2_copy_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2_copy(*a, *dest);
+ return 0;
+}
+
+
+int glm_vec2_zero_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ glm_vec2_zero(*v);
+ return 0;
+}
+
+
+int glm_vec2_one_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ glm_vec2_one(*v);
+ return 0;
+}
+
+
+int glm_vec2_dot_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ float bind_result = glm_vec2_dot(*a, *b);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec2_cross_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2_cross(*a, *b);
+ return 0;
+}
+
+
+int glm_vec2_norm2_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float bind_result = glm_vec2_norm2(*v);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec2_norm_bind(lua_State *L)
+{
+ vec2 *vec = luaL_checkudata(L, 1, glm_vec2_tname);
+ float bind_result = glm_vec2_norm(*vec);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec2_add_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_add(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_adds_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_adds(*a, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_sub_bind(lua_State *L)
+{
+ vec2 *v1 = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *v2 = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_sub(*v1, *v2, *dest);
+ return 0;
+}
+
+
+int glm_vec2_subs_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_subs(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_mul_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *d = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_mul(*a, *b, *d);
+ return 0;
+}
+
+
+int glm_vec2_scale_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_scale(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_scale_as_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_scale_as(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_div_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_div(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_divs_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_divs(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_addadd_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_addadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_subadd_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_subadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_muladd_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_muladd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_muladds_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ float s = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_muladds(*a, s, *dest);
+ return 0;
+}
+
+
+int glm_vec2_maxadd_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_maxadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_minadd_bind(lua_State *L)
+{
+ vec2 *a = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *b = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_minadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec2_negate_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ glm_vec2_negate(*v);
+ return 0;
+}
+
+
+int glm_vec2_negate_to_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2_negate_to(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec2_normalize_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ glm_vec2_normalize(*v);
+ return 0;
+}
+
+
+int glm_vec2_normalize_to_bind(lua_State *L)
+{
+ vec2 *vec = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2_normalize_to(*vec, *dest);
+ return 0;
+}
+
+
+int glm_vec2_rotate_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float angle = luaL_checknumber(L, 2);
+ vec2 *dest = luaL_checkudata(L, 2, glm_vec2_tname);
+ glm_vec2_rotate(*v, angle, *dest);
+ return 0;
+}
+
+
+int glm_vec2_distance2_bind(lua_State *L)
+{
+ vec2 *v1 = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *v2 = luaL_checkudata(L, 2, glm_vec2_tname);
+ float bind_result = glm_vec2_distance2(*v1, *v2);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec2_distance_bind(lua_State *L)
+{
+ vec2 *v1 = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *v2 = luaL_checkudata(L, 2, glm_vec2_tname);
+ float bind_result = glm_vec2_distance(*v1, *v2);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec2_maxv_bind(lua_State *L)
+{
+ vec2 *v1 = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *v2 = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_maxv(*v1, *v2, *dest);
+ return 0;
+}
+
+
+int glm_vec2_minv_bind(lua_State *L)
+{
+ vec2 *v1 = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *v2 = luaL_checkudata(L, 2, glm_vec2_tname);
+ vec2 *dest = luaL_checkudata(L, 3, glm_vec2_tname);
+ glm_vec2_minv(*v1, *v2, *dest);
+ return 0;
+}
+
+
+int glm_vec2_clamp_bind(lua_State *L)
+{
+ vec2 *v = luaL_checkudata(L, 1, glm_vec2_tname);
+ float minVal = luaL_checknumber(L, 2);
+ float maxVal = luaL_checknumber(L, 3);
+ glm_vec2_clamp(*v, minVal, maxVal);
+ return 0;
+}
+
+
+int glm_vec2_lerp_bind(lua_State *L)
+{
+ vec2 *from = luaL_checkudata(L, 1, glm_vec2_tname);
+ vec2 *to = luaL_checkudata(L, 2, glm_vec2_tname);
+ float t = luaL_checknumber(L, 3);
+ vec2 *dest = luaL_checkudata(L, 4, glm_vec2_tname);
+ glm_vec2_lerp(*from, *to, t, *dest);
+ return 0;
+}
diff --git a/src/glm/vec4.c b/src/glm/vec4.c
new file mode 100644
index 0000000..76e332d
--- /dev/null
+++ b/src/glm/vec4.c
@@ -0,0 +1,383 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <cglm/cglm.h>
+#include "glm.h"
+
+
+int glm_vec4_create(lua_State *L)
+{
+ lua_newuserdata(L, sizeof(vec4));
+ luaL_getmetatable(L, glm_vec4_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int glm_vec4_set(lua_State *L)
+{
+ vec4 *vec = luaL_checkudata(L, 1, glm_vec4_tname);
+ int index = luaL_checkinteger(L, 2);
+ double value = luaL_checknumber(L, 3);
+ (*vec)[index] = value;
+ return 0;
+}
+
+
+int glm_vec4_get(lua_State *L)
+{
+ vec4 *vec = luaL_checkudata(L, 1, glm_vec4_tname);
+ int index = luaL_checkinteger(L, 2);
+ lua_pushnumber(L, (*vec)[index]);
+ return 1;
+}
+
+
+int glm_vec4_bind(lua_State *L)
+{
+ vec3 *v3 = luaL_checkudata(L, 1, glm_vec3_tname);
+ float last = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4(*v3, last, *dest);
+ return 0;
+}
+
+
+int glm_vec4_copy3_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec3 *dest = luaL_checkudata(L, 2, glm_vec3_tname);
+ glm_vec4_copy3(*a, *dest);
+ return 0;
+}
+
+
+int glm_vec4_copy_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_copy(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec4_ucopy_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_ucopy(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec4_zero_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ glm_vec4_zero(*v);
+ return 0;
+}
+
+
+int glm_vec4_dot_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ float bind_result = glm_vec4_dot(*a, *b);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec4_norm2_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float bind_result = glm_vec4_norm2(*v);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec4_norm_bind(lua_State *L)
+{
+ vec4 *vec = luaL_checkudata(L, 1, glm_vec4_tname);
+ float bind_result = glm_vec4_norm(*vec);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec4_add_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_add(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_adds_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_adds(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_sub_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_sub(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_subs_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_subs(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_mul_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *d = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_mul(*a, *b, *d);
+ return 0;
+}
+
+
+int glm_vec4_scale_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_scale(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_scale_as_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_scale_as(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_div_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_div(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_divs_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_divs(*v, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_addadd_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_addadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_subadd_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_subadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_muladd_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_muladd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_muladds_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ float s = luaL_checknumber(L, 2);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_muladds(*a, s, *dest);
+ return 0;
+}
+
+
+int glm_vec4_maxadd_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_maxadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_minadd_bind(lua_State *L)
+{
+ vec4 *a = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *b = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_minadd(*a, *b, *dest);
+ return 0;
+}
+
+
+int glm_vec4_flipsign_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ glm_vec4_flipsign(*v);
+ return 0;
+}
+
+
+int glm_vec4_flipsign_to_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_flipsign_to(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec4_inv_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ glm_vec4_inv(*v);
+ return 0;
+}
+
+
+int glm_vec4_inv_to_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_inv_to(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec4_negate_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ glm_vec4_negate(*v);
+ return 0;
+}
+
+
+int glm_vec4_negate_to_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_negate_to(*v, *dest);
+ return 0;
+}
+
+
+int glm_vec4_normalize_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ glm_vec4_normalize(*v);
+ return 0;
+}
+
+
+int glm_vec4_normalize_to_bind(lua_State *L)
+{
+ vec4 *vec = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_normalize_to(*vec, *dest);
+ return 0;
+}
+
+
+int glm_vec4_distance_bind(lua_State *L)
+{
+ vec4 *v1 = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *v2 = luaL_checkudata(L, 2, glm_vec4_tname);
+ float bind_result = glm_vec4_distance(*v1, *v2);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glm_vec4_maxv_bind(lua_State *L)
+{
+ vec4 *v1 = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *v2 = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_maxv(*v1, *v2, *dest);
+ return 0;
+}
+
+
+int glm_vec4_minv_bind(lua_State *L)
+{
+ vec4 *v1 = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *v2 = luaL_checkudata(L, 2, glm_vec4_tname);
+ vec4 *dest = luaL_checkudata(L, 3, glm_vec4_tname);
+ glm_vec4_minv(*v1, *v2, *dest);
+ return 0;
+}
+
+
+int glm_vec4_clamp_bind(lua_State *L)
+{
+ vec4 *v = luaL_checkudata(L, 1, glm_vec4_tname);
+ float minVal = luaL_checknumber(L, 2);
+ float maxVal = luaL_checknumber(L, 3);
+ glm_vec4_clamp(*v, minVal, maxVal);
+ return 0;
+}
+
+
+int glm_vec4_lerp_bind(lua_State *L)
+{
+ vec4 *from = luaL_checkudata(L, 1, glm_vec4_tname);
+ vec4 *to = luaL_checkudata(L, 2, glm_vec4_tname);
+ float t = luaL_checknumber(L, 3);
+ vec4 *dest = luaL_checkudata(L, 4, glm_vec4_tname);
+ glm_vec4_lerp(*from, *to, t, *dest);
+ return 0;
+}
+
+
+int glm_vec4_cubic_bind(lua_State *L)
+{
+ float s = luaL_checknumber(L, 1);
+ vec4 *dest = luaL_checkudata(L, 2, glm_vec4_tname);
+ glm_vec4_cubic(s, *dest);
+ return 0;
+}