diff options
Diffstat (limited to 'demo/bouncing_ball/main.lua')
-rw-r--r-- | demo/bouncing_ball/main.lua | 136 |
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() |