singe/testScripts/scene11.singe

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