summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2023-03-23 13:35:37 -0500
committersanine-a <sanine.not@pm.me>2023-03-23 13:35:37 -0500
commite5553bb81c93cd76456d07d3a1d7e8bb1b249b6e (patch)
treea92801deaba55c85dd4f52636ab4f616e8483796 /main.lua
parentf4346b8f06653dbc1e0c346d88f5f83ca8a7b876 (diff)
implement skeleton of physics system
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua139
1 files changed, 94 insertions, 45 deletions
diff --git a/main.lua b/main.lua
index 9f26eb3..2c92223 100644
--- a/main.lua
+++ b/main.lua
@@ -4,54 +4,20 @@ local glfw = honey.glfw
local gl = honey.gl
local Vec3 = honey.Vec3
local Mat4 = honey.Mat4
+local Quaternion = honey.Quaternion
local ecs = honey.ecs
local systems = honey.standardSystems
local ode = honey.ode
+local nvg = honey.nvg
-- initialize honey
local window = honey.init()
--- setup physics
-local world = ode.WorldCreate()
-local space = ode.HashSpaceCreate(ode.Space0)
-ode.WorldSetGravity(world, 0, -10, 0)
-ode.WorldSetCFM(world, 1e-5)
-ode.CreatePlane(space, 0, 1, 0, 0)
-local contactgroup = ode.JointGroupCreate(16)
-local body = ode.BodyCreate(world)
-local geom = ode.CreateSphere(space, 0.5)
-local mass = ode.MassCreate()
-ode.MassSetSphere(mass, 1, 0.5)
-ode.BodySetMass(body, mass)
-ode.GeomSetBody(geom, body)
-ode.BodySetPosition(body, 0, 3, 0)
-
-function physicsStep()
- ode.SpaceCollide(space, function(o1, o2)
- local b1 = ode.GeomGetBody(o1)
- local b2 = ode.GeomGetBody(o2)
- local contact = ode.CreateContact{
- surface = {
- mode = ode.ContactBounce + ode.ContactSoftCFM,
- mu = ode.Infinity,
- bounce = 1.0,
- bounce_vel = 0.1,
- soft_cfm = 0.001,
- },
- }
- local collisions = ode.Collide(o1, o2, 1)
- if #collisions > 0 then
- print("collision detected!")
- ode.ContactSetGeom(contact, collisions[1])
- local joint = ode.JointCreateContact(world, contactgroup, contact)
- ode.JointAttach(joint, b1, b2)
- end
- end)
- ode.WorldQuickStep(world, 0.01)
- ode.JointGroupEmpty(contactgroup)
-end
-
+-- setup vector graphics
+local vg = nvg.CreateContext()
+local november = nvg.CreateFont(vg, "November", "assets/november.regular.ttf")
+local vw, vh = 640, 480
-- create camera matrices
local camera = {
@@ -65,6 +31,63 @@ level:addSystem(systems.transformCascade)
level:addSystem(systems.renderCam(camera))
level:addSystem(systems.update)
+-- physics system
+local world = ode.WorldCreate()
+local space = ode.HashSpaceCreate(ode.Space0)
+level:addSystem{
+ setup=function(self)
+ self.time = 0
+ self.world=world
+ self.space=space
+ ode.WorldSetGravity(self.world, 0, -10, 0)
+ ode.WorldSetCFM(self.world, 1e-5)
+ self.contactgroup = ode.JointGroupCreate(32)
+ self.__gc = honey.util.gc_canary(function()
+ ode.WorldDestroy(self.world)
+ ode.SpaceDestroy(self.space)
+ end)
+ end,
+ filter = ecs.Filter.AND{"transform", "collisionShape", "physicsBody"},
+ preUpdate = function(self)
+ self.dt = nil
+ if self.time > 0.01 then
+ self.time = self.time - 0.01
+ ode.SpaceCollide(self.space, function(o1, o2)
+ local b1 = ode.GeomGetBody(o1)
+ local b2 = ode.GeomGetBody(o2)
+ local contact = ode.CreateContact{
+ surface = {
+ mode = ode.ContactBounce + ode.ContactSoftCFM,
+ mu = ode.Infinity,
+ bounce = 0.99,
+ bounce_vel = 0.1,
+ soft_cfm = 0.001,
+ },
+ }
+ local collisions = ode.Collide(o1, o2, 1)
+ if #collisions > 0 then
+ print("collision detected!")
+ ode.ContactSetGeom(contact, collisions[1])
+ local joint = ode.JointCreateContact(self.world, self.contactgroup, contact)
+ ode.JointAttach(joint, b1, b2)
+ end
+ end)
+ ode.WorldQuickStep(self.world, 0.01)
+ ode.JointGroupEmpty(self.contactgroup)
+ end
+ end,
+ update = function(self, entity, dt)
+ if not self.dt then
+ self.dt = dt
+ self.time = self.time + dt
+ end
+
+ local x, y, z = ode.BodyGetPosition(entity.physicsBody)
+ local a, b, c, d = ode.BodyGetQuaternion(entity.physicsBody)
+ entity.transform:identity():translate(Vec3{x, y, z}):mul(Quaternion{a, b, c, d}:toMat4())
+ end,
+}
+
-- create shader
local shader = honey.Shader{
vertexFile = "vertex.glsl",
@@ -127,13 +150,20 @@ local ball = {
parent=false,
mesh=icosa,
shader=shader,
- update=function(self, dt)
- local x, y, z = ode.BodyGetPosition(body)
- self.transform:identity():translate(Vec3{x, y, z})
- end,
+ collisionShape=ode.CreateSphere(space, 0.5),
+ physicsBody=ode.BodyCreate(world),
}
level:addEntity(ball)
+local mass = ode.MassCreate()
+ode.MassSetSphere(mass, 1, 0.5)
+ode.BodySetMass(ball.physicsBody, mass)
+ode.GeomSetBody(ball.collisionShape, ball.physicsBody)
+ode.BodySetPosition(ball.physicsBody, 0, 3, 0)
+ode.BodySetLinearVel(ball.physicsBody, 1, 0, 0)
+
+ode.CreatePlane(space, 0, 1, 0, -2)
+
-- close window on ESCAPE key
window:setKeyCallback(function(_, key)
if key == glfw.KEY_ESCAPE then
@@ -145,14 +175,33 @@ end)
window:setFramebufferSizeCallback(function(_, width, height)
gl.Viewport(0, 0, width, height)
camera.projection:perspectiveResize(width/height)
+ vw, vh = width, height
end)
+-- averager (for fps)
+function averager(memory)
+ local buf = {}
+ local avg = 0
+ for i=1,memory do table.insert(buf, 0) end
+ return function(value)
+ table.insert(buf, value)
+ local val = table.remove(buf, 1)
+ avg = avg + value - val
+ return avg / memory
+ end
+end
+local fpsAverage = averager(200)
+
-- main loop
honey.loop(window, function(dt)
gl.ClearColor(0.2, 0.4, 1.0, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT)
level:update(dt)
- physicsStep()
+ nvg.BeginFrame(vg, vw, vh, 1.0)
+ nvg.StrokeColor(vg, nvg.RGBf(1, 1, 1))
+ nvg.FontFace(vg, "November")
+ nvg.Text(vg, 50, 50, "fps: "..tostring(math.floor(fpsAverage(1/dt))))
+ nvg.EndFrame(vg)
end)
-- clean up