112 lines
3.5 KiB
Text
112 lines
3.5 KiB
Text
-- Soft bodies: a flag pinned to a pole, a sheet pinned at four corners catching a crate, a rope
|
|
-- swinging from a crane, and a balloon under pressure dropped onto the floor.
|
|
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 cloth = materialNew()
|
|
materialSetColor(cloth, 220, 60, 60)
|
|
materialSetDoubleSided(cloth, true)
|
|
materialSetRoughness(cloth, 0.8)
|
|
local linen = materialNew()
|
|
materialSetColor(linen, 230, 225, 200)
|
|
materialSetDoubleSided(linen, true)
|
|
local wood = materialNew()
|
|
materialSetColor(wood, 150, 100, 50)
|
|
local hemp = materialNew()
|
|
materialSetColor(hemp, 190, 160, 100)
|
|
local rubber = materialNew()
|
|
materialSetColor(rubber, 80, 180, 90)
|
|
|
|
local floor = nodeNew()
|
|
nodeSetMesh(floor, meshBox(16, 0.2, 12), stone)
|
|
nodeSetPosition(floor, 0, -0.1, 0)
|
|
bodyNew(floor, BODY_STATIC, SHAPE_BOX, 16, 0.2, 12)
|
|
|
|
-- The flag: a grid standing upright, pinned along its left edge to the pole.
|
|
local pole = nodeNew()
|
|
nodeSetMesh(pole, meshCylinder(0.04, 3, 8), wood)
|
|
nodeSetPosition(pole, -5, 1.5, 0)
|
|
bodyNew(pole, BODY_STATIC, SHAPE_CYLINDER, 0.04, 3)
|
|
local flag = nodeNew()
|
|
nodeSetMesh(flag, meshPlane(1.6, 1.0, 16, 10), cloth)
|
|
nodeSetPosition(flag, -4.16, 2.4, 0)
|
|
nodeSetRotation(flag, 90, 0, 0)
|
|
softNew(flag, SOFT_CLOTH)
|
|
softSetStiffness(flag, 0.95, 0.1)
|
|
softSetMass(flag, 0.5)
|
|
for _, y in ipairs({ 1.9, 2.15, 2.4, 2.65, 2.9 }) do
|
|
softPin(flag, -4.96, y, 0)
|
|
end
|
|
|
|
-- The sheet: pinned at four corners, a crate dropped onto it.
|
|
local sheet = nodeNew()
|
|
nodeSetMesh(sheet, meshPlane(3, 3, 20, 20), linen)
|
|
nodeSetPosition(sheet, 0, 1.6, 0)
|
|
softNew(sheet, SOFT_CLOTH)
|
|
softSetStiffness(sheet, 1.0, 0.05)
|
|
softSetMass(sheet, 4)
|
|
for _, c in ipairs({ { -1.5, -1.5 }, { 1.5, -1.5 }, { -1.5, 1.5 }, { 1.5, 1.5 } }) do
|
|
softPin(sheet, c[1], 1.6, c[2])
|
|
end
|
|
local crate = nodeNew()
|
|
nodeSetMesh(crate, meshBox(0.6, 0.6, 0.6), wood)
|
|
nodeSetPosition(crate, 0.2, 3.5, 0.1)
|
|
nodeSetRotation(crate, 20, 30, 0)
|
|
bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 0.6, 0.6, 0.6)
|
|
bodySetMass(crate, 3)
|
|
|
|
-- The rope: from a crane arm out and down, swinging free from a horizontal start.
|
|
local crane = nodeNew()
|
|
nodeSetPosition(crane, 4, 4, -1)
|
|
local rope = nodeNew()
|
|
nodeSetPosition(rope, 4, 4, -1)
|
|
softNew(rope, SOFT_ROPE, 6.5, 4, -1, 16, 0.04)
|
|
nodeSetMaterial(rope, hemp)
|
|
softSetMass(rope, 1.5)
|
|
softPin(rope, 4, 4, -1, crane)
|
|
|
|
-- The balloon: a sphere kept round by pressure, dropped and squashed.
|
|
local balloon = nodeNew()
|
|
nodeSetMesh(balloon, meshSphere(0.5, 14), rubber)
|
|
nodeSetPosition(balloon, 4, 2.5, 2)
|
|
softNew(balloon, SOFT_BODY)
|
|
softSetStiffness(balloon, 0.8, 0.3)
|
|
softSetMass(balloon, 0.6)
|
|
softSetPressure(balloon, 8)
|
|
|
|
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, 3.5, 9)
|
|
nodeLookAt(camera, 0, 1.5, 0)
|
|
cameraSet(camera)
|
|
|
|
function onOverlayUpdate()
|
|
frames = frames + 1
|
|
overlayClear()
|
|
fontPrint(20, 20, "Soft bodies, frame " .. frames)
|
|
if frames % 30 == 0 then
|
|
local cx, cy = nodeGetPosition(crate)
|
|
local bx, by = nodeGetPosition(balloon)
|
|
debugPrint(string.format("frame %d crate y %.2f balloon y %.2f", frames, cy, by))
|
|
end
|
|
if frames == 40 or frames == 100 or frames == 170 then
|
|
singeScreenshot()
|
|
end
|
|
if frames == 180 then
|
|
singeQuit()
|
|
end
|
|
end
|