main.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. --[[ A utility function that draws all possible physics colliders and joint geometry
  2. Useful for debugging physics (to see if colliders line up with rendered geometry),
  3. and for experimenting and prototyping with physics, to get the rendering out of way. --]]
  4. local world
  5. local count = 100
  6. function lovr.load()
  7. gravity = gravity or 2
  8. sleepingAllowed = sleepingAllowed or false
  9. world = lovr.physics.newWorld(0, -gravity, 0, sleepingAllowed)
  10. -- ground plane
  11. local box = world:newBoxCollider(vec3(0, 0, 0), vec3(20, 0.1, 20))
  12. box:setKinematic(true)
  13. box:setUserData({1, 1, 1})
  14. end
  15. function lovr.update(dt)
  16. world:update(1 / 72) -- simulation is more stable if executed with fixed step
  17. -- every 100ms add random shape until there's enough of them
  18. if lovr.timer.getTime() % 0.1 < dt and count > 0 then
  19. local collider
  20. local colliderType = ({'box', 'sphere', 'cylinder', 'capsule'})[count % 4 + 1]
  21. local position = vec3(2 - 4 * lovr.math.random(), 4, 1 - 2 * lovr.math.random())
  22. if colliderType == 'box' then
  23. local size = vec3(0.1, 0.2, 0.3)
  24. collider = world:newBoxCollider(position, size)
  25. elseif colliderType == 'sphere' then
  26. local radius = 0.2
  27. collider = world:newSphereCollider(position, radius)
  28. elseif colliderType == 'cylinder' then
  29. local radius, length = 0.1, 0.3
  30. collider = world:newCylinderCollider(position, radius, length)
  31. elseif colliderType == 'capsule' then
  32. local radius, length = 0.1, 0.3
  33. collider = world:newCapsuleCollider(position, radius, length)
  34. end
  35. local shade = 0.2 + 0.6 * lovr.math.random()
  36. collider:setUserData({shade, shade, shade})
  37. collider:setOrientation(math.pi, lovr.math.random(), lovr.math.random(), lovr.math.random())
  38. count = count - 1
  39. end
  40. end
  41. function lovr.draw()
  42. for i, collider in ipairs(world:getColliders()) do
  43. -- rendering shapes of each collider
  44. drawCollider(collider)
  45. -- debug geometry for joints (no joints are used in this example)
  46. drawAttachedJoints(collider)
  47. end
  48. end
  49. function drawCollider(collider)
  50. local color = collider:getUserData()
  51. lovr.graphics.setColor(color or 0x202020)
  52. local shape = collider:getShapes()[1]
  53. if shape:isSensor() then
  54. local r,g,b = lovr.graphics.getColor()
  55. lovr.graphics.setColor(r,g,b,0.2)
  56. end
  57. -- shapes
  58. for _, shape in ipairs(collider:getShapes()) do
  59. local shapeType = shape:getType()
  60. local x,y,z, angle, ax,ay,az = collider:getPose()
  61. -- draw primitive at collider's position with correct dimensions
  62. if shapeType == 'box' then
  63. local sx, sy, sz = shape:getDimensions()
  64. lovr.graphics.box('fill', x,y,z, sx,sy,sz, angle, ax,ay,az)
  65. elseif shapeType == 'sphere' then
  66. lovr.graphics.sphere(x,y,z, shape:getRadius())
  67. elseif shapeType == 'cylinder' then
  68. local l, r = shape:getLength(), shape:getRadius()
  69. local x,y,z, angle, ax,ay,az = collider:getPose()
  70. lovr.graphics.cylinder(x,y,z, l, angle, ax,ay,az, r, r)
  71. elseif shapeType == 'capsule' then
  72. local l, r = shape:getLength(), shape:getRadius()
  73. local x,y,z, angle, ax,ay,az = collider:getPose()
  74. local m = mat4(x,y,z, 1,1,1, angle, ax,ay,az)
  75. lovr.graphics.cylinder(x,y,z, l, angle, ax,ay,az, r, r, false)
  76. lovr.graphics.sphere(vec3(m:mul(0, 0, l/2)), r)
  77. lovr.graphics.sphere(vec3(m:mul(0, 0, -l/2)), r)
  78. end
  79. end
  80. end
  81. function drawAttachedJoints(collider)
  82. lovr.graphics.setColor(1,1,1,0.3)
  83. -- joints are attached to two colliders; function draws joint for second collider
  84. for j, joint in ipairs(collider:getJoints()) do
  85. local anchoring, attached = joint:getColliders()
  86. if attached == collider then
  87. jointType = joint:getType()
  88. if jointType == 'ball' then
  89. local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
  90. drawAnchor(vec3(x1,y1,z1))
  91. drawAnchor(vec3(x2,y2,z2))
  92. elseif jointType == 'slider' then
  93. local position = joint:getPosition()
  94. local x,y,z = anchoring:getPosition()
  95. drawAxis(vec3(x,y,z), vec3(joint:getAxis()))
  96. elseif jointType == 'distance' then
  97. local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
  98. drawAnchor(vec3(x1,y1,z1))
  99. drawAnchor(vec3(x2,y2,z2))
  100. drawAxis(vec3(x2,y2,z2), vec3(x1, y1, z1) - vec3(x2,y2,z2))
  101. elseif jointType == 'hinge' then
  102. local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
  103. drawAnchor(vec3(x1,y1,z1))
  104. drawAnchor(vec3(x2,y2,z2))
  105. drawAxis(vec3(x1,y1,z1), vec3(joint:getAxis()))
  106. end
  107. end
  108. end
  109. end
  110. function drawAnchor(origin)
  111. lovr.graphics.sphere(origin, .02)
  112. end
  113. function drawAxis(origin, axis)
  114. lovr.graphics.line(origin, origin + axis:normalize() * 0.3)
  115. end