singe/testScripts/scene33.singe

104 lines
3.6 KiB
Text

-- Navigation: a walkable mesh baked from Sponza's floor, a path traced along the nave round the
-- columns (drawn as a chain of thin posts), and six Foxes wandering between random points on the
-- mesh without walking through the columns or each other (onNavArrived sends each to a new spot).
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
sceneEnable(true)
sceneSetBackground(120, 150, 200, 255)
sceneSetAmbient(120, 126, 150)
sceneSetShadowSize(2048)
local model = modelLoad("testScripts/Models/Sponza.glb")
local sponza = modelInstance(model)
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, 5, 22, 4)
nodeLookAt(sun, -2, 0, -1.5)
lightSetIntensity(sun, 4.5)
lightSetColor(sun, 255, 236, 205)
lightSetShadow(sun, true)
-- The mesh: an agent 0.4 wide and 1.6 tall that climbs 0.3 and walks slopes to 45 degrees.
local nav = navNew(0.4, 1.6, 45, 0.3)
navAddNode(nav, sponza)
navBuild(nav)
-- The path from one end of the nave to the other, as posts at its corners and along its legs.
local marker = materialNew()
materialSetColor(marker, 255, 60, 40)
materialSetEmissive(marker, 120, 20, 10)
local path = navPath(nav, 11, 0.2, 0, -11, 0.2, 0)
local pathPosts = 0
if path then
for i = 1, #path do
local post = nodeNew()
nodeSetMesh(post, meshCylinder(0.08, 0.6, 8), marker)
nodeSetPosition(post, path[i][1], path[i][2] + 0.3, path[i][3])
pathPosts = pathPosts + 1
if i < #path then
local dx, dy, dz = path[i + 1][1] - path[i][1], path[i + 1][2] - path[i][2], path[i + 1][3] - path[i][3]
local length = math.sqrt(dx * dx + dy * dy + dz * dz)
for s = 1, math.floor(length / 0.8) do
local t = s * 0.8 / length
local p = nodeNew()
nodeSetMesh(p, meshSphere(0.06, 8), marker)
nodeSetPosition(p, path[i][1] + dx * t, path[i][2] + dy * t + 0.1, path[i][3] + dz * t)
end
end
end
end
-- The Foxes, each an agent sent to a random point and, when it arrives, to another.
local foxModel = modelLoad("testScripts/Models/Fox.glb")
local agents = {}
local foxes = {}
for i = 1, 6 do
local fox = modelInstance(foxModel)
nodeSetScale(fox, 0.01)
local x, y, z = navRandomPoint(nav)
nodeSetPosition(fox, x, y, z)
animationPlay(fox, "Walk", true)
local agent = navAgentNew(nav, fox, 0.35, 1.0, 1.4)
local tx, ty, tz = navRandomPoint(nav)
navAgentMoveTo(agent, tx, ty, tz)
agents[agent] = fox
foxes[i] = fox
end
function onNavArrived(agent)
local x, y, z = navRandomPoint(nav)
navAgentMoveTo(agent, x, y, z)
end
local camera = nodeNew()
cameraSet(camera)
cameraSetPerspective(60, 0.05, 100)
local stops = {
{ 10, 3, 0, -10, 0.5, 0 }, -- Down the nave along the path
{ 0, 5.5, 1, 0, 0.3, -6 }, -- From the gallery height over the atrium, the Foxes about
{ 4, 1.2, 0.5, -6, 0.6, 0.5 }, -- Low along the nave among them
{ -9, 1.6, 0.3, 8, 0.4, 0 }, -- From the far end back along the path
}
function onOverlayUpdate()
local stop = stops[math.min(#stops, math.floor(frames / 45) + 1)]
frames = frames + 1
nodeSetPosition(camera, stop[1], stop[2], stop[3])
nodeLookAt(camera, stop[4], stop[5], stop[6])
overlayClear()
fontPrint(20, 20, string.format("Navigation, frame %d path corners %d", frames, pathPosts))
if frames == 40 or frames == 85 or frames == 130 or frames == 175 then
singeScreenshot()
for agent, fox in pairs(agents) do
local x, y, z = nodeGetWorldPosition(fox)
local vx, vy, vz = navAgentGetVelocity(agent)
debugPrint(string.format("frame %d agent %d at %.1f %.1f %.1f moving %.2f %.2f", frames, agent, x, y, z, vx, vz))
end
end
if frames == 180 then
singeQuit()
end
end