summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-03-29 00:46:16 -0500
committersanine <sanine.not@pm.me>2023-03-29 00:46:16 -0500
commitee3b19aa4f0ec65c159a31d589bbafd4a644610e (patch)
treec8052c53c0e486daeaec241f3463e4582a68b8d6 /main.lua
parent5a93fb6f6a8fb6f1dad821b407b4f4531bc23783 (diff)
re-implement recursive transform system
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua150
1 files changed, 113 insertions, 37 deletions
diff --git a/main.lua b/main.lua
index f13a1a6..38556ca 100644
--- a/main.lua
+++ b/main.lua
@@ -20,51 +20,74 @@ local november = nvg.CreateFont(vg, "November", "assets/november.regular.ttf")
local vw, vh = 640, 480
--- create camera matrices
-local camera = {
- view=Mat4():identity():translate(Vec3{0, 0, -3}),
+-- setup ecs
+local edb = ecs.EntityDb()
+local sdb = ecs.SystemDb()
+
+local camera = edb:createEntity()
+edb:addComponent(camera, "camera", {
projection=Mat4():perspective(math.rad(45), 640/480, 0.1, 100),
+})
+edb:addComponent(camera, "transform", {
+ matrix=Mat4():identity():translate(Vec3{0, 0, -6}),
+})
+
+
+sdb:addSystem{
+ update = function(self, dt)
+ local transform = edb:getComponent(camera, "transform")
+ transform.matrix:translate(Vec3{0, 0, -0.2*math.sin(math.pi * glfw.GetTime())})
+ end
}
+sdb:addSystem{
+ update = function(self, dt)
+ local entities = self.db:queryComponent("transform")
--- close window on ESCAPE key
-window:setKeyCallback(function(_, key, scancode, action)
- if action == glfw.PRESS then
- if key == glfw.KEY_ESCAPE then
- window:setShouldClose(true)
+ -- prepare transforms
+ for id, transform in pairs(entities) do
+ transform._visited = false
end
- end
-end)
--- resize window correctly
-window:setFramebufferSizeCallback(function(_, width, height)
- gl.Viewport(0, 0, width, height)
- camera.projection:perspectiveResize(width/height)
- vw, vh = width, height
-end)
-
--- averager (for fps)
-function averager(memory)
- local buf = {}
- local avg = 0
- for i=1,memory do table.insert(buf, 0) end
- return function(value)
- table.insert(buf, value)
- local val = table.remove(buf, 1)
- avg = avg + value - val
- return avg / memory
- end
-end
-local fpsAverage = averager(200)
+ -- helper function
+ local function recursiveTransform(transform)
+ if transform._visited then
+ return transform._matrix
+ end
+ if not transform.parent then
+ transform._matrix = transform.matrix
+ else
+ local parentTransform = self.db:getComponent(transform.parent, "transform")
+ local parentMatrix = recursiveTransform(parentTransform)
+ transform._matrix = parentMatrix * transform.matrix
+ end
+ transform._visited = true
+ return transform._matrix
+ end
--- setup ecs
-local edb = ecs.EntityDb()
-local sdb = ecs.SystemDb()
+ -- compute transforms
+ for id, transform in pairs(entities) do
+ recursiveTransform(transform)
+ end
+ end,
+ db = edb,
+ priority = 0,
+}
sdb:addSystem{
+ camera = camera,
update = function(self, dt)
+ local cameraParams = self.db:getComponent(camera, "camera")
+ local cameraTransform = self.db:getComponent(camera, "transform")
+ local view
+ if cameraTransform then
+ view = cameraTransform._matrix
+ else
+ view = Mat4():identity()
+ end
+
local entities = self.db:queryComponent("renderMesh")
for entity, tbl in pairs(entities) do
-- get shader
@@ -73,7 +96,7 @@ sdb:addSystem{
-- bind textures
local texOffset = 0
- for name, texTbl in pairs(tbl.textures) do
+ for name, texTbl in pairs(tbl.textures or {}) do
local texture = honey.image.loadImage(texTbl.filename, texTbl.params)
gl.BindTexture(gl.TEXTURE_2D + texOffset, texture.texture)
shader:setInt(name, texOffset)
@@ -81,14 +104,16 @@ sdb:addSystem{
end
-- configure default uniforms
+ local query = self.db:getComponent(entity, "transform")
+ local model = (query and query._matrix) or Mat4():identity()
shader:configure{
float={
time=glfw.GetTime(),
},
matrix={
- view=camera.view,
- projection=camera.projection,
- model=Mat4():identity(),
+ view=view,
+ projection=cameraParams.projection,
+ model=model,
},
}
@@ -115,7 +140,58 @@ edb:addComponent(id, "renderMesh", {
shader = { vertex="vertex.glsl", fragment="fragment.glsl" },
mesh = { filename="assets/icosahedron.obj", index=1 },
})
+edb:addComponent(id, "transform", {
+ matrix = Mat4():identity():rotateZ(math.rad(45)),
+})
+sdb:addSystem{
+ update = function(self, dt)
+ local transform = edb:getComponent(id, "transform")
+ transform.matrix:rotateZ(math.pi * dt)
+ end,
+}
+local id2 = edb:createEntity()
+edb:addComponent(id2, "renderMesh", {
+ shader = { vertex="vertex.glsl", fragment="fragment.glsl" },
+ mesh = { filename="assets/tetrahedron.obj", index=1 },
+})
+edb:addComponent(id2, "transform", {
+ parent=id,
+ matrix=Mat4():identity():translate(Vec3{0, 2, 0}),
+})
+
+
+
+-- close window on ESCAPE key
+window:setKeyCallback(function(_, key, scancode, action)
+ if action == glfw.PRESS then
+ if key == glfw.KEY_ESCAPE then
+ window:setShouldClose(true)
+ end
+ end
+end)
+
+-- resize window correctly
+window:setFramebufferSizeCallback(function(_, width, height)
+ gl.Viewport(0, 0, width, height)
+ local cameraParams = edb:getComponent(camera, "camera")
+ cameraParams.projection:perspectiveResize(width/height)
+ vw, vh = width, height
+end)
+
+-- averager (for fps)
+function averager(memory)
+ local buf = {}
+ local avg = 0
+ for i=1,memory do table.insert(buf, 0) end
+ return function(value)
+ table.insert(buf, value)
+ local val = table.remove(buf, 1)
+ avg = avg + value - val
+ return avg / memory
+ end
+end
+local fpsAverage = averager(200)
-- main loop