summaryrefslogtreecommitdiff
path: root/demo/bouncing_ball/main.lua
diff options
context:
space:
mode:
Diffstat (limited to 'demo/bouncing_ball/main.lua')
-rw-r--r--demo/bouncing_ball/main.lua136
1 files changed, 136 insertions, 0 deletions
diff --git a/demo/bouncing_ball/main.lua b/demo/bouncing_ball/main.lua
new file mode 100644
index 0000000..ecbff7b
--- /dev/null
+++ b/demo/bouncing_ball/main.lua
@@ -0,0 +1,136 @@
+local gl = honey.gl
+local window = honey.window
+
+local Shader = require 'shader'
+local Mesh = require 'mesh'
+
+
+--====== initialize opengl ======--
+
+gl.Init()
+window.setHint(window.hintType.contextVersionMajor, 3)
+window.setHint(window.hintType.contextVersionMinor, 3)
+window.setHint(window.hintType.openGlProfile, window.profileType.openGlCoreProfile)
+
+
+--====== create window ======--
+
+local w = window.create(640, 480, 'bouncing ball demo')
+window.makeContextCurrent(w)
+gl.InitGlad()
+gl.Enable(gl.DEPTH_TEST)
+
+window.setFramebufferSizeCallback(w, function(_, width, height)
+ print(string.format("resize: (%d, %d)", width, height))
+ gl.setViewport(0, 0, width, height)
+end)
+
+
+--===== load mesh and shader =====--
+
+local shader = Shader.Load('vertex.vs', 'fragment.fs')
+local ball = Mesh.Load('ball.dae')
+
+--===== set up ode =====--
+
+local ode = honey.ode
+ode.InitODE()
+local world = ode.WorldCreate()
+local space = ode.HashSpaceCreate()
+ode.WorldSetGravity(world, 0, -10, 0)
+ode.WorldSetCFM(world, 1e-5)
+ode.CreatePlane(space, 0, 1, 0, 0)
+local contactgroup = ode.JointGroupCreate()
+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.ContactCreate()
+ ode.ContactSurfaceSetMode(contact, ode.ContactBounce + ode.ContactSoftCFM)
+ ode.ContactSurfaceSetMu(contact, ode.Infinity)
+ ode.ContactSurfaceSetBounce(contact, 0.9)
+ ode.ContactSurfaceSetBounceVel(contact, 0.1)
+ ode.ContactSurfaceSetSoftCFM(contact, 0.001)
+ local collisionCount = ode.Collide(o1, o2, contact)
+ if collisionCount > 0 then
+ local joint = ode.JointCreateContact(world, contactgroup, contact)
+ ode.JointAttach(joint, b1, b2)
+ end
+ end)
+ ode.WorldQuickStep(world, 0.01)
+ ode.JointGroupEmpty(contactgroup)
+end
+
+
+--====== matrices ======--
+
+function setVector(vector, x, y, z)
+ honey.glm.vec3_set(vector, 0, x)
+ honey.glm.vec3_set(vector, 1, y)
+ honey.glm.vec3_set(vector, 2, z)
+end
+
+local view = honey.glm.mat4()
+honey.glm.mat4_identity(view)
+local translation = honey.glm.vec3()
+setVector(translation, 0, -1, -6)
+honey.glm.translate(view, translation)
+
+local projection = honey.glm.mat4()
+honey.glm.perspective(math.rad(45), 800/600, 0.1, 1000, projection)
+
+
+--====== main loop ======--
+
+local ballPosition = honey.glm.vec3()
+setVector(ballPosition, ode.BodyGetPosition(body))
+
+local time = 0
+local dtAverage = 0
+local dtCount = 0
+
+while not window.shouldClose(w) do
+ local newTime = window.getTime()
+ local dt = newTime - time
+ dtAverage = dtAverage + dt
+ dtCount = dtCount + 1
+ if dtCount > 60 then
+ local fps = dtCount/dtAverage
+ print(string.format('%0.2f fps', fps))
+ dtAverage = 0
+ dtCount = 0
+ end
+ time = newTime
+
+ physicsStep()
+
+ gl.ClearColor(0.2, 0.3, 0.3, 1.0)
+ gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT)
+
+ setVector(ballPosition, ode.BodyGetPosition(body))
+ ball:SetPosition(ballPosition)
+
+ shader:Use()
+ shader:SetMatrix('model', ball.transform)
+ shader:SetMatrix('view', view)
+ shader:SetMatrix('projection', projection)
+
+
+ ball:Draw()
+
+ window.swapBuffers(w)
+ window.pollEvents()
+end
+
+--===== shut down =====--
+
+window.destroy(w)
+gl.Terminate()