summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-04-15 20:04:57 -0500
committersanine <sanine.not@pm.me>2023-04-15 20:04:57 -0500
commit02c6f822e2cca41d5d28afd9f3a05211316587fd (patch)
treeafb1fec88273f8fe123ae8750a75c146969f4d9a
parente603997055259039cefcdceaece5604e3856e36d (diff)
add collision system
-rw-r--r--honey/ecs-systems.lua61
-rw-r--r--honey/glm.lua6
-rw-r--r--main.lua27
-rw-r--r--save7
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"}}})