summaryrefslogtreecommitdiff
path: root/honey/ecs/physics.lua
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-05-10 23:59:04 -0500
committersanine <sanine.not@pm.me>2023-05-10 23:59:04 -0500
commit14195dac1eda9140192ca07003258715b8b0abd3 (patch)
treebb4e41153363c791d4a9c7948bc85e0d4f77bc98 /honey/ecs/physics.lua
parent26bfc10ad0e8a355e9b02946dd31642f49a6ec60 (diff)
implement basic floating-ray character controller
Diffstat (limited to 'honey/ecs/physics.lua')
-rw-r--r--honey/ecs/physics.lua83
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 =====--