diff options
author | sanine-a <sanine.not@pm.me> | 2020-11-29 22:38:45 -0600 |
---|---|---|
committer | sanine-a <sanine.not@pm.me> | 2020-11-29 22:38:45 -0600 |
commit | 306e6cca8e49638779b111d66852877416971a59 (patch) | |
tree | 0faaf9087b9acaa8a74ff2716ad2b406e4dfc526 | |
parent | 8a75194c51a189f9c8f72d9821beb00b7f75d06d (diff) |
add camera functions and fix bug in argument parsing
-rw-r--r-- | demo/main.lua | 96 | ||||
-rw-r--r-- | src/glm_bindings.c | 6 | ||||
-rw-r--r-- | src/glm_bindings.h | 8 | ||||
-rw-r--r-- | src/glm_mat4_bindings.c | 98 | ||||
-rw-r--r-- | src/honey_lua.c | 142 |
5 files changed, 179 insertions, 171 deletions
diff --git a/demo/main.lua b/demo/main.lua index 660614d..ec5746a 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -1,95 +1,3 @@ -local Vector = require('Vector') -local Matrix = require('Matrix') -local FPSCamera = require('FPSCamera') -local Node = require('Node') -local SpatialShader = require('SpatialShader') -local ScreenQuad = require('ScreenQuad') -local MeshInstance = require('MeshInstance') -FPSCamera.movement_speed = 5 +local v = honey.glm.vec3() -honey.input.key.bind(honey.input.key.escape, honey.exit) - -local buffer = false -honey.input.key.bind(honey.input.key.f, function(action) if action == 1 then buffer = not buffer end end) - -local tex = honey.texture.new() -honey.texture.load(tex, 'checkerboard.png', false) - -local sceneRoot = Node.new(nil, - Vector.Vec3.new(), - Vector.Vec3.new(), - Vector.Vec3.new{1,1,1}) - -local shader = SpatialShader.new(tex) -local lightDirection = Vector.Vec3.new{1,1,1} -lightDirection:normalize() -shader:setVec3('directional_lights[0].direction', lightDirection) -shader:setVec3('directional_lights[0].color', Vector.Vec3.new{0,1,0}) -local meshes = honey.mesh.load('Suzanne.obj') -print(#meshes) -local suzanne = MeshInstance.new(sceneRoot, - Vector.Vec3.new{0,0,-3}, - Vector.Vec3.new{0,math.pi,0}, - Vector.Vec3.new{0.5,1,0.5}, - meshes[1], - shader) -local plane = MeshInstance.new(suzanne, - Vector.Vec3.new{1,0,0}, - Vector.Vec3.new{0,0,0}, - Vector.Vec3.new{1,1,1}, - honey.primitives.plane(4,4), - shader) -local plane2 = MeshInstance.new(suzanne, - Vector.Vec3.new{5,0,0}, - Vector.Vec3.new{0,math.pi,0}, - Vector.Vec3.new{1,1,1}, - honey.primitives.plane(4,4), - shader) - -suzanne.update = function(self, dt) - --local angle = dt * math.pi - --self:yaw(angle) -end - -local total_frames = 0 -local total_time = 0 - -honey.window.set_size(640, 480) - -function honey.update(dt) - total_time = total_time + dt - FPSCamera:update(dt) - sceneRoot:updateCascade(dt) - if total_time > 1 then - print('FPS: '..tostring(total_frames/total_time)) - total_time = 0 - total_frames = 0 - end -end - -function draw_suzanne() - sceneRoot:drawCascade(FPSCamera) -end - -function honey.draw() - total_frames = total_frames + 1 - - if buffer then - honey.set_framebuffer(ScreenQuad.fb) - honey.set_viewport_size(480,640) - honey.clear_color(Vector.Vec4.new().array, true, true, false) - honey.enable_depth_test(true) - draw_suzanne() - - honey.set_framebuffer(0) - honey.set_viewport_size(640, 480) - honey.enable_depth_test(false) - honey.clear_color(Vector.Vec4.new{0,0,1,1}.array, true, false, false) - ScreenQuad:draw() - else - honey.clear_color(Vector.Vec4.new{1,1,0,1}.array, true, true, false) - honey.set_viewport_size(640, 480) - honey.enable_depth_test(true) - draw_suzanne() - end -end +v.dot(v, v) diff --git a/src/glm_bindings.c b/src/glm_bindings.c index 41e1d4d..a3ce419 100644 --- a/src/glm_bindings.c +++ b/src/glm_bindings.c @@ -87,7 +87,7 @@ void honey_setup_glm(lua_State* L) honey_lua_create_table (L, 2, - HONEY_TABLE, "__index", 16, + HONEY_TABLE, "__index", 21, HONEY_FUNCTION, "copy", honey_glm_mat4_copy, HONEY_FUNCTION, "eye", honey_glm_mat4_eye, HONEY_FUNCTION, "zero", honey_glm_mat4_zero, @@ -105,6 +105,10 @@ void honey_setup_glm(lua_State* L) HONEY_FUNCTION, "rotateY", honey_glm_rotate_y, HONEY_FUNCTION, "rotateZ", honey_glm_rotate_z, HONEY_FUNCTION, "rotate", honey_glm_rotate, + HONEY_FUNCTION, "perspective", honey_glm_perspective, + HONEY_FUNCTION, "perspectiveResize", honey_glm_perspective_resize, + HONEY_FUNCTION, "lookAt", honey_glm_lookat, + HONEY_FUNCTION, "look", honey_glm_look, HONEY_FUNCTION, "__gc", honey_glm_array_destroy); honey_glm_mat4_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX); diff --git a/src/glm_bindings.h b/src/glm_bindings.h index c9eaa91..6c1898f 100644 --- a/src/glm_bindings.h +++ b/src/glm_bindings.h @@ -188,4 +188,12 @@ int honey_glm_rotate_z(lua_State* L); int honey_glm_rotate(lua_State* L); +int honey_glm_perspective(lua_State* L); + +int honey_glm_perspective_resize(lua_State* L); + +int honey_glm_lookat(lua_State* L); + +int honey_glm_look(lua_State* L); + #endif diff --git a/src/glm_mat4_bindings.c b/src/glm_mat4_bindings.c index f10f954..460cde2 100644 --- a/src/glm_mat4_bindings.c +++ b/src/glm_mat4_bindings.c @@ -397,3 +397,101 @@ int honey_glm_rotate(lua_State* L) return 0; } +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Camera functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +int honey_glm_perspective(lua_State* L) +{ + honey_glm_array *self; + float fov, aspect, near, far; + honey_lua_parse_arguments + (L, 1, 5, + HONEY_USERDATA, &self, + HONEY_NUMBER, &fov, HONEY_NUMBER, &aspect, + HONEY_NUMBER, &near, HONEY_NUMBER, &far); + + glm_perspective(fov, aspect, near, far, self->data); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_glm_perspective_resize(lua_State* L) +{ + honey_glm_array *self; + float new_aspect; + honey_lua_parse_arguments + (L, 1, 2, HONEY_USERDATA, &self, HONEY_NUMBER, new_aspect); + + glm_perspective_resize(new_aspect, self->data); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_glm_lookat(lua_State* L) +{ + honey_glm_array *self, *eye, *center, *up; + honey_lua_parse_arguments + (L, 1, 4, + HONEY_USERDATA, &self, + HONEY_USERDATA, &eye, + HONEY_USERDATA, ¢er, + HONEY_USERDATA, &up); + + if (eye->type != VEC3) + honey_lua_throw_error + (L, "eye vector must be of type VEC3 (%d); got %d instead", + VEC3, eye->type); + + if (center->type != VEC3) + honey_lua_throw_error + (L, "center vector must be of type VEC3 (%d); got %d instead", + VEC3, center->type); + + if (up->type != VEC3) + honey_lua_throw_error + (L, "up vector must be of type VEC3 (%d); got %d instead", + VEC3, up->type); + + glm_lookat(eye->data, center->data, up->data, self->data); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_glm_look(lua_State* L) +{ + honey_glm_array *self, *eye, *dir, *up; + honey_lua_parse_arguments + (L, 1, 4, + HONEY_USERDATA, &self, + HONEY_USERDATA, &eye, + HONEY_USERDATA, &dir, + HONEY_USERDATA, &up); + + if (eye->type != VEC3) + honey_lua_throw_error + (L, "eye vector must be of type VEC3 (%d); got %d instead", + VEC3, eye->type); + + if (dir->type != VEC3) + honey_lua_throw_error + (L, "direction vector must be of type VEC3 (%d); got %d instead", + VEC3, dir->type); + + if (up->type != VEC3) + honey_lua_throw_error + (L, "up vector must be of type VEC3 (%d); got %d instead", + VEC3, up->type); + + glm_look(eye->data, dir->data, up->data, self->data); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + diff --git a/src/honey_lua.c b/src/honey_lua.c index 2469d37..72624be 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -25,8 +25,7 @@ struct argument_list { */ /* string must be able to hold at least 16 characters. */ -static int type_to_string(char* string, - honey_lua_type type); +static const char* type_to_string(honey_lua_type type); static bool check_argument(lua_State* L, honey_lua_type type, @@ -100,34 +99,6 @@ void honey_lua_throw_error(lua_State* L, * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static void honey_lua_arg_error(lua_State* L, - honey_lua_type type, - int position) -{ - char expected_type[16]; - type_to_string(expected_type, type); - - char* error_message; - honey_result result; - char* got_type = (char*) lua_typename(L, lua_type(L, position)); - result = honey_format_string(&error_message, - "bad argument in position %d: " - "expected %s, but got %s instead.", - position, - expected_type, - got_type); - if (result != HONEY_OK) { - lua_pushstring(L, "error allocating memory for error message :("); - } - else { - lua_pushstring(L, error_message); - free(error_message); - } - lua_error(L); -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - static bool check_arg_list(lua_State* L, struct argument_list arg_list) { @@ -141,28 +112,22 @@ static bool check_arg_list(lua_State* L, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static int arg_list_to_string(char* string, - int start_index, +static void arg_list_to_string(char** string, struct argument_list arg_list) { struct argument_pair* args = arg_list.args; - string[start_index] = '('; + size_t size = sizeof(char) * (18*arg_list.length + 5); + *string = malloc(size); + + memcpy(*string, "(", 2); - int index = start_index + 1; - for (int i=0; i<arg_list.length; i++) { - index += type_to_string(string + index, args[i].type); - if (i != arg_list.length - 1) { - string[index + 1] = ','; - string[index + 2] = ' '; - index += 2; - } + strcat(*string, type_to_string(args[i].type)); + if (i != arg_list.length-1) + strcat(*string, ", "); } - - string[index] = ')'; - - return index+1; + strcat(*string, ")"); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -176,19 +141,41 @@ static void arg_lists_to_string(char** string, size += 18*arg_lists[i].length + 5; *string = calloc(size, sizeof(char)); - int index = 0; + + char* arg_list_string; for (int i=0; i<n; i++) { - index = arg_list_to_string(*string, index, arg_lists[i]); - if (i != n) { - *string[index] = '\n'; - index++; - } + arg_list_to_string(&arg_list_string, arg_lists[i]); + strcat(*string, arg_list_string); + free(arg_list_string); + if (i != n-1) + strcat(*string, "\n"); } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +static void arguments_to_string(lua_State* L, char** string) +{ + unsigned int argc = lua_gettop(L); + + size_t size = sizeof(char) * (18*argc + 5); + *string = malloc(size); + + memcpy(*string, "(", 2); + + char type_string[16]; + for (int i=0; i<argc; i++) { + int type = lua_type(L, i+1); + strncat(*string, lua_typename(L, type), 16*sizeof(char)); + if (i != argc-1) + strncat(*string, ", ", 4*sizeof(char)); + } + strncat(*string, ")", 4); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + static void get_arg_list(lua_State* L, struct argument_list arg_list) { @@ -218,6 +205,9 @@ int honey_lua_parse_arguments(lua_State* L, unsigned int n, ...) for (int j=0; j<arg_lists[i].length; j++) { honey_lua_type type = va_arg(args, honey_lua_type); void* destination = va_arg(args, void*); + + arg_lists[i].args[j].type = type; + arg_lists[i].args[j].ptr = destination; } } @@ -233,7 +223,18 @@ int honey_lua_parse_arguments(lua_State* L, unsigned int n, ...) } if (index == n) { - /* no arguments match, throw error */ + char* arg_lists_str, *argv, *error; + arg_lists_to_string(&arg_lists_str, n, arg_lists); + arguments_to_string(L, &argv); + honey_format_string + (&error, + "expected arguments of the form\n%s\nbut received\n%s", + arg_lists_str, argv); + lua_pushstring(L, error); + free(arg_lists_str); + free(argv); + free(error); + lua_error(L); } @@ -383,57 +384,46 @@ int honey_exit(lua_State* L) */ /* string must be able to hold at least 16 characters. */ -static int type_to_string(char* string, - honey_lua_type type) +static const char* type_to_string(honey_lua_type type) { switch(type) { case HONEY_BOOLEAN: - memcpy(string, "boolean", 8); - return 7; + return "boolean"; case HONEY_INTEGER: - memcpy(string, "integer", 8); - return 7; + return "integer"; case HONEY_NUMBER: - memcpy(string, "number", 7); - return 6; + return "number"; case HONEY_STRING: - memcpy(string, "string", 7); - return 6; + return "string"; case HONEY_FUNCTION: - memcpy(string, "function", 9); - return 8; + return "function"; case HONEY_TABLE: - memcpy(string, "table", 6); - return 5; + return "table"; case HONEY_NIL: - memcpy(string, "nil", 4); - return 3; + return "nil"; case HONEY_USERDATA: - memcpy(string, "userdata", 9); - return 8; + return "userdata"; case HONEY_LIGHTUSERDATA: - memcpy(string, "light userdata", 16); - return 15; + return "light userdata"; case HONEY_ANY: - memcpy(string, "any", 4); - return 3; + return "any"; default: - return 0; + return "ERROR"; } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - + static bool check_argument(lua_State* L, honey_lua_type type, int index) |