128 lines
4.2 KiB
Text
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
|