2
0

main.lua 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. -- Newton's cradle: array of balls suspended from two strings, demonstrating conservation of energy / momentum
  2. -- Strings are modeled with distance joints, which means they behave more like rods.
  3. local world
  4. local frame
  5. local framePose
  6. local balls = {}
  7. local count = 10
  8. local radius = 1 / count / 2
  9. -- small air gap between balls results in collisions in separate frames, to carry impulse through to last ball
  10. -- without this gap the physics engine would need to calculate transfer of impulses between contacts
  11. local gap = 0.01
  12. function lovr.load()
  13. world = lovr.physics.newWorld({ restitutionThreshold = .05 })
  14. -- a static geometry from which balls are suspended
  15. local size = vec3(1.2, 0.1, 0.3)
  16. frame = world:newBoxCollider(vec3(0, 2, -2), size)
  17. frame:setKinematic(true)
  18. framePose = lovr.math.newMat4(frame:getPose()):scale(size)
  19. -- create balls along the length of frame and attach them with two distance joints to frame
  20. for x = -0.5, 0.5, 1 / count do
  21. local ball = world:newSphereCollider(vec3(x, 1, -2), radius - gap)
  22. ball:setRestitution(1.0)
  23. table.insert(balls, ball)
  24. lovr.physics.newDistanceJoint(frame, ball, vec3(x, 2, -2 + 0.25), vec3(x, 1, -2))
  25. lovr.physics.newDistanceJoint(frame, ball, vec3(x, 2, -2 - 0.25), vec3(x, 1, -2))
  26. end
  27. -- displace the last ball to set the Newton's cradle in motion
  28. local lastBall = balls[#balls]
  29. lastBall:applyLinearImpulse(.6, 0, 0)
  30. lovr.graphics.setBackgroundColor(0.1, 0.1, 0.1)
  31. end
  32. function lovr.draw(pass)
  33. pass:setColor(0, 0, 0)
  34. pass:box(framePose)
  35. pass:setColor(1, 1, 1)
  36. for i, ball in ipairs(balls) do
  37. local position = vec3(ball:getPosition())
  38. pass:sphere(position, radius)
  39. end
  40. end
  41. function lovr.update(dt)
  42. world:update(dt)
  43. end