diff options
Diffstat (limited to 'honey/ecs')
-rw-r--r-- | honey/ecs/collision.lua | 2 | ||||
-rw-r--r-- | honey/ecs/ecs.lua | 2 | ||||
-rw-r--r-- | honey/ecs/render.lua | 118 |
3 files changed, 99 insertions, 23 deletions
diff --git a/honey/ecs/collision.lua b/honey/ecs/collision.lua index f34c320..b385e76 100644 --- a/honey/ecs/collision.lua +++ b/honey/ecs/collision.lua @@ -67,7 +67,7 @@ end local updateGeom = ecs.System("collisionGeoms", function(db, dt, p) for id, collision in pairs(db:queryComponent("collision")) do if not collision._geom then - createGeom(p.space, collision) + createGeom(p.space, id, collision) end updateGeom(collision) end diff --git a/honey/ecs/ecs.lua b/honey/ecs/ecs.lua index 0c84041..dc096be 100644 --- a/honey/ecs/ecs.lua +++ b/honey/ecs/ecs.lua @@ -307,7 +307,7 @@ end function SystemDb.addSystems(self, systems, params) for _, system in ipairs(systems) do self.systems[system.name] = system - self.params[system.name] = params + self.params[system.name] = params or {} end self.sort, self.dangling = tsort(self.systems) return self diff --git a/honey/ecs/render.lua b/honey/ecs/render.lua index 8cca6cf..1c38692 100644 --- a/honey/ecs/render.lua +++ b/honey/ecs/render.lua @@ -1,4 +1,10 @@ -local ecs = require 'honey.ecs.ecs' +local gl = honey.gl +local glfw = honey.glfw +local ode = honey.ode + +local ecs = require 'honey.ecs.ecs' +local collision = require 'honey.ecs.collision' +local node = require 'honey.ecs.node' local image = require 'honey.asset.image' local shader = require 'honey.asset.shader' @@ -8,16 +14,12 @@ local glm = require 'honey.glm' local Vec3 = glm.Vec3 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 =====-- + local function drawMesh(program, uniforms, matrices, vao, count) gl.UseProgram(program) @@ -49,6 +51,88 @@ local function drawMesh(program, uniforms, matrices, vao, count) end +local function drawMeshes(db, view, projection) + 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 + + +local function drawGeoms(db, view, projection) + -- draw wireframes + gl.Enable(gl.CULL_FACE) + gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) + gl.LineWidth(1) + + -- shader program for all geoms + local program = shader.get{ vertex="builtin.basic3d.vert", fragment="builtin.color.frag" } + local uniforms = { + vec3 = { + color = Vec3{ 1, 0, 1 }, + }, + } + + local query = db:queryComponent("collision") + for id, tbl in pairs(query) do + -- compute model matrix + local m = Mat4():identity() + m[1][4], m[2][4], m[3][4] = ode.GeomGetPosition(tbl._geom) + m[1][1], m[1][2], m[1][3], + m[2][1], m[2][2], m[2][3], + m[3][1], m[3][2], m[3][3] = ode.GeomGetRotation(tbl._geom) + + local matrices = { + view=view, + projection=projection, + model=m, + } + + -- get the mesh + if tbl.class == "sphere" then + m:scale(Vec3{tbl.radius, tbl.radius, tbl.radius}) + local vao, count = mesh.get("builtin.hemisphere", 1) + drawMesh(program, uniforms, matrices, vao, count) + m:rotateX(math.pi) + drawMesh(program, uniforms, matrices, vao, count) + elseif tbl.class == "box" then + m:scale(Vec3{tbl.lx, tbl.ly, tbl.lz}) + local vao, count = mesh.get("builtin.cube", 1) + drawMesh(program, uniforms, matrices, vao, count) + elseif tbl.class == "capsule" then + m:scale(Vec3{tbl.radius, tbl.length/2, tbl.radius}) + local vao, count = mesh.get("builtin.tube", 1) + drawMesh(program, uniforms, matrices, vao, count) + m:scale(Vec3{1, 2*tbl.radius/tbl.length, 1}) + :translate(Vec3{0, tbl.length/2, 0}) + vao, count = mesh.get("builtin.hemisphere", 1) + drawMesh(program, uniforms, matrices, vao, count) + m:translate(Vec3{0, -tbl.length, 0}) + :rotateX(math.pi) + drawMesh(program, uniforms, matrices, vao, count) + elseif tbl.class == "ray" then + m:scale(Vec3{0.001, 0.001, tbl.length}) + local vao, count = mesh.get("builtin.cube", 1) + drawMesh(program, uniforms, matrices, vao, count) + end + end + + -- switch out of wireframe mode + gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) +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 @@ -60,26 +144,18 @@ local render = ecs.System("render", function(db, dt, p) else view:identity() 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) + -- optionally draw collision geoms + if p.drawGeoms then + drawGeoms(db, view, projection) end + + -- render all scene meshes + drawMeshes(db, view, projection) end end) render:addDependencies(node.system) +render:addDependencies(collision.system) system = {render} |