125 lines
4.2 KiB
Text
125 lines
4.2 KiB
Text
-- Physics stage 4: the Duck as a convex hull rolling down a ramp, a torus as a static mesh shape
|
|
-- the ball rolls around, a swinging door on a hinge with limits, a pendulum on a ball joint, and
|
|
-- a crate on a slider.
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
|
|
local frames = 0
|
|
|
|
fontSelect(font)
|
|
discPlay()
|
|
sceneEnable(true)
|
|
sceneSetBackground(18, 18, 30, 255)
|
|
sceneSetAmbient(70, 70, 85)
|
|
|
|
local floorLook = materialNew()
|
|
materialSetColor(floorLook, 120, 110, 100)
|
|
materialSetRoughness(floorLook, 0.9)
|
|
local rampLook = materialNew()
|
|
materialSetColor(rampLook, 90, 100, 130)
|
|
local doorLook = materialNew()
|
|
materialSetColor(doorLook, 160, 90, 40)
|
|
local ballLook = materialNew()
|
|
materialSetColor(ballLook, 60, 140, 230)
|
|
local ringLook = materialNew()
|
|
materialSetColor(ringLook, 220, 200, 60)
|
|
materialSetMetallic(ringLook, 0.8)
|
|
materialSetRoughness(ringLook, 0.35)
|
|
local frameLook = materialNew()
|
|
materialSetColor(frameLook, 40, 40, 50)
|
|
local crateLook = materialNew()
|
|
materialSetColor(crateLook, 200, 140, 60)
|
|
|
|
local floor = nodeNew()
|
|
nodeSetMesh(floor, meshBox(16, 0.2, 16), floorLook)
|
|
nodeSetPosition(floor, 0, -1.9, 0)
|
|
bodyNew(floor, BODY_STATIC, SHAPE_BOX, 16, 0.2, 16)
|
|
|
|
-- A ramp, and the Duck as a convex hull rolling down it.
|
|
local ramp = nodeNew()
|
|
nodeSetMesh(ramp, meshBox(3.0, 0.2, 2.2), rampLook)
|
|
nodeSetPosition(ramp, -3.4, -1.0, -1.0)
|
|
nodeSetRotation(ramp, 0, 0, -28)
|
|
bodyNew(ramp, BODY_STATIC, SHAPE_BOX, 3.0, 0.2, 2.2)
|
|
|
|
local duck = modelInstance(modelLoad("testScripts/Models/Duck.glb"))
|
|
nodeSetPosition(duck, -4.4, 0.6, -1.0)
|
|
nodeSetRotation(duck, 0, 90, 0)
|
|
nodeSetScale(duck, 0.6)
|
|
bodyNew(duck, BODY_DYNAMIC, SHAPE_HULL)
|
|
bodySetFriction(duck, 0.4)
|
|
|
|
-- A torus lying on the floor as a static triangle mesh; the ball rolls around inside it.
|
|
local ring = nodeNew()
|
|
nodeSetMesh(ring, meshTorus(1.2, 0.25, 40), ringLook)
|
|
nodeSetPosition(ring, 2.6, -1.55, 0.6)
|
|
bodyNew(ring, BODY_STATIC, SHAPE_MESH)
|
|
|
|
local ball = nodeNew()
|
|
nodeSetMesh(ball, meshSphere(0.3, 32), ballLook)
|
|
nodeSetPosition(ball, 2.6, 1.2, 0.6)
|
|
bodyNew(ball, BODY_DYNAMIC, SHAPE_SPHERE, 0.3)
|
|
bodySetBounce(ball, 0.4)
|
|
|
|
-- A door hinged to the world along its left edge, limited to swing 100 degrees one way.
|
|
local post = nodeNew()
|
|
nodeSetMesh(post, meshBox(0.15, 2.4, 0.15), frameLook)
|
|
nodeSetPosition(post, -1.0, -0.6, 1.4)
|
|
bodyNew(post, BODY_STATIC, SHAPE_BOX, 0.15, 2.4, 0.15)
|
|
|
|
local door = nodeNew()
|
|
nodeSetMesh(door, meshBox(1.4, 2.2, 0.1), doorLook)
|
|
nodeSetPosition(door, -0.1, -0.62, 1.4)
|
|
bodyNew(door, BODY_DYNAMIC, SHAPE_BOX, 1.4, 2.2, 0.1)
|
|
bodySetMass(door, 8)
|
|
local hinge = jointHinge(door, -1, -0.85, -0.62, 1.4, 0, 1, 0)
|
|
jointSetLimits(hinge, 0, 100)
|
|
|
|
-- A pendulum: a ball hanging from a point in the air.
|
|
local bob = nodeNew()
|
|
nodeSetMesh(bob, meshSphere(0.25, 24), ballLook)
|
|
nodeSetPosition(bob, 1.4, 1.6, -1.6)
|
|
bodyNew(bob, BODY_DYNAMIC, SHAPE_SPHERE, 0.25)
|
|
jointBall(bob, -1, 0.2, 2.6, -1.6)
|
|
|
|
-- A crate on a slider along X, pushed sideways at the start.
|
|
local rail = nodeNew()
|
|
nodeSetMesh(rail, meshBox(3.0, 0.08, 0.08), frameLook)
|
|
nodeSetPosition(rail, 0.6, 0.9, -3.0)
|
|
local crate = nodeNew()
|
|
nodeSetMesh(crate, meshBox(0.5, 0.5, 0.5), crateLook)
|
|
nodeSetPosition(crate, -0.6, 0.9, -3.0)
|
|
bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 0.5, 0.5, 0.5)
|
|
local slider = jointSlider(crate, -1, -0.6, 0.9, -3.0, 1, 0, 0)
|
|
jointSetLimits(slider, 0, 2.4)
|
|
bodySetVelocity(crate, 3, 0, 0)
|
|
|
|
local sun = lightNew(LIGHT_DIRECTIONAL)
|
|
nodeSetPosition(sun, -3, 6, 4)
|
|
nodeLookAt(sun, 0, 0, 0)
|
|
lightSetIntensity(sun, 1.2)
|
|
lightSetShadow(sun, true)
|
|
|
|
local camera = nodeNew()
|
|
nodeSetPosition(camera, 0.8, 2.4, 7.5)
|
|
nodeLookAt(camera, 0, -0.4, -0.5)
|
|
cameraSet(camera)
|
|
cameraSetPerspective(52, 0.1, 100)
|
|
|
|
function onOverlayUpdate()
|
|
frames = frames + 1
|
|
overlayClear()
|
|
fontPrint(20, 20, "Physics joints and hulls, frame " .. frames)
|
|
if frames == 40 then
|
|
-- Kick the door and the pendulum.
|
|
bodyApplyImpulse(door, 0, 0, -60, 0.5, -0.62, 1.45)
|
|
bodyApplyImpulse(bob, 6, 0, 0)
|
|
end
|
|
if frames == 30 or frames == 90 or frames == 180 then
|
|
singeScreenshot()
|
|
end
|
|
if frames == 200 then
|
|
local dx, dy, dz = nodeGetWorldPosition(duck)
|
|
local cx = nodeGetWorldPosition(crate)
|
|
debugPrint(string.format("RESULT duck %.2f %.2f %.2f crate x %.2f", dx, dy, dz, cx))
|
|
singeQuit()
|
|
end
|
|
end
|