singe/testScripts/scene18.singe

128 lines
4.2 KiB
Text

-- Particles, 3D: a torch flame on a post, a fountain, and dust drifting in a sunbeam over the disc,
-- with a crate to show the billboards depth-testing against geometry and casting no shadow. The
-- smoke is lit by the scene's lights and fades softly where it meets the post; sparks bounce on
-- the floor and leave trails; the fountain's drops fade into the pool rather than cutting into it.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
discPlay()
sceneEnable(true)
sceneSetBackground(0, 0, 0, 0)
sceneSetAmbient(50, 50, 60)
local stone = materialNew()
materialSetColor(stone, 110, 110, 120)
materialSetRoughness(stone, 0.9)
local wood = materialNew()
materialSetColor(wood, 140, 90, 50)
local floor = nodeNew()
nodeSetMesh(floor, meshBox(12, 0.2, 8), stone)
nodeSetPosition(floor, 0, -1.1, 0)
local post = nodeNew()
nodeSetMesh(post, meshCylinder(0.08, 2.2, 12), wood)
nodeSetPosition(post, -2.5, 0, 0)
local crate = nodeNew()
nodeSetMesh(crate, meshBox(1, 1, 1), wood)
nodeSetPosition(crate, 0.8, -0.5, 0.5)
-- The flame: additive, born in a small ball at the top of the post, rising and shrinking.
local torchTip = nodeNew()
nodeSetParent(torchTip, post)
nodeSetPosition(torchTip, 0, 1.15, 0)
local flame = emitterNew(torchTip)
emitterSetBlend(flame, PARTICLE_ADD)
emitterSetRate(flame, 140)
emitterSetLife(flame, 0.4, 0.9)
emitterSetSpeed(flame, 0.6, 1.4)
emitterSetDirection(flame, 0, 1, 0)
emitterSetSpread(flame, 15)
emitterSetSize(flame, 0.35, 0.05, 0.3)
emitterSetColor(flame, 255, 200, 90, 255, 255, 40, 0, 0)
emitterSetRadius(flame, 0.06)
emitterSetSpin(flame, -90, 90)
emitterStart(flame)
-- Smoke above the flame, alpha blended and slow.
local smoke = emitterNew(torchTip)
emitterSetRate(smoke, 25)
emitterSetLife(smoke, 1.5, 2.5)
emitterSetSpeed(smoke, 0.5, 0.9)
emitterSetDirection(smoke, 0.2, 1, 0)
emitterSetSpread(smoke, 20)
emitterSetSize(smoke, 0.2, 0.9, 0.2)
emitterSetColor(smoke, 160, 160, 170, 120, 120, 120, 130, 0)
emitterSetSpin(smoke, -30, 30)
emitterSetLit(smoke, true)
emitterSetSoftness(smoke, 0.3)
emitterStart(smoke)
-- Sparks: thrown from the torch, falling, bouncing on the floor, each trailing a streak.
local sparks = emitterNew(torchTip)
emitterSetBlend(sparks, PARTICLE_ADD)
emitterSetRate(sparks, 40)
emitterSetLife(sparks, 1.2, 2.0)
emitterSetSpeed(sparks, 1.5, 3.0)
emitterSetDirection(sparks, 0, 1, 0)
emitterSetSpread(sparks, 50)
emitterSetGravity(sparks, 0, -6, 0)
emitterSetSize(sparks, 0.05, 0.02)
emitterSetColor(sparks, 255, 220, 120, 255, 255, 80, 20, 0)
emitterSetCollide(sparks, COLLIDE_FLOOR, 0.5, 0.3, -1)
emitterSetTrail(sparks, 8, 0.03)
emitterStart(sparks)
-- A fountain: water drops thrown up and falling under gravity, staying where they were born.
local spout = nodeNew()
nodeSetPosition(spout, 2.5, -1, -0.5)
local fountain = emitterNew(spout)
emitterSetRate(fountain, 300)
emitterSetLife(fountain, 1.0, 1.6)
emitterSetSpeed(fountain, 4.0, 5.0)
emitterSetDirection(fountain, 0, 1, 0)
emitterSetSpread(fountain, 8)
emitterSetGravity(fountain, 0, -9.8, 0)
emitterSetSize(fountain, 0.08, 0.12)
emitterSetColor(fountain, 150, 200, 255, 220, 150, 200, 255, 0)
emitterSetMax(fountain, 1500)
emitterSetSoftness(fountain, 0.15)
emitterStart(fountain)
-- Dust: a few slow motes in a box of air, following nothing.
local air = nodeNew()
nodeSetPosition(air, 0, 0.5, 0)
local dust = emitterNew(air)
emitterSetRate(dust, 20)
emitterSetLife(dust, 4, 6)
emitterSetSpeed(dust, 0.05, 0.2)
emitterSetSpread(dust, 180)
emitterSetSize(dust, 0.04, 0.04)
emitterSetColor(dust, 255, 240, 200, 0, 255, 240, 200, 160)
emitterSetRadius(dust, 2.5)
emitterSetMax(dust, 200)
emitterStart(dust)
emitterBurst(dust, 120)
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, -3, 6, 4)
nodeLookAt(sun, 0, 0, 0)
lightSetIntensity(sun, 1.4)
lightSetShadow(sun, true)
local camera = nodeNew()
nodeSetPosition(camera, 0, 1.2, 7)
nodeLookAt(camera, 0, 0, 0)
cameraSet(camera)
function onOverlayUpdate()
frames = frames + 1
nodeRotate(post, 0, 0.5, 0)
overlayClear()
fontPrint(20, 20, "Particles 3D, frame " .. frames .. " flame " .. emitterGetCount(flame) .. " fountain " .. emitterGetCount(fountain))
if frames == 60 or frames == 120 or frames == 170 then
singeScreenshot()
end
if frames == 180 then
singeQuit()
end
end