diff options
author | sanine <sanine.not@pm.me> | 2023-05-10 23:59:04 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-05-10 23:59:04 -0500 |
commit | 14195dac1eda9140192ca07003258715b8b0abd3 (patch) | |
tree | bb4e41153363c791d4a9c7948bc85e0d4f77bc98 /honey/ecs/physics.lua | |
parent | 26bfc10ad0e8a355e9b02946dd31642f49a6ec60 (diff) |
implement basic floating-ray character controller
Diffstat (limited to 'honey/ecs/physics.lua')
-rw-r--r-- | honey/ecs/physics.lua | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/honey/ecs/physics.lua b/honey/ecs/physics.lua index 9b22bd7..2bef336 100644 --- a/honey/ecs/physics.lua +++ b/honey/ecs/physics.lua @@ -4,6 +4,8 @@ local Mat4 = glm.Mat4 local Quaternion = glm.Quaternion local ode = honey.ode +local script = require 'honey.ecs.script' + local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) @@ -22,13 +24,23 @@ local function createMass(tbl) tbl.radius ) elseif class == "capsule" then - ode.MassSetCapsule( - mass, - tbl.density, - tbl.direction, - tbl.radius, - tbl.length - ) + if tbl.mass then + ode.MassSetCapsuleTotal( + mass, + tbl.mass, + tbl.direction, + tbl.radius, + tbl.length + ) + else + ode.MassSetCapsule( + mass, + tbl.density, + tbl.direction, + tbl.radius, + tbl.length + ) + end end return mass end @@ -92,10 +104,11 @@ local function createPhysicsBody(db, world, id, component) end -local function handleCollision(db, self, other) +local function handleCollision(db, self, other, collision) local handler = db:getComponent(self, "onCollision") if handler then - handler(db, self, other) + h = script.getFunction(handler) + h(db, self, other, collision) end end @@ -104,28 +117,36 @@ local function collide(self, a, b, collision) -- check for collision handlers local idA = ode.GeomGetData(a) local idB = ode.GeomGetData(b) - handleCollision(self.db, idA, idB) - handleCollision(self.db, idB, idA) - - -- set up the joint params - local contact = ode.CreateContact{ surface={ - mode = ode.ContactBounce + ode.ContactSoftCFM, - mu = ode.Infinity, - bounce = 0.90, - bounce_vel = 0.1, - soft_cfm = 0.001, - }} - ode.ContactSetGeom(contact, collision) - -- create the joint - local joint = ode.JointCreateContact( - self.world, - self.contactGroup, - contact - ) - -- attach the two bodies - local bodyA = ode.GeomGetBody(a) - local bodyB = ode.GeomGetBody(b) - ode.JointAttach(joint, bodyA, bodyB) + handleCollision(self.db, idA, idB, collision) + handleCollision(self.db, idB, idA, collision) + + local physicsA = self.db:getComponent(idA, "physics") + local physicsB = self.db:getComponent(idB, "physics") + + local surface = (physicsA and physicsA.surface) or + (physicsB and physicsB.surface) + + if surface then + -- set up the joint params + local contact = ode.CreateContact{ surface={ + mode = ode.ContactBounce + ode.ContactSoftCFM, + mu = ode.Infinity, + bounce = 0.90, + bounce_vel = 0.1, + soft_cfm = 0.001, + }} + ode.ContactSetGeom(contact, collision) + -- create the joint + local joint = ode.JointCreateContact( + self.world, + self.contactGroup, + contact + ) + -- attach the two bodies + local bodyA = ode.GeomGetBody(a) + local bodyB = ode.GeomGetBody(b) + ode.JointAttach(joint, bodyA, bodyB) + end end --===== physics =====-- |