local ecs = require 'honey.ecs' local gl = honey.gl local glfw = honey.glfw local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) --===== transform cascading =====-- transform = function(params) return { db = params.db, update = function(self, dt) local entities = self.db:queryComponent("transform") -- prepare transforms for id, transform in pairs(entities) do transform._visited = false end -- 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 -- compute transforms for id, transform in pairs(entities) do recursiveTransform(transform) end end, priority = 0, } end --===== rendering =====-- function renderCamera(params) return { camera = params.camera, db = params.db, priority = params.priority or 99, update = function(self, dt) local cameraParams = self.db:getComponent(self.camera, "camera") local cameraTransform = self.db:getComponent(self.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 local shader = honey.shader.loadShader(tbl.shader.vertex, tbl.shader.fragment) shader:use() -- bind textures local texOffset = 0 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) texOffset = texOffset + 1 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=view, projection=cameraParams.projection, model=model, }, } -- draw mesh local mesh = honey.mesh.loadMesh(tbl.mesh.filename, tbl.mesh.index) mesh:drawElements() -- unbind textures for i=0,texOffset-1 do gl.BindTexture(gl.TEXTURE_2D + i, 0) end end end, } end --===== update functions =====-- --===== script system =====-- script = function(params) return { db=params.db, update=function(self, dt) local entities = self.db:queryComponent("script") for id, script in pairs(entities) do local f = require(script.name) f(self.db, id, dt) end end } end return module