summaryrefslogtreecommitdiff
path: root/honey/ecs
diff options
context:
space:
mode:
Diffstat (limited to 'honey/ecs')
-rw-r--r--honey/ecs/ecs.lua6
-rw-r--r--honey/ecs/node.lua77
-rw-r--r--honey/ecs/render.lua144
-rw-r--r--honey/ecs/script.lua28
4 files changed, 113 insertions, 142 deletions
diff --git a/honey/ecs/ecs.lua b/honey/ecs/ecs.lua
index d7eb4ac..0c84041 100644
--- a/honey/ecs/ecs.lua
+++ b/honey/ecs/ecs.lua
@@ -77,11 +77,9 @@ end
-- load database from file
function EntityDb.load(self, filename)
- print(collectgarbage("count"))
self.entities = {}
self.components = {}
collectgarbage()
- print(collectgarbage("count"))
local env = {
Entity = function(id, components)
self:createEntity(id)
@@ -320,7 +318,6 @@ function SystemDb.update(self, dt)
-- check for dangling dependencies
local dangle = ""
for dependency in pairs(self.dangling) do
- print(dependency)
dangle = dangle .. string.format(
"unresolved dangling dependency: %s\n",
dependency
@@ -330,11 +327,10 @@ function SystemDb.update(self, dt)
error(dangle)
end
-
for _, name in ipairs(self.sort) do
local system = self.systems[name]
local params = self.params[name]
- system.f(self.db, dt, params)
+ system.f(self.entityDb, dt, params)
end
end
diff --git a/honey/ecs/node.lua b/honey/ecs/node.lua
index 4953af5..6a47a1f 100644
--- a/honey/ecs/node.lua
+++ b/honey/ecs/node.lua
@@ -1,52 +1,47 @@
+local ecs = require 'honey.ecs.ecs'
+
local module = {}
setmetatable(module, {__index=_G})
setfenv(1, module)
--===== transform cascading =====--
-system = function(params)
- return {
- db = params.db,
-
- priority = 2,
- update = function(self, dt)
- local nodes = self.db:queryComponent("node")
-
- -- prepare nodes
- for id, node in pairs(nodes) do
- node._visited = false
- node._child = nil
- end
-
- -- helper function
- local function recursiveTransform(id, node)
- if node._visited then
- return node._matrix
- end
-
- if not node.parent then
- node._matrix = node.matrix
- else
- local parentNode = self.db:getComponent(node.parent, "node")
- local parentMatrix = recursiveTransform(node.parent, parentNode)
- node._matrix = parentMatrix * node.matrix
- if node.name then
- if not parentNode._child then parentNode._child = {} end
- parentNode._child[node.name] = honey.ecs.Accessor(self.db, id)
- end
- end
- node._visited = true
- return node._matrix
- end
-
- -- compute nodes
- for id, node in pairs(nodes) do
- recursiveTransform(id, node)
- end
- end,
- }
+local function recursiveTransform(db, id, node)
+ if node._visited then
+ return node._matrix
+ end
+
+ if not node.parent then
+ node._matrix = node.matrix
+ else
+ local parentNode = db:getComponent(node.parent, "node")
+ local parentMatrix = recursiveTransform(db, node.parent, parentNode)
+ node._matrix = parentMatrix * node.matrix
+ if node.name then
+ if not parentNode._child then parentNode._child = {} end
+ parentNode._child[node.name] = ecs.Accessor(db, id)
+ end
+ end
+ node._visited = true
+ return node._matrix
end
+system = {ecs.System("node", function(db, dt, params)
+ local nodes = db:queryComponent("node")
+
+ -- prepare nodes
+ for id, node in pairs(nodes) do
+ node._visited = false
+ node._child = nil
+ end
+
+ -- compute nodes
+ for id, node in pairs(nodes) do
+ recursiveTransform(db, id, node)
+ end
+end)}
+
+
return module
diff --git a/honey/ecs/render.lua b/honey/ecs/render.lua
index 1e41e7a..8cca6cf 100644
--- a/honey/ecs/render.lua
+++ b/honey/ecs/render.lua
@@ -1,3 +1,9 @@
+local ecs = require 'honey.ecs.ecs'
+
+local image = require 'honey.asset.image'
+local shader = require 'honey.asset.shader'
+local mesh = require 'honey.asset.mesh'
+
local glm = require 'honey.glm'
local Vec3 = glm.Vec3
local Mat4 = glm.Mat4
@@ -5,103 +11,77 @@ local Mat4 = glm.Mat4
local gl = honey.gl
local glfw = honey.glfw
+local node = require 'honey.ecs.node'
+
local module = {}
setmetatable(module, {__index=_G})
setfenv(1, module)
--===== rendering =====--
-function draw(model, view, projection, textures, shader, mesh)
- shader:use()
+local function drawMesh(program, uniforms, matrices, vao, count)
+ gl.UseProgram(program)
- -- bind textures
- local texOffset = 0
- for name, texTbl in pairs(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
- shader:configure{
- float={
- time=glfw.GetTime(),
- },
+ -- bind matrices
+ shader.configure(program, {
matrix={
- view=view,
- projection=projection,
- model=model,
+ model = matrices.model,
+ view = matrices.view,
+ projection = matrices.projection,
},
- }
+ })
- -- draw mesh
- mesh:drawElements()
-
- -- unbind textures
- for i=0,texOffset-1 do
- gl.BindTexture(gl.TEXTURE_2D + i, 0)
+ -- bind textures
+ local offset = 0
+ for name, tbl in pairs(uniforms.textures or {}) do
+ local tex = image.get(tbl.filename)
+ gl.BindTexture(gl.TEXTURE_2D + offset, tex)
+ shader.setInt(program, name, offset)
+ offset = offset+1
end
+
+ -- configure additional uniforms
+ shader.configure(program, uniforms)
+
+ -- render mesh
+ gl.BindVertexArray(vao)
+ gl.DrawElements(gl.TRIANGLES, count, gl.UNSIGNED_INT, 0)
end
-system = function(params)
- return {
- db = params.db,
- priority = params.priority or 99,
- update = function(self, dt)
- for id, camera in pairs(self.db:queryComponent("camera")) do
- local projection = camera.projection
- local cameraTransform = self.db:getComponent(id, "node")
- local view = Mat4()
- if cameraTransform then
- honey.glm.mat4_inv(cameraTransform._matrix.data, view.data)
- else
- view:identity()
- end
+
+local render = ecs.System("render", function(db, dt, p)
+ for id, camera in pairs(db:queryComponent("camera")) do
+ -- get camera's view and projection matrices
+ local projection = camera.projection
+ local view = Mat4()
+ local node = db:getComponent(id, "node")
+ if node then
+ honey.glm.mat4_inv(node._matrix.data, view.data)
+ else
+ view:identity()
+ end
- local entities = self.db:queryComponent("renderMesh")
- for entity, tbl in pairs(entities) do
- -- get model
- local node = self.db:getComponent(entity, "node")
- local model =
- (node and node._matrix) or
- Mat4():identity()
- -- get shader
- if not tbl.shader then
- print(node)
- print(node and node._matrix)
- print(node and node.name)
- print(node and node.parent)
- for k, v in pairs(tbl) do
- print(k, v)
- end
- end
- local shader = honey.shader.loadShader(
- tbl.shader.vertex, tbl.shader.fragment
- )
- -- get mesh
- local mesh = honey.mesh.loadCached(
- tbl.mesh.filename, tbl.mesh.index, tbl.mesh.debug
- )
- draw(model, view, projection, tbl.textures, shader, mesh)
- end
-
- entities = self.db:queryComponent("renderQuad")
- local quadmesh = honey.mesh.loadCached("builtin.quad", 1)
- for entity, tbl in pairs(entities) do
- -- get model
- local model = Mat4():identity()
- -- get shader
- local shader = honey.shader.loadShader(
- tbl.shader.vertex, tbl.shader.fragment
- )
- draw(model, view, projection, tbl.textures, shader, quadmesh)
- end
- end
- end,
- }
-end
+ -- iterate over all scene meshes
+ local meshes = db:queryComponent("renderMesh")
+ for id, tbl in pairs(meshes) do
+ -- get model matrix
+ local node = db:getComponent(id, "node")
+ local model = (node and node._matrix) or Mat4():identity()
+
+ -- get shader program
+ local program = shader.get(tbl.shader)
+
+ -- get mesh
+ local vao, count = mesh.get(tbl.mesh.filename, tbl.mesh.index)
+
+ -- draw c:
+ drawMesh(program, tbl.uniforms or {}, {view=view, model=model, projection=projection}, vao, count)
+ end
+ end
+end)
+render:addDependencies(node.system)
+system = {render}
return module
diff --git a/honey/ecs/script.lua b/honey/ecs/script.lua
index 9ae7d72..46af4fa 100644
--- a/honey/ecs/script.lua
+++ b/honey/ecs/script.lua
@@ -1,3 +1,6 @@
+local ecs = require 'honey.ecs.ecs'
+local node = require 'honey.ecs.node'
+
local module = {}
setmetatable(module, {__index=_G})
setfenv(1, module)
@@ -16,8 +19,8 @@ end
--===== dispatch messages to handlers =====--
-dispatch = function(entities, msg, data)
- local query = entities:queryComponent(msg)
+dispatch = function(db, msg, data)
+ local query = db:queryComponent(msg)
for id, handler in pairs(query) do
local f = getFunction(handler)
f(entities, id, data)
@@ -26,19 +29,16 @@ end
--===== script system =====--
-system = 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 = getFunction(script)
- f(self.db, id, dt)
- end
- end
- }
-end
+local script = ecs.System("script", function(db, dt, params)
+ local entities = db:queryComponent("script")
+ for id, script in pairs(entities) do
+ local f = getFunction(script)
+ f(db, id, dt)
+ end
+end)
+script:addDependencies(node.system)
+system = {script}
return module