diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | demo/Camera.lua | 6 | ||||
-rw-r--r-- | demo/MeshInstance.lua | 6 | ||||
-rw-r--r-- | demo/Node.lua | 37 | ||||
-rw-r--r-- | demo/SignalManager.lua | 24 | ||||
-rw-r--r-- | demo/main.lua | 9 | ||||
-rw-r--r-- | src/glm_mat4_bindings.c | 2 | ||||
-rw-r--r-- | src/honey.c | 2 | ||||
-rw-r--r-- | src/scene_tree.h | 23 | ||||
-rw-r--r-- | src/scene_tree_node.c | 331 |
10 files changed, 55 insertions, 386 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bd7243..aeeb8ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ set(SOURCE_FILES src/mesh.c src/primitives.c src/shader.c - src/scene_tree_node.c src/texture.c src/window.c) diff --git a/demo/Camera.lua b/demo/Camera.lua index fda23f2..4f5c1fe 100644 --- a/demo/Camera.lua +++ b/demo/Camera.lua @@ -1,7 +1,9 @@ +local Node = require('Node') + local Camera = {} Camera.prototype = {} -setmetatable(Camera.prototype, { __index = honey.nodeMetatable.__index }) +setmetatable(Camera.prototype, { __index = Node.prototype }) Camera.prototype.updateView = function(self) self.basis = self.transform:basis() @@ -16,7 +18,7 @@ Camera.mt.__index = Camera.prototype -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Camera.new = function(parent, position, rotation, scale, fov, aspect, near, far) - local camera = honey.node(parent, position, rotation, scale) + local camera = Node.new(parent, position, rotation, scale) setmetatable(camera, Camera.mt) camera.view = honey.glm.mat4() diff --git a/demo/MeshInstance.lua b/demo/MeshInstance.lua index eceec5d..3e879e1 100644 --- a/demo/MeshInstance.lua +++ b/demo/MeshInstance.lua @@ -1,7 +1,9 @@ +local Node = require('Node') + local MeshInstance = {} MeshInstance.prototype = {} -setmetatable(MeshInstance.prototype, { __index = honey.nodeMetatable.__index }) +setmetatable(MeshInstance.prototype, { __index = Node.prototype }) MeshInstance.prototype.draw = function(self, camera, shader) local shader = shader or self.shader @@ -18,7 +20,7 @@ MeshInstance.mt.__index = MeshInstance.prototype -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MeshInstance.new = function(parent, position, rotation, scale, mesh, shader) - local meshinstance = honey.node(parent, position, rotation, scale) + local meshinstance = Node.new(parent, position, rotation, scale) meshinstance.mesh = mesh meshinstance.shader = shader diff --git a/demo/Node.lua b/demo/Node.lua index 5af745b..bfbfddd 100644 --- a/demo/Node.lua +++ b/demo/Node.lua @@ -1,6 +1,3 @@ -local Vector = require('Vector') -local Matrix = require('Matrix') - local Node = {} Node.prototype = {} @@ -10,11 +7,11 @@ Node.prototype.updateTransform = function(self) self.transform:translate(self.position) - self.transform:rotate(Vector.Vec3.ZERO, Vector.Vec3.Z_UNIT, self.rotation:at(2)) - self.transform:rotate(Vector.Vec3.ZERO, Vector.Vec3.Y_UNIT, self.rotation:at(1)) - self.transform:rotate(Vector.Vec3.ZERO, Vector.Vec3.X_UNIT, self.rotation:at(0)) + self.transform:rotateZ(self.rotation:get(2)) + self.transform:rotateY(self.rotation:get(1)) + self.transform:rotateX(self.rotation:get(0)) - self.transform:scale(self.scale) + self.transform:scalev(self.scale) if self.parent ~= nil then self.parent.transform:mul(self.transform, self.transform) @@ -50,16 +47,13 @@ Node.prototype.translate = function(self, translation) self.position:add(translation, self.position) end -Node.prototype.pitch = function(self, angle) - self.rotation:setAt(0, self.rotation:at(0) + angle) -end - -Node.prototype.yaw = function(self, angle) - self.rotation:setAt(1, self.rotation:at(1) + angle) -end +local rotationAxes = { x=0, y=1, z=2 } -Node.prototype.roll = function(self, angle) - self.rotation:setAt(2, self.rotation:at(2) + angle) +function Node.prototype.rotate(self, axis, angle) + local index = rotationAxes[axis] + print(index) + local oldAngle = self.rotation:get(index) + self.rotation:set(index, oldAngle + angle) end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -76,9 +70,14 @@ Node.new = function(parent, position, rotation, scale) node.parent = parent - node.position = position - node.rotation = rotation - node.scale = scale + if not position then node.position = honey.glm.vec3{0,0,0} + else node.position = position end + + if not rotation then node.rotation = honey.glm.vec3{0,0,0} + else node.rotation = rotation end + + if not scale then node.scale = honey.glm.vec3{1,1,1} + else node.scale = scale end node.children = {} diff --git a/demo/SignalManager.lua b/demo/SignalManager.lua new file mode 100644 index 0000000..b7e9d6b --- /dev/null +++ b/demo/SignalManager.lua @@ -0,0 +1,24 @@ +local SignalManager = {} +SignalManager.signals = {} + +function SignalManager.addCallback(self, signal, func) + if not self.signals[signal] then self.signals[signal] = {} end + self.signals[signal][func] = true +end + +function SignalManager.removeCallback(self, signal, func) + if self.signals[signal] then + self.signals[signal][func] = nil + end +end + +function SignalManager.emit(self, signal, argtable) + local sig = self.signals[signal] + if not sig then return end + + for f, _ in pairs(sig) do + f(argtable) + end +end + +return SignalManager diff --git a/demo/main.lua b/demo/main.lua index 3382d8d..d0695a6 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -1,3 +1,4 @@ +local Node = require('Node') local FPSCamera = require('FPSCamera') local SpatialShader = require('SpatialShader') local ScreenQuad = require('ScreenQuad') @@ -12,10 +13,7 @@ honey.input.key.bind(honey.input.key.f, function(action) if action == 1 then buf local tex = honey.texture.new() honey.texture.load(tex, 'checkerboard.png', false) -local sceneRoot = honey.node(nil, - honey.glm.vec3(), - honey.glm.vec3(), - honey.glm.vec3{1,1,1}) +local sceneRoot = Node.new() local shader = SpatialShader.new(tex) local lightDirection = honey.glm.vec3{1,1,1} @@ -43,7 +41,8 @@ local plane2 = MeshInstance.new(suzanne, shader) suzanne.update = function(self, dt) - self:rotate('y', dt) + self:rotate('y', 10*dt) + print(self.rotation) end local total_frames = 0 diff --git a/src/glm_mat4_bindings.c b/src/glm_mat4_bindings.c index 8320dcb..f27130b 100644 --- a/src/glm_mat4_bindings.c +++ b/src/glm_mat4_bindings.c @@ -57,7 +57,7 @@ int honey_glm_mat4_mul(lua_State* L) int choice = honey_lua_parse_arguments (L, 2, 2, HONEY_USERDATA, &self, HONEY_USERDATA, &mult, - 4, HONEY_USERDATA, &self, HONEY_USERDATA, &mult, HONEY_USERDATA, &dest); + 3, HONEY_USERDATA, &self, HONEY_USERDATA, &mult, HONEY_USERDATA, &dest); if (mult->type != MAT4) honey_lua_throw_error diff --git a/src/honey.c b/src/honey.c index 5f83544..dc716a4 100644 --- a/src/honey.c +++ b/src/honey.c @@ -131,8 +131,6 @@ bool honey_setup(lua_State** L) honey_setup_texture(*L); - honey_setup_scene_tree(*L); - lua_pushcfunction(*L, honey_exit); lua_setfield(*L, -2, "exit"); diff --git a/src/scene_tree.h b/src/scene_tree.h deleted file mode 100644 index ea1e37b..0000000 --- a/src/scene_tree.h +++ /dev/null @@ -1,23 +0,0 @@ -#include "common.h" - -/* @file Defines the basic scene tree nodes and functions to manipulate them. */ - -extern int honey_node_mt_ref; - -void honey_setup_scene_tree(lua_State* L); - -int honey_node_new(lua_State* L); - -int honey_node_update_transform(lua_State* L); - -int honey_node_update_cascade(lua_State* L); - -int honey_node_draw_cascade(lua_State* L); - -int honey_node_translate(lua_State* L); - -int honey_node_rotate(lua_State* L); - -int honey_node_scale(lua_State* L); - - diff --git a/src/scene_tree_node.c b/src/scene_tree_node.c deleted file mode 100644 index 87618e6..0000000 --- a/src/scene_tree_node.c +++ /dev/null @@ -1,331 +0,0 @@ -#include "scene_tree.h" -#include "glm_bindings.h" - -int honey_node_mt_ref = LUA_NOREF; - -void honey_setup_scene_tree(lua_State* L) -{ - honey_lua_create_table - (L, 1, - HONEY_TABLE, "__index", 6, - HONEY_FUNCTION, "updateTransform", honey_node_update_transform, - HONEY_FUNCTION, "updateCascade", honey_node_update_cascade, - HONEY_FUNCTION, "drawCascade", honey_node_draw_cascade, - HONEY_FUNCTION, "translate", honey_node_translate, - HONEY_FUNCTION, "rotate", honey_node_rotate, - HONEY_FUNCTION, "scale", honey_node_scale); - honey_node_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX); - - lua_rawgeti(L, LUA_REGISTRYINDEX, honey_node_mt_ref); - lua_setfield(L, -2, "nodeMetatable"); - - lua_pushcfunction(L, honey_node_new); - lua_setfield(L, -2, "node"); -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * Basic node functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_node_new(lua_State* L) -{ - honey_glm_array *position, *rotation, *scale; - honey_lua_parse_arguments - (L, 1, 4, - HONEY_ANY, NULL, - HONEY_USERDATA, &position, - HONEY_USERDATA, &rotation, - HONEY_USERDATA, &scale); - - lua_createtable(L, 5, 0); - - lua_rawgeti(L, LUA_REGISTRYINDEX, honey_node_mt_ref); - lua_setmetatable(L, -2); - - if (lua_istable(L, 1)) { - /* add self to parent.children */ - lua_getfield(L, 1, "children"); - int length = lua_objlen(L, -1); - - lua_pushinteger(L, length+1); - lua_pushvalue(L, -3); - lua_settable(L, -3); - lua_pop(L, 1); - - lua_pushvalue(L, 1); - lua_setfield(L, -2, "parent"); - } - - if (position->type != VEC3) - honey_lua_throw_error - (L, "position vector must be of type VEC3 (%d); got %d instead", - VEC3, position->type); - lua_pushvalue(L, 2); - lua_setfield(L, -2, "position"); - - if (rotation->type != VEC3) - honey_lua_throw_error - (L, "rotation vector must be of type VEC3 (%d); got %d instead", - VEC3, rotation->type); - lua_pushvalue(L, 3); - lua_setfield(L, -2, "rotation"); - - if (scale->type != VEC3) - honey_lua_throw_error - (L, "scale vector must be of type VEC3 (%d); got %d instead", - VEC3, scale->type); - lua_pushvalue(L, 4); - lua_setfield(L, -2, "scale"); - - /* create transform */ - lua_pushcfunction(L, honey_glm_new_mat4); - honey_lua_pcall(L, 0, 1); - - /* call honey.glm.eye() */ - lua_pushcfunction(L, honey_glm_mat4_eye); - lua_pushvalue(L, -2); - honey_lua_pcall(L, 1, 0); - - lua_setfield(L, -2, "transform"); - - /* call node:updateTransform() */ - lua_getfield(L, -1, "updateTransform"); - lua_pushvalue(L, -2); - honey_lua_pcall(L, 1, 0); - - /* create children */ - lua_createtable(L, 0, 0); - lua_setfield(L, -2, "children"); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_update_transform(lua_State* L) -{ - honey_lua_parse_arguments(L, 1, 1, HONEY_TABLE, NULL); - - honey_glm_array *transform, *position, *rotation, *parent_transform; - - lua_getfield(L, 1, "transform"); - transform = lua_touserdata(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "position"); - position = lua_touserdata(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "rotation"); - rotation = lua_touserdata(L, -1); - lua_pop(L, 1); - - glm_mat4_identity(transform->data); - - glm_translate(transform->data, position->data); - - glm_rotate_z(transform->data, rotation->data[2], transform->data); - glm_rotate_y(transform->data, rotation->data[1], transform->data); - glm_rotate_x(transform->data, rotation->data[0], transform->data); - - lua_getfield(L, 1, "parent"); - if (lua_istable(L, -1)) { - lua_getfield(L, -1, "transform"); - parent_transform = lua_touserdata(L, -1); - lua_pop(L, 1); - - glm_mat4_mul(parent_transform->data, transform->data, transform->data); - } - lua_pop(L, 1); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_update_cascade(lua_State* L) -{ - float dt; - honey_lua_parse_arguments(L, 1, 2, HONEY_TABLE, NULL, HONEY_NUMBER, &dt); - - /* call self.update if it exists */ - lua_getfield(L, 1, "update"); - if (!lua_isnil(L, -1)) { - lua_pushvalue(L, 1); - lua_pushnumber(L, dt); - honey_lua_pcall(L, 2, 0); - } - else - lua_pop(L, 1); - - lua_pushcfunction(L, honey_node_update_transform); - lua_pushvalue(L, 1); - honey_lua_pcall(L, 1, 0); - - /* update cascade for each child node */ - lua_getfield(L, 1, "children"); - int n_children = lua_objlen(L, -1); - for (int i=0; i<n_children; i++) { - lua_rawgeti(L, -1, i+1); - lua_pushcfunction(L, honey_node_update_cascade); - lua_pushvalue(L, -2); - lua_pushnumber(L, dt); - honey_lua_pcall(L, 2, 0); - lua_pop(L, 1); - } - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_draw_cascade(lua_State* L) -{ - int* shader; - int choice = honey_lua_parse_arguments - (L, 2, - 2, HONEY_TABLE, NULL, HONEY_TABLE, NULL, - 3, HONEY_TABLE, NULL, HONEY_TABLE, NULL, HONEY_USERDATA, &shader); - - /* call self.draw if it exists */ - lua_getfield(L, 1, "draw"); - if (!lua_isnil(L, -1)) { - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - if (choice == 1) { - lua_pushvalue(L, 3); - honey_lua_pcall(L, 3, 0); - } - else - honey_lua_pcall(L, 2, 0); - } - else - lua_pop(L, 1); - - /* draw cascade for each child node */ - lua_getfield(L, 1, "children"); - int n_children = lua_objlen(L, -1); - for (int i=0; i<n_children; i++) { - lua_rawgeti(L, -1, i+1); - lua_pushcfunction(L, honey_node_draw_cascade); - lua_pushvalue(L, -2); - lua_pushvalue(L, 2); - if (choice == 1) { - lua_pushvalue(L, 3); - honey_lua_pcall(L, 3, 0); - } - else - honey_lua_pcall(L, 2, 0); - lua_pop(L, 1); - } - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_translate(lua_State* L) -{ - honey_glm_array* position, *v; - honey_lua_parse_arguments(L, 1, 2, HONEY_TABLE, NULL, HONEY_USERDATA, &v); - - lua_getfield(L, 1, "position"); - position = lua_touserdata(L, -1); - lua_pop(L, 1); - - position->data[0] += v->data[0]; - position->data[1] += v->data[1]; - position->data[2] += v->data[2]; - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_rotate(lua_State* L) -{ - char* axisName; - float angle; - int index; - - honey_lua_parse_arguments - (L, 1, 3, - HONEY_TABLE, NULL, HONEY_STRING, &axisName, HONEY_NUMBER, &angle); - - switch (axisName[0]) { - case 'x': - index = 0; - break; - - case 'y': - index = 1; - break; - - case 'z': - index = 2; - break; - - default: - honey_lua_throw_error - (L, "axis string must be one of 'x', 'y', or 'z'; got '%s' instead", axisName); - } - - lua_getfield(L, 1, "rotation"); - honey_glm_array* rotation = lua_touserdata(L, -1); - lua_pop(L, 1); - - rotation->data[index] += angle; - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_node_scale(lua_State* L) -{ - char* axisName; - float s; - int index; - - int choice = honey_lua_parse_arguments - (L, 2, - 2, - HONEY_TABLE, NULL, HONEY_NUMBER, &s, - 3, - HONEY_TABLE, NULL, HONEY_STRING, &axisName, HONEY_NUMBER, &s); - - lua_getfield(L, 1, "scale"); - honey_glm_array* scale = lua_touserdata(L, -1); - lua_pop(L, 1); - - if (choice == 0) { - for (int i=0; i<3; i++) - scale->data[i] *= s; - } - else { - switch (axisName[0]) { - case 'x': - index = 0; - break; - - case 'y': - index = 1; - break; - - case 'z': - index = 2; - break; - - default: - honey_lua_throw_error - (L, "axis string must be one of 'x', 'y', or 'z'; got '%s' instead", axisName); - } - - scale->data[index] *= s; - } - - return 0; -} |