From 02c6f822e2cca41d5d28afd9f3a05211316587fd Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 15 Apr 2023 20:04:57 -0500 Subject: add collision system --- honey/ecs-systems.lua | 61 ++++++++++++++++++++++++++++++++++++++++++++++----- honey/glm.lua | 6 +++++ main.lua | 27 ++++++++++++++++++++--- save | 7 +++--- 4 files changed, 90 insertions(+), 11 deletions(-) diff --git a/honey/ecs-systems.lua b/honey/ecs-systems.lua index 47c0f6d..c287d06 100644 --- a/honey/ecs-systems.lua +++ b/honey/ecs-systems.lua @@ -1,5 +1,6 @@ local ecs = require 'honey.ecs' local glm = require 'honey.glm' +local Mat4 = glm.Mat4 local Vec3 = glm.Vec3 local Quaternion = glm.Quaternion local gl = honey.gl @@ -41,7 +42,7 @@ transform = function(params) return { db = params.db, - priority = 1, + priority = 2, update = function(self, dt) local entities = self.db:queryComponent("transform") @@ -169,7 +170,7 @@ physics = function(params) contactGroup=ode.JointGroupCreate(groupSize), time=interval, - priority=0, + priority=1, update=function(self, dt) for i, ref in ipairs(refs) do print(i, ref.tbl, ref.physics) @@ -186,6 +187,12 @@ physics = function(params) body = nil end) + local collision = self.db:getComponent(id, "collision") + if collision then + print(id, collision.class) + ode.GeomSetBody(collision._geom, body) + end + local mass = ode.MassCreate() local class = physics.mass.class if not class then @@ -247,12 +254,12 @@ physics = function(params) -- create the joint local joint = ode.JointCreateContact( self.world, - self.contactgroup, + self.contactGroup, contact ) -- attach the two bodies - local bodyA = ode.GeomGetData(a) - local bodyB = ode.GeomGetData(b) + local bodyA = ode.GeomGetBody(a) + local bodyB = ode.GeomGetBody(b) ode.JointAttach(joint, bodyA, bodyB) end end) @@ -283,4 +290,48 @@ physics = function(params) end +--===== collision space =====-- + + +local function createGeom(self, id, collision) + local geom + if collision.class == "sphere" then + geom = ode.CreateSphere(self.space, collision.radius) + elseif collision.class == "plane" then + local transform = self.db:getComponent(id, "transform") + local m = transform.matrix + local normal = transform.matrix:mulv3(Vec3{0,1,0}):normalize() + local position = Vec3{m[1][4], m[2][4], m[3][4]} + print(position) + local d = normal:dot(position) + print(normal, d) + geom = ode.CreatePlane(self.space, normal[1], normal[2], normal[3], d) + end + collision._geom = geom + collision._gc = honey.util.gc_canary(function() + print("release geom for id"..id) + ode.GeomDestroy(geom) + end) +end + +function collision(params) + local db = params.db + local space = params.space + return { + db=db, + space=space, + priority=0, + update = function(self, dt) + local query = self.db:queryComponent("collision") + for id, collision in pairs(query) do + if not collision._geom then + createGeom(self, id, collision) + print(id, collision._geom) + end + end + end + } +end + + return module diff --git a/honey/glm.lua b/honey/glm.lua index 3357815..c950b9a 100644 --- a/honey/glm.lua +++ b/honey/glm.lua @@ -167,6 +167,7 @@ end function Vec3.normalize(self) glm.vec3_normalize(self.data) + return self end function Vec3.normalizeTo(self, dest) glm.vec3_normalize_to(self.data, dest.data) @@ -288,6 +289,11 @@ function Mat4.mul(self, other) glm.mat4_mul(self.data, other.data, self.data) return self end +function Mat4.mulv3(self, v) + local dest = Vec3() + glm.mat4_mulv3(self.data, v.data, 1.0, dest.data) + return dest +end function Mat4.translate(self, vec) diff --git a/main.lua b/main.lua index fe97123..0f46f70 100644 --- a/main.lua +++ b/main.lua @@ -38,6 +38,7 @@ local systems = ecs.SystemDb(entities) systems:addSystem(sys.transform) systems:addSystem(sys.renderCamera) systems:addSystem(sys.script) +systems:addSystem(sys.collision, {space=space}) systems:addSystem(sys.physics, {space=space, world=world}) package.loaded['baseRotationScript'] = function(entities, id, dt) local transform = entities:getComponent(id, "transform") @@ -77,6 +78,19 @@ function setupEntities() }, onWindowResize = { script = "cameraHandleResize" }, }) + + + local plane = entities:createEntity() + entities:addComponents(plane, { + transform = { + matrix = Mat4() + :identity() + :rotateZ(math.rad(5)) + }, + collision = { + class = "plane", + }, + }) @@ -88,7 +102,14 @@ function setupEntities() mesh = { filename="assets/icosahedron.obj", index=1 }, }, transform = { - matrix = Mat4():identity():rotateZ(math.rad(45)), + matrix = Mat4() + :identity() + :translate(Vec3{0,1,0}) + :rotateZ(math.rad(45)), + }, + collision = { + class = "sphere", + radius = 1, }, physics = { mass = { @@ -96,8 +117,8 @@ function setupEntities() density = 1, radius = 1, }, - velocity = Vec3{ 0, 10, 0 }, - angularVelocity = Vec3{ 0, 1, 0 }, + velocity = Vec3{ 0, 0, 0 }, + angularVelocity = Vec3{ 0, 0, 0 }, }, }) diff --git a/save b/save index 778b248..22a16b1 100644 --- a/save +++ b/save @@ -1,3 +1,4 @@ -Entity("3b5d66ec-e448-4d45-81b4-55ea9664c2f9", {camera={projection=Mat4{1.8107, 0.0000, 0.0000, 0.0000, 0.0000, 2.4142, 0.0000, 0.0000, 0.0000, 0.0000, -1.0020, -0.2002, 0.0000, 0.0000, -1.0000, 0.0000}},z={value=-60},script={script="cameraRotationScript"},onKey={script="cameraKeyHandler"},onWindowResize={script="cameraHandleResize"},transform={matrix=Mat4{1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, -59.0040, 0.0000, 0.0000, 0.0000, 1.0000}}}) -Entity("8513af47-a427-4ff0-a1fc-bfe80c1e5c68", {renderMesh={shader={vertex="vertex.glsl",fragment="fragment.glsl"},mesh={index=1,filename="assets/icosahedron.obj"},textures={ourTexture={filename="77155.png"}}},physics={velocity=Vec3{0.0000, -12.7200, 0.0000},angularVelocity=Vec3{0.0000, 1.0000, -0.0000},mass={density=1,radius=1,class="sphere"}},transform={matrix=Mat4{-0.4562, 0.4562, 0.7641, 0.0000, 0.7071, 0.7071, 0.0000, -3.2717, -0.5403, 0.5403, -0.6451, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000}}}) -Entity("fe3dd9ef-198c-4708-8d23-a05b06442dbf", {renderMesh={mesh={index=1,filename="assets/tetrahedron.obj"},shader={vertex="vertex.glsl",fragment="fragment.glsl"}},transform={parent="8513af47-a427-4ff0-a1fc-bfe80c1e5c68",matrix=Mat4{1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 2.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000}}}) +Entity("252e3aec-c36d-4e59-a5b9-73872a63656b", {transform={parent="f451df85-d8d1-4b72-abf5-f384f2ffa730",matrix=Mat4{1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 2.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000}},renderMesh={mesh={index=1,filename="assets/tetrahedron.obj"},shader={vertex="vertex.glsl",fragment="fragment.glsl"}}}) +Entity("4f4191ff-f1b7-4382-904b-156b07091850", {onKey={script="cameraKeyHandler"},transform={matrix=Mat4{1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, -59.1379, 0.0000, 0.0000, 0.0000, 1.0000}},script={script="cameraRotationScript"},camera={projection=Mat4{2.5518, 0.0000, 0.0000, 0.0000, 0.0000, 2.4142, 0.0000, 0.0000, 0.0000, 0.0000, -1.0020, -0.2002, 0.0000, 0.0000, -1.0000, 0.0000}},z={value=-60},onWindowResize={script="cameraHandleResize"}}) +Entity("268bfa52-f18b-4d23-bd02-7f3366ae9da3", {collision={class="plane"},transform={matrix=Mat4{1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000}}}) +Entity("f451df85-d8d1-4b72-abf5-f384f2ffa730", {transform={matrix=Mat4{0.6164, -0.6164, 0.4899, -0.0000, 0.7071, 0.7071, 0.0000, 4.8477, -0.3464, 0.3464, 0.8718, -0.0000, 0.0000, 0.0000, 0.0000, 1.0000}},collision={radius=1,class="sphere"},physics={angularVelocity=Vec3{0.0000, 1.0000, 0.0000},mass={radius=1,class="sphere",density=1},velocity=Vec3{-0.0000, 6.9881, -0.0000}},renderMesh={mesh={index=1,filename="assets/icosahedron.obj"},textures={ourTexture={filename="77155.png"}},shader={vertex="vertex.glsl",fragment="fragment.glsl"}}}) -- cgit v1.2.1