From d94d9fb122e42264eca20bb037fe8a82290bd3e2 Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 16 Mar 2023 12:12:39 -0500 Subject: implement ecs node cascading --- main.lua | 136 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 32 deletions(-) (limited to 'main.lua') diff --git a/main.lua b/main.lua index 831aa54..9be332b 100644 --- a/main.lua +++ b/main.lua @@ -5,21 +5,73 @@ local glfw = honey.glfw local gl = honey.gl local Vec3 = honey.Vec3 local Mat4 = honey.Mat4 +local ecs = honey.ecs + + +-- camera matrices +local camera = { + view=Mat4.Identity(), + projection=Mat4(), +} +camera.view:translate(Vec3{0, 0, -3}) +camera.projection:perspective(math.rad(45), 640/480, 0.1, 100) + + + +function recursiveComputeTransform(entity) + if entity._transformComputed then + return entity._transform + end + if entity.parent == false then + entity._transformComputed = true + entity._transform = entity.transform + return entity.transform + end + + entity._transformComputed = true + local parentTransform = recursiveComputeTransform(entity.parent) + entity._transform = parentTransform * entity.transform + return entity._transform +end + +local world = ecs.World() +-- update transforms +world:addSystem{ + filter=ecs.Filter.AND{"transform", "parent"}, + update=function(entity, dt) + recursiveComputeTransform(entity) + end, + priority=1, +} +world:addSystem{ + filter=ecs.Filter.AND{"transform", "parent"}, + update=function(entity, dt) + entity._transform = nil + entity._transformComputed = false + end, + priority=0, +} + +-- render objects +world:addSystem{ + filter=ecs.Filter.AND{"mesh", "shader", "transform"}, + update=function(entity, dt) + entity.shader:use() + entity.shader:setMatrix('model', entity._transform) + entity.shader:setMatrix('view', camera.view) + entity.shader:setMatrix('projection', camera.projection) + entity.mesh:drawElements() + end, + priority=99, +} -local window = honey.init() -gl.Enable(gl.DEPTH_TEST) -local model = Mat4() -model:identity() -local view = Mat4() -view:identity() -view:translate(Vec3{0, 0, -3}) +local window = honey.init() +gl.Enable(gl.DEPTH_TEST) -local projection = Mat4() -projection:perspective(math.rad(45), 640/480, 0.1, 100) local vertexShaderSource = [[ @@ -75,40 +127,60 @@ local octa = honey.mesh.loadFile("assets/octahedron.obj")[1] local dodeca = honey.mesh.loadFile("assets/dodecahedron.obj")[1] local icosa = honey.mesh.loadFile("assets/icosahedron.obj")[1] -local meshes = { tetra, cube, octa, dodeca, icosa } -local meshIndex = 1 -local mesh = meshes[1] -window:setKeyCallback(function(_, key, scancode, action, mods) - if action ~= glfw.PRESS then return end +local tetraEntity = { + parent=false, + transform=Mat4.Identity(), + mesh=tetra, + shader=shader, +} + +local cubeEntity = { + parent=tetraEntity, + transform=Mat4.Identity(), + mesh=cube, + shader=shader, +} +cubeEntity.transform:translate(Vec3{2, 0, 0}) + +local octaEntity = { + parent=cubeEntity, + transform=Mat4.Identity(), + mesh=octa, + shader=shader, +} +octaEntity.transform:translate(Vec3{2, 0, 0}) + - if key == glfw.KEY_SPACE then - meshIndex = meshIndex + 1 - if meshIndex > #meshes then meshIndex = 1 end - mesh = meshes[meshIndex] - elseif key == glfw.KEY_ESCAPE then - window:setShouldClose(true) - end -end) +world:addEntity(tetraEntity) +world:addEntity(cubeEntity) +world:addEntity(octaEntity) + + + +local prevTime = 0 while not window:shouldClose() do local time = glfw.GetTime() - model:identity() - model:rotateY(0.5 * math.pi * time) - model:rotateX(0.05 * math.pi * time) + local dt = time - prevTime + prevTime = time + + tetraEntity.transform:identity() + tetraEntity.transform:rotateY(0.5 * math.pi * time) + tetraEntity.transform:rotateX(0.05 * math.pi * time) --model:scale(0.2 * Vec3{1, 1, 1}) - gl.ClearColor(0.2, 0.4, 1.0, 1.0) - gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT) + cubeEntity.transform:identity() + cubeEntity.transform:translate(Vec3{2, 0, 0}) + cubeEntity.transform:rotateY(0.3 * math.pi * time) + cubeEntity.transform:rotateX(0.08 * math.pi * time) - shader:use() - shader:setMatrix('model', model) - shader:setMatrix('view', view) - shader:setMatrix('projection', projection) - mesh:drawElements() + gl.ClearColor(0.2, 0.4, 1.0, 1.0) + gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT) + world:update(dt) window:swapBuffers() glfw.PollEvents() -- cgit v1.2.1