From f0a6a17e4fba3510c8ba8f6b114012873035a4a1 Mon Sep 17 00:00:00 2001 From: sanine-a Date: Tue, 27 Oct 2020 23:23:22 -0500 Subject: fix minor bugs, add cube primitive binding, and implement basic first-person camera --- demo/FPSCamera.lua | 94 +++++++++++++++++++++++++++++++++++++++++++++ demo/Matrix.lua | 65 ++++++++++++++++++------------- demo/Vector.lua | 13 +++++-- demo/main.lua | 41 +++++--------------- src/cglm_bindings.c | 34 ++++++++++++++-- src/cglm_bindings.h | 20 ++++++++++ src/primitives/primitives.c | 19 ++++++++- 7 files changed, 221 insertions(+), 65 deletions(-) create mode 100644 demo/FPSCamera.lua diff --git a/demo/FPSCamera.lua b/demo/FPSCamera.lua new file mode 100644 index 0000000..6b4e4f9 --- /dev/null +++ b/demo/FPSCamera.lua @@ -0,0 +1,94 @@ +local Vec3, Vec4 = require('Vector')() +local Mat3, Mat4 = require('Matrix')() + +local Basis = function(M) + local m = Mat3.new() + honey.cglm.mat4.pick3(M, m) + + local x0 = honey.cglm.get_value(m, Mat3.index(1,1)) + local x1 = honey.cglm.get_value(m, Mat3.index(2,1)) + local x2 = honey.cglm.get_value(m, Mat3.index(3,1)) + + local y0 = honey.cglm.get_value(m, Mat3.index(1,2)) + local y1 = honey.cglm.get_value(m, Mat3.index(2,2)) + local y2 = honey.cglm.get_value(m, Mat3.index(3,2)) + + local z0 = honey.cglm.get_value(m, Mat3.index(1,3)) + local z1 = honey.cglm.get_value(m, Mat3.index(2,3)) + local z2 = honey.cglm.get_value(m, Mat3.index(3,3)) + + local b = {} + b.x = Vec3.new{x0, x1, x2} + b.y = Vec3.new{y0, y1, y2} + b.z = Vec3.new{z0, z1, z2} + + return b +end + +local camera = {} + +camera.pitch = 0 +camera.yaw = 0 + +camera.sensitivity = 0.1 + +camera.movement_speed = 1 + +camera.position = Vec3.new{0,0,-1} + +camera.view = Mat4.new() +honey.cglm.mat4.identity(camera.view) + +camera.basis = Basis(camera.view) + +camera.projection = Mat4.new() +honey.cglm.camera.perspective( + camera.projection, + math.rad(90), + 640/480, + 0.1, + 8192) + +function camera:update() + local M = Mat4.new() + honey.cglm.mat4.identity(M) + honey.cglm.affine.rotate(M, Vec3.ZERO, self.basis.x, math.rad(self.pitch)) + honey.cglm.affine.rotate(M, Vec3.ZERO, Vec3.Y_UNIT, math.rad(self.yaw)) + self.basis = Basis(M) + + movement = Vec3.new() + if honey.input.key.is_down(honey.input.key.w) then honey.cglm.vec3.add(movement, self.basis.z, movement) end + if honey.input.key.is_down(honey.input.key.a) then honey.cglm.vec3.add(movement, self.basis.x, movement) end + if honey.input.key.is_down(honey.input.key.s) then honey.cglm.vec3.sub(movement, self.basis.z, movement) end + if honey.input.key.is_down(honey.input.key.d) then honey.cglm.vec3.sub(movement, self.basis.x, movement) end + + honey.cglm.set_value(movement, 1, 0) + honey.cglm.vec3.normalize(movement) + honey.cglm.vec3.muls(self.movement_speed, movement, movement) + honey.cglm.vec3.add(self.position, movement, self.position) + + honey.cglm.camera.look(self.position, self.basis.z, Vec3.Y_UNIT, self.view) +end + +camera.mouse_pos = {} +camera.mouse_pos.x = 0 +camera.mouse_pos.y = 0 + +honey.input.mouse.bind_movement( + function(xpos, ypos) + local dx = xpos - camera.mouse_pos.x + local dy = ypos - camera.mouse_pos.y + + camera.mouse_pos = { x=xpos, y=ypos } + + camera.pitch = camera.pitch + camera.sensitivity * dy + camera.yaw = camera.yaw - camera.sensitivity * dx + + if camera.pitch > 89 then camera.pitch = 89 end + if camera.pitch < -89 then camera.pitch = -89 end + end +) + +honey.input.mouse.set_mode(honey.input.mouse.mode.disabled) + +return camera diff --git a/demo/Matrix.lua b/demo/Matrix.lua index a78de65..11b704c 100644 --- a/demo/Matrix.lua +++ b/demo/Matrix.lua @@ -1,15 +1,19 @@ local Mat3 = {} +Mat3.index = function(i, j) + return (i-1) + 3*(j-1) +end + Mat3.tostring = function(mat) local str = '[ ['.. tostring(honey.cglm.get_value(mat, 0))..', '.. - tostring(honey.cglm.get_value(mat, 1))..', '.. - tostring(honey.cglm.get_value(mat, 2))..']\n ['.. tostring(honey.cglm.get_value(mat, 3))..', '.. + tostring(honey.cglm.get_value(mat, 6))..']\n ['.. + tostring(honey.cglm.get_value(mat, 1))..', '.. tostring(honey.cglm.get_value(mat, 4))..', '.. - tostring(honey.cglm.get_value(mat, 5))..']\n ['.. - tostring(honey.cglm.get_value(mat, 6))..', '.. - tostring(honey.cglm.get_value(mat, 7))..', '.. + tostring(honey.cglm.get_value(mat, 7))..']\n ['.. + tostring(honey.cglm.get_value(mat, 2))..', '.. + tostring(honey.cglm.get_value(mat, 5))..', '.. tostring(honey.cglm.get_value(mat, 8))..'] ]' return str end @@ -35,24 +39,18 @@ end local Mat4 = {} -Mat4.tostring = function(mat) - local str = '[ ['.. - tostring(honey.cglm.get_value(mat, 0))..', '.. - tostring(honey.cglm.get_value(mat, 1))..', '.. - tostring(honey.cglm.get_value(mat, 2))..', '.. - tostring(honey.cglm.get_value(mat, 3))..']\n ['.. - tostring(honey.cglm.get_value(mat, 4))..', '.. - tostring(honey.cglm.get_value(mat, 5))..', '.. - tostring(honey.cglm.get_value(mat, 6))..', '.. - tostring(honey.cglm.get_value(mat, 7))..']\n ['.. - tostring(honey.cglm.get_value(mat, 8))..', '.. - tostring(honey.cglm.get_value(mat, 9))..', '.. - tostring(honey.cglm.get_value(mat, 10))..', '.. - tostring(honey.cglm.get_value(mat, 11))..']\n ['.. - tostring(honey.cglm.get_value(mat, 12))..', '.. - tostring(honey.cglm.get_value(mat, 13))..', '.. - tostring(honey.cglm.get_value(mat, 14))..', '.. - tostring(honey.cglm.get_value(mat, 15))..'] ]' +Mat4.index = function(i, j) + return (i-1) + 4*(j-1) +end + +Mat4.tostring = function(matrix) + str = '' + for i = 1,4 do + for j = 1,4 do + str = str..tostring(honey.cglm.get_value(matrix, Mat4.index(i,j)))..', ' + end + str = str..'\n' + end return str end @@ -66,9 +64,24 @@ Mat4.new = function(tbl) end local mat4 = honey.cglm.new_array_zero(16) - for i = 0,15 do - honey.cglm.set_value(mat4, i, tbl[i+1]) - end + honey.cglm.set_value(mat4, 0, tbl[1]) + honey.cglm.set_value(mat4, 1, tbl[5]) + honey.cglm.set_value(mat4, 2, tbl[9]) + honey.cglm.set_value(mat4, 3, tbl[13]) + honey.cglm.set_value(mat4, 4, tbl[2]) + honey.cglm.set_value(mat4, 5, tbl[6]) + honey.cglm.set_value(mat4, 6, tbl[10]) + honey.cglm.set_value(mat4, 7, tbl[14]) + honey.cglm.set_value(mat4, 8, tbl[3]) + honey.cglm.set_value(mat4, 9, tbl[7]) + honey.cglm.set_value(mat4, 10, tbl[11]) + honey.cglm.set_value(mat4, 11, tbl[15]) + honey.cglm.set_value(mat4, 12, tbl[4]) + honey.cglm.set_value(mat4, 13, tbl[8]) + honey.cglm.set_value(mat4, 14, tbl[12]) + honey.cglm.set_value(mat4, 15, tbl[16]) + + setmetatable(mat4, Mat4.mt) return mat4 end diff --git a/demo/Vector.lua b/demo/Vector.lua index 752c927..89fd26a 100644 --- a/demo/Vector.lua +++ b/demo/Vector.lua @@ -2,9 +2,9 @@ local Vec3 = {} Vec3.tostring = function(vec3) local str = '['.. - tostring(honey.cglm.get_value(vec4, 0))..','.. - tostring(honey.cglm.get_value(vec4, 1))..','.. - tostring(honey.cglm.get_value(vec4, 2))..']' + tostring(honey.cglm.get_value(vec3, 0))..','.. + tostring(honey.cglm.get_value(vec3, 1))..','.. + tostring(honey.cglm.get_value(vec3, 2))..']' return str end @@ -19,12 +19,17 @@ Vec3.new = function(tbl) local vec3 = honey.cglm.new_array_zero(3) for i = 0,2 do - honey.cglm.set_value(data, i, tbl[i+1]) + honey.cglm.set_value(vec3, i, tbl[i+1]) end return vec3 end +Vec3.ZERO = Vec3.new() +Vec3.X_UNIT = Vec3.new{1, 0, 0} +Vec3.Y_UNIT = Vec3.new{0, 1, 0} +Vec3.Z_UNIT = Vec3.new{0, 0, 1} + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local Vec4 = {} diff --git a/demo/main.lua b/demo/main.lua index 1cb63d8..ec1a952 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -1,39 +1,17 @@ local Vec3, Vec4 = require('Vector')() local Mat3, Mat4 = require('Matrix')() +local FPSCamera = require('FPSCamera') -local m = Mat3.new{1, 0, 1, - 0, 1, 0, - 0, 0, 0} -print(Mat3.tostring(m)) +local model = Mat4.new() +honey.cglm.mat4.identity(model) +honey.cglm.affine.rotate(model, Vec3.ZERO, Vec3.X_UNIT, math.pi/4) honey.input.key.bind(honey.input.key.escape, honey.exit) -local basis = function(matrix) - local b = {} - b.x = Vec3.new{1, 0, 0} - b.y = Vec3.new{0, 1, 0} - b.z = Vec3.new{0, 0, 1} - - local mat3 = honey.cglm.new_array_zero(9) - honey.cglm.mat4.pick3(matrix, mat3) - - honey.cglm.mat3.mulv(b.x, mat3, b.x) - honey.cglm.mat3.mulv(b.y, mat3, b.y) - honey.cglm.mat3.mulv(b.z, mat3, b.z) - - return b -end - local vertex_shader = [[ #version 330 core layout(location = 0) in vec3 position; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec2 tex_coord; - -out vec2 uv_coord; -out vec3 v_normal; -out vec3 v_position; uniform mat4 model; uniform mat4 view; @@ -41,10 +19,7 @@ uniform mat4 projection; void main() { - gl_Position = projection * view * model * vec4(position.xyz, 1); - uv_coord = tex_coord; - v_normal = mat3(view) * normal; - v_position = vec3(view * model * vec4(position.xyz, 1.0)); + gl_Position = projection * view * vec4(position.xyz, 1); } ]] local fragment_shader = [[ #version 330 core @@ -54,7 +29,7 @@ out vec4 color; void main() { color = base_color; } ]] local shader = honey.shader.new(vertex_shader, fragment_shader) -local plane = honey.primitives.plane(2,2) +local plane = honey.primitives.cube(10,10,10) local color1 = Vec4.new{1,0,0,1} local color2 = Vec4.new{0,0,1,1} @@ -68,6 +43,10 @@ function honey.update(dt) end function honey.draw() + FPSCamera:update() + honey.shader.set_mat4(shader, 'model', model) + honey.shader.set_mat4(shader, 'view', FPSCamera.view) + honey.shader.set_mat4(shader, 'projection', FPSCamera.projection) honey.shader.set_vec4(shader, "base_color", color) honey.mesh.draw(plane, shader) end diff --git a/src/cglm_bindings.c b/src/cglm_bindings.c index f8f6c8a..947c394 100644 --- a/src/cglm_bindings.c +++ b/src/cglm_bindings.c @@ -8,6 +8,7 @@ void honey_setup_cglm(lua_State* L) { "norm", HONEY_FUNCTION, { .function = honey_cglm_vec3_norm } }, { "add", HONEY_FUNCTION, { .function = honey_cglm_vec3_add } }, { "adds", HONEY_FUNCTION, { .function = honey_cglm_vec3_adds } }, + { "sub", HONEY_FUNCTION, { .function = honey_cglm_vec3_sub } }, { "mul", HONEY_FUNCTION, { .function = honey_cglm_vec3_mul } }, { "muls", HONEY_FUNCTION, { .function = honey_cglm_vec3_muls } }, { "normalize", HONEY_FUNCTION, { .function = honey_cglm_vec3_normalize } }, @@ -21,6 +22,7 @@ void honey_setup_cglm(lua_State* L) { "norm", HONEY_FUNCTION, { .function = honey_cglm_vec4_norm } }, { "add", HONEY_FUNCTION, { .function = honey_cglm_vec4_add } }, { "adds", HONEY_FUNCTION, { .function = honey_cglm_vec4_adds } }, + { "sub", HONEY_FUNCTION, { .function = honey_cglm_vec4_sub } }, { "mul", HONEY_FUNCTION, { .function = honey_cglm_vec4_mul } }, { "muls", HONEY_FUNCTION, { .function = honey_cglm_vec4_muls } }, { "normalize", HONEY_FUNCTION, { .function = honey_cglm_vec4_normalize } }, @@ -69,15 +71,15 @@ void honey_setup_cglm(lua_State* L) { "set_value", HONEY_FUNCTION, { .function = honey_cglm_array_set_value } }, { "get_value", HONEY_FUNCTION, { .function = honey_cglm_array_get_value } }, { "copy_array", HONEY_FUNCTION, { .function = honey_cglm_array_copy } }, - { "vec3", HONEY_TABLE, { .table = { 10, vec3_elements } } }, - { "vec4", HONEY_TABLE, { .table = { 10, vec4_elements } } }, + { "vec3", HONEY_TABLE, { .table = { 11, vec3_elements } } }, + { "vec4", HONEY_TABLE, { .table = { 11, vec4_elements } } }, { "mat3", HONEY_TABLE, { .table = { 8, mat3_elements } } }, { "mat4", HONEY_TABLE, { .table = { 10, mat4_elements } } }, { "affine", HONEY_TABLE, { .table = { 3, affine_elements } } }, { "camera", HONEY_TABLE, { .table = { 3, camera_elements } } }, }; - honey_lua_create_table(L, cglm_elements, 9); + honey_lua_create_table(L, cglm_elements, 10); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -202,6 +204,19 @@ int honey_cglm_vec3_add(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +int honey_cglm_vec3_sub(lua_State* L) +{ + float* a, *b, *dest; + honey_lua_parse_arguments(L, 3, + HONEY_USERDATA, &a, + HONEY_USERDATA, &b, + HONEY_USERDATA, &dest); + glm_vec3_sub(a, b, dest); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + int honey_cglm_vec3_adds(lua_State* L) { float a, *v, *dest; @@ -359,6 +374,19 @@ int honey_cglm_vec4_adds(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +int honey_cglm_vec4_sub(lua_State* L) +{ + float* a, *b, *dest; + honey_lua_parse_arguments(L, 3, + HONEY_USERDATA, &a, + HONEY_USERDATA, &b, + HONEY_USERDATA, &dest); + glm_vec4_sub(a, b, dest); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + int honey_cglm_vec4_mul(lua_State* L) { float *a, *b, *dest; diff --git a/src/cglm_bindings.h b/src/cglm_bindings.h index ba7714e..61554e3 100644 --- a/src/cglm_bindings.h +++ b/src/cglm_bindings.h @@ -102,6 +102,16 @@ int honey_cglm_vec3_norm(lua_State* L); */ int honey_cglm_vec3_add(lua_State* L); +/** @brief Subtract one vector from another. + * + * @param[in] a The first vector. + * @param[in] b The second vector. + * @param[out] dest Vector to fill with a - b + * + * @returns Nothing. + */ +int honey_cglm_vec3_sub(lua_State* L); + /** @brief Add a scalar to a vector. * * @param[in] a The scalar. @@ -215,6 +225,16 @@ int honey_cglm_vec4_add(lua_State* L); */ int honey_cglm_vec4_adds(lua_State* L); +/** @brief Subtract one vector from another. + * + * @param[in] a The first vector. + * @param[in] b The second vector. + * @param[out] dest vec4 to fill with a - b. + * + * @returns Nothing. + */ +int honey_cglm_vec4_sub(lua_State* L); + /** @param Component-wise multiply two vectors together. * * @param[in] a The first vector. diff --git a/src/primitives/primitives.c b/src/primitives/primitives.c index 1bfbe14..8293d4d 100644 --- a/src/primitives/primitives.c +++ b/src/primitives/primitives.c @@ -15,13 +15,30 @@ static int honey_mesh_lua_plane(lua_State* L) return 1; } +static int honey_mesh_lua_cube(lua_State* L) +{ + float width, height, depth; + honey_lua_parse_arguments(L, 3, + HONEY_NUMBER, &width, + HONEY_NUMBER, &height, + HONEY_NUMBER, &depth); + + honey_mesh* mesh = lua_newuserdata(L, sizeof(honey_mesh)); + if (honey_mesh_new_textured_cube(mesh, width, height, depth) != HONEY_OK) { + lua_pushstring(L, "error encountered while building plane"); + lua_error(L); + } + return 1; +} + void honey_setup_primitives(lua_State* L) { honey_lua_element primitive_elements[] = { { "plane", HONEY_FUNCTION, { .function = honey_mesh_lua_plane } }, + { "cube", HONEY_FUNCTION, { .function = honey_mesh_lua_cube } }, }; - honey_lua_create_table(L, primitive_elements, 1); + honey_lua_create_table(L, primitive_elements, 2); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -- cgit v1.2.1