104 lines
3.6 KiB
Text
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
|