From 4b2507b2f30d50c8673f33179c2b537ac83da3bf Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 16 May 2023 22:51:17 -0500 Subject: add basic collision geom visualizations --- honey/ecs/render.lua | 118 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 21 deletions(-) (limited to 'honey/ecs/render.lua') 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} -- cgit v1.2.1