summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-03-16 12:12:39 -0500
committersanine <sanine.not@pm.me>2023-03-16 12:12:39 -0500
commitd94d9fb122e42264eca20bb037fe8a82290bd3e2 (patch)
tree7cb5b0ffd657ba69e193b4f2af6f1ddd3ec75ed2 /main.lua
parent7516044247663dabccc7db110703cfcf8545d95f (diff)
implement ecs node cascading
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua136
1 files changed, 104 insertions, 32 deletions
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()