123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- --[[ A utility function that draws all possible physics colliders and joint geometry
- Useful for debugging physics (to see if colliders line up with rendered geometry),
- and for experimenting and prototyping with physics, to get the rendering out of way. --]]
- local world
- local count = 100
- function lovr.load()
- gravity = gravity or 2
- sleepingAllowed = sleepingAllowed or false
- world = lovr.physics.newWorld(0, -gravity, 0, sleepingAllowed)
- -- ground plane
- local box = world:newBoxCollider(vec3(0, 0, 0), vec3(20, 0.1, 20))
- box:setKinematic(true)
- box:setUserData({1, 1, 1})
- end
- function lovr.update(dt)
- world:update(1 / 72) -- simulation is more stable if executed with fixed step
- -- every 100ms add random shape until there's enough of them
- if lovr.timer.getTime() % 0.1 < dt and count > 0 then
- local collider
- local colliderType = ({'box', 'sphere', 'cylinder', 'capsule'})[count % 4 + 1]
- local position = vec3(2 - 4 * lovr.math.random(), 4, 1 - 2 * lovr.math.random())
- if colliderType == 'box' then
- local size = vec3(0.1, 0.2, 0.3)
- collider = world:newBoxCollider(position, size)
- elseif colliderType == 'sphere' then
- local radius = 0.2
- collider = world:newSphereCollider(position, radius)
- elseif colliderType == 'cylinder' then
- local radius, length = 0.1, 0.3
- collider = world:newCylinderCollider(position, radius, length)
- elseif colliderType == 'capsule' then
- local radius, length = 0.1, 0.3
- collider = world:newCapsuleCollider(position, radius, length)
- end
- local shade = 0.2 + 0.6 * lovr.math.random()
- collider:setUserData({shade, shade, shade})
- collider:setOrientation(math.pi, lovr.math.random(), lovr.math.random(), lovr.math.random())
- count = count - 1
- end
- end
- function lovr.draw()
- for i, collider in ipairs(world:getColliders()) do
- -- rendering shapes of each collider
- drawCollider(collider)
- -- debug geometry for joints (no joints are used in this example)
- drawAttachedJoints(collider)
- end
- end
- function drawCollider(collider)
- local color = collider:getUserData()
- lovr.graphics.setColor(color or 0x202020)
- local shape = collider:getShapes()[1]
- if shape:isSensor() then
- local r,g,b = lovr.graphics.getColor()
- lovr.graphics.setColor(r,g,b,0.2)
- end
- -- shapes
- for _, shape in ipairs(collider:getShapes()) do
- local shapeType = shape:getType()
- local x,y,z, angle, ax,ay,az = collider:getPose()
- -- draw primitive at collider's position with correct dimensions
- if shapeType == 'box' then
- local sx, sy, sz = shape:getDimensions()
- lovr.graphics.box('fill', x,y,z, sx,sy,sz, angle, ax,ay,az)
- elseif shapeType == 'sphere' then
- lovr.graphics.sphere(x,y,z, shape:getRadius())
- elseif shapeType == 'cylinder' then
- local l, r = shape:getLength(), shape:getRadius()
- local x,y,z, angle, ax,ay,az = collider:getPose()
- lovr.graphics.cylinder(x,y,z, l, angle, ax,ay,az, r, r)
- elseif shapeType == 'capsule' then
- local l, r = shape:getLength(), shape:getRadius()
- local x,y,z, angle, ax,ay,az = collider:getPose()
- local m = mat4(x,y,z, 1,1,1, angle, ax,ay,az)
- lovr.graphics.cylinder(x,y,z, l, angle, ax,ay,az, r, r, false)
- lovr.graphics.sphere(vec3(m:mul(0, 0, l/2)), r)
- lovr.graphics.sphere(vec3(m:mul(0, 0, -l/2)), r)
- end
- end
- end
- function drawAttachedJoints(collider)
- lovr.graphics.setColor(1,1,1,0.3)
- -- joints are attached to two colliders; function draws joint for second collider
- for j, joint in ipairs(collider:getJoints()) do
- local anchoring, attached = joint:getColliders()
- if attached == collider then
- jointType = joint:getType()
- if jointType == 'ball' then
- local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
- drawAnchor(vec3(x1,y1,z1))
- drawAnchor(vec3(x2,y2,z2))
- elseif jointType == 'slider' then
- local position = joint:getPosition()
- local x,y,z = anchoring:getPosition()
- drawAxis(vec3(x,y,z), vec3(joint:getAxis()))
- elseif jointType == 'distance' then
- local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
- drawAnchor(vec3(x1,y1,z1))
- drawAnchor(vec3(x2,y2,z2))
- drawAxis(vec3(x2,y2,z2), vec3(x1, y1, z1) - vec3(x2,y2,z2))
- elseif jointType == 'hinge' then
- local x1, y1, z1, x2, y2, z2 = joint:getAnchors()
- drawAnchor(vec3(x1,y1,z1))
- drawAnchor(vec3(x2,y2,z2))
- drawAxis(vec3(x1,y1,z1), vec3(joint:getAxis()))
- end
- end
- end
- end
- function drawAnchor(origin)
- lovr.graphics.sphere(origin, .02)
- end
- function drawAxis(origin, axis)
- lovr.graphics.line(origin, origin + axis:normalize() * 0.3)
- end
|