105 lines
3.4 KiB
Text
105 lines
3.4 KiB
Text
-- Ragdolls: one Fox runs at a wall and collapses on impact; another is dropped onto a flight of
|
|
-- stairs limp; a third lies on the floor and gets up again under motor strength.
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
|
|
local frames = 0
|
|
|
|
fontSelect(font)
|
|
discPlay()
|
|
sceneEnable(true)
|
|
sceneSetBackground(0, 0, 0, 0)
|
|
sceneSetAmbient(70, 70, 80)
|
|
|
|
local stone = materialNew()
|
|
materialSetColor(stone, 120, 120, 130)
|
|
materialSetRoughness(stone, 0.9)
|
|
local steel = materialNew()
|
|
materialSetColor(steel, 90, 110, 150)
|
|
|
|
local function block(x, y, z, w, h, d, material)
|
|
local node = nodeNew()
|
|
nodeSetMesh(node, meshBox(w, h, d), material)
|
|
nodeSetPosition(node, x, y, z)
|
|
bodyNew(node, BODY_STATIC, SHAPE_BOX, w, h, d)
|
|
return node
|
|
end
|
|
block(0, -0.1, 0, 20, 0.2, 14, stone)
|
|
block(4, 0.75, -1, 0.3, 1.5, 3, steel) -- The wall the runner hits
|
|
for i = 1, 5 do
|
|
block(-4 - i * 0.5, i * 0.15, 3, 0.5, i * 0.3, 3, stone) -- Stairs going up to the left
|
|
end
|
|
|
|
local foxModel = modelLoad("testScripts/Models/Fox.glb")
|
|
|
|
-- The runner: a player carrying the Fox; the ragdoll is made now and switched on at the crash.
|
|
local runner = nodeNew()
|
|
nodeSetPosition(runner, -1, 0.05, -1)
|
|
playerNew(runner, 0.3, 0.9)
|
|
local runnerFox = modelInstance(foxModel)
|
|
nodeSetParent(runnerFox, runner)
|
|
nodeSetScale(runnerFox, 0.01)
|
|
nodeSetRotation(runnerFox, 0, 90, 0)
|
|
animationPlay(runnerFox, "Run", true)
|
|
ragdollNew(runnerFox)
|
|
|
|
-- The faller: dropped limp from above the stairs.
|
|
local faller = modelInstance(foxModel)
|
|
nodeSetPosition(faller, -6.5, 2.5, 3)
|
|
nodeSetScale(faller, 0.01)
|
|
nodeSetRotation(faller, 30, 40, 0)
|
|
animationPlay(faller, "Survey", true)
|
|
ragdollNew(faller)
|
|
ragdollActivate(faller)
|
|
|
|
-- The riser: lying limp on the floor, then pulled back toward its standing pose.
|
|
local riser = modelInstance(foxModel)
|
|
nodeSetPosition(riser, 3, 0, 3.5)
|
|
nodeSetScale(riser, 0.01)
|
|
nodeSetRotation(riser, 0, -30, 0)
|
|
animationPlay(riser, "Survey", true)
|
|
ragdollNew(riser)
|
|
ragdollActivate(riser)
|
|
|
|
local sun = lightNew(LIGHT_DIRECTIONAL)
|
|
nodeSetPosition(sun, -4, 8, 6)
|
|
nodeLookAt(sun, 0, 0, 0)
|
|
lightSetIntensity(sun, 1.5)
|
|
lightSetShadow(sun, true)
|
|
|
|
local camera = nodeNew()
|
|
nodeSetPosition(camera, 0, 4, 9)
|
|
nodeLookAt(camera, -1, 0.5, 0)
|
|
cameraSet(camera)
|
|
|
|
local crashed = false
|
|
|
|
function onCollision(a, b, x, y, z, speed)
|
|
if not crashed and (a == runner or b == runner) and speed > 1.5 then
|
|
crashed = true
|
|
playerSetEnabled(runner, false)
|
|
ragdollActivate(runnerFox)
|
|
ragdollApplyImpulse(runnerFox, "b_Spine02_03", 40, 30, 0)
|
|
end
|
|
end
|
|
|
|
function onOverlayUpdate()
|
|
frames = frames + 1
|
|
if not crashed then
|
|
playerMove(runner, 4, 0)
|
|
end
|
|
if frames == 100 then
|
|
ragdollSetStrength(riser, 60)
|
|
end
|
|
overlayClear()
|
|
fontPrint(20, 20, string.format("Ragdolls, frame %d %s faller %s riser %s", frames, crashed and "crashed" or "running", ragdollIsResting(faller) and "resting" or "moving", ragdollIsResting(riser) and "resting" or "moving"))
|
|
if frames % 30 == 0 then
|
|
local rx, ry, rz = nodeGetPosition(runner)
|
|
local fx, fy, fz = nodeGetWorldPosition(faller)
|
|
debugPrint(string.format("frame %d runner %.2f %.2f crashed %s | faller %.2f %.2f %.2f resting %s | riser resting %s", frames, rx, ry, tostring(crashed), fx, fy, fz, tostring(ragdollIsResting(faller)), tostring(ragdollIsResting(riser))))
|
|
end
|
|
if frames == 50 or frames == 110 or frames == 170 then
|
|
singeScreenshot()
|
|
end
|
|
if frames == 180 then
|
|
singeQuit()
|
|
end
|
|
end
|