Title: Polygon Soup for the Programmers Soul: 3D Pathfinding
1Polygon Soup for the Programmers Soul 3D
Pathfinding
Patrick Smith (psmith_at_westwood.com) Greg
Hjelstrom (greg_at_westwood.com)
2Introduction
- AI is an important contributor to the realism of
games. - Pathfinding is a major component of convincing AI.
3Problem Domain
- Pathfinding requires connectivity.
- A streetmap is a real-life example.
- Given this connectivity graph, paths can be found
using well known algorithms such as A. - How do we get this connectivity data?
4Connectivity Solutions
- In grid-based games the grid inherently provided
the connectivity data. - RTS games.
- Many 3D games use manual connectivity.
- Manually placed points and connections between
points. - Automatic connectivity.
- How?
5Floodfilling to the Rescue!
- Well reuse old 2D paint program technology the
recursive floodfill. - For our purposes the floodfill is really a
recursive physics simulation of an AI moving
between points. - The goal given a seed point, detect all
traversable locations in a level.
6The Floodfill Algorithm
- Simulate the AI moving in each of the 4 cardinal
directions. - Add each successful position to a list.
- Mark this position as traversable.
- Store the connection between positions.
- Pop the head of the list and recurse into it.
7Movement Simulation
- The character is represented by an axis aligned
collision box. - Our collision code uses swept boxes.
- The floodfill algorithm performs tens of millions
of swept box queries so we need to make them fast.
8Colliding with the World
- We use a hierarchical bounding volume tree to
quickly determine what meshes in the world need
to be checked for collision. - Each mesh contains an internal bounding volume
tree to quickly determine which of its triangles
need to be checked for collision. - For speed and space, we use axis aligned bounding
boxes.
9Swept Box Collision
- Separating axis theorem
- Given two convex polyhedra, if they are not
intersecting at least one separating plane will
exist. - The plane normal will be defined by either
- One of the faces of either object
- The cross product of two edges, one from each
object - Early rejection.
- Once you find a separating plane, you can reject
the triangle. - This algorithm can be extended to support swept
convex primitives, providing time of collision.
10Making a Move
- During the floodfill, to move one unit in any
given direction, we must successfully complete
the following steps - Move up the maximum height the AI can step over.
- Sweep the collision box one unit in the
movement direction at an angle equal to the
steepest slope the AI can climb. - Finally, sweep the collision box back down to the
ground to see if we have a place to stand.
11Of Units and Positions
- Our pathfinding system will make good use of the
AIs collision box. - Unit of Distance
- A unit is ¼ of the AIs collision box.
- Position
- A position is the volume defined by splitting the
collision box into four equal pieces.
12Visualizing the Data
- Each position is a box.
- Each unit moves one box length away.
- This forms a sort of grid.
- However, since the floodfill can travel over and
under overpasses there can be more then one
cell for every x,y position on the grid.
13What the Data Gives Us
- Each cell knows which directions it can travel
(up, down, left, right). - This linkage forms a connectivity graph of all
possible traversable locations in the level. - Given this connectivity graph we can now use our
favorite shortest path algorithm to pathfind
between any two points in the level.
14Too Much Data!
- A typical level might require in excess of 2
million cells. - This can require upwards of 128 MB of RAM just to
store the graph. - This is way too much data for a real time game.
15Compression
- The goal is to combine cells into largest
possible rectangular regions.
16Sectors
- Compressed cells become sectors.
- Sectors are 3D axis-aligned boxes that the
pathfind system can use to determine where an AI
is in the connectivity graph. - Sectors need connection data to other sectors.
17Portals
- Portals are connections between sectors.
- Portals can be one-way or two-way.
- Portals have a physical location in the world.
- Because of this, an AI simple needs to walk to
the portal, at which point they are at the
destination sector. - This allows us to easily integrate teleporters
such as doors, ladders, elevators, or even
star-trek like teleporters. - How do we generate these portals?
18Portal Generation
- During the compression stage, we store a list of
edge cells with each sector. - Each edge cell also stores which sector it
belongs to.
19Portal Generation
- Once all sectors have been generated, the edge
cells can then be converted into portals. - These portals know what sector they are coming
from and which sector they are going to.
20Data Summary
- Floodfill the world by simulating the AI walking
in a recursive pattern. - Compress the millions of floodfill cells into
sectors. - Use the edge cells of a sector to generate
portals between sectors.
21Floodfill Demo
22Extending the Pathsolve
- Lets consider a few pieces of information we can
bake into our pathfind data that will allow us
to easily path solve across teleporters such as
doors, elevators, and ladders. - A teleporter is a feature of the level that,
when activated, will transport a game object from
one part of the world to the other.
23Floodfilling across Teleporters
- Consider a building with roof access via elevator
only. - Currently, the pathsolve will never reach the
roof. - To solve this
- During floodfill, check each cell to see if its
inside an entrance zone. - Create a cell inside the exit zone for the
elevator and continue floodfilling from this
cell.
24Pathsolving Across Teleporters
- Incorporate teleporters post floodfill.
- Each teleporter has an entrance and exit zone.
- For each teleporter in the level, check to see if
both the entrance and exit zones intersect a
pathfind sector. - Create a teleporter portal and add it to the
portal list for the entrance sector. - Create a portal and add it to the portal list for
the exit sector. - Link the entrance portal to the exit portal as a
one-way transition.
25Teleport Portal Data
- Embed as much information about the teleporter as
necessary into the entrance portal. - Flag specifying teleporter type.
- Door, elevator, ladder, etc.
- Teleporter mechanism ID.
- Keys needed to operate mechanism.
26Solving the Path
- Given our connectivity graph, solving the path is
now straightforward. - Given an AIs current position and a destination
position we can lookup the pathfind sectors that
contain these points. - Path is unsolvable if either sector cannot be
found. - We now have a start position and end position
within our connectivity graph.
27The Pathsolve Algorithm
- Most traditional shortest path algorithms can be
used. - A modified A worked pretty good for Renegade.
- First, loop over all the portals for the starting
sector. - Each portal has a destination sector.
- Each of these destination sectors has a list of
portals. - Continue traversing sectors until youve reached
the destination sector.
28Path Demo
29Time to Solve
- Short paths can solve quickly.
- Long paths take a bit longer.
- 20 AIs solving long paths at the same time can
tax even the most efficient pathsolver.
30Distributing the Solve
- If an AI takes 15 frames to solve a path in a 30
FPS game, they will only pause for ½ a second. - In most cases, this short pause is not
noticeable. - This means we can devote a set amount of time
each frame to pathfinding and simply solve as
much of each path as possible.
31The Distributed Algorithm
while (Time_Left () PathSolver ! NULL)
if (PathSolver-gtProcess (Time_Left_This_Frame))
RELEASE (PathSolver)
PathSolver Get_Next_Path_Solver ()
32The Distributed Algorithm
while (Time_Has_Not_Elapsed) CPathfindSector
sector Get_Least_Cost_Sector () if (sector
NULL) Handle_No_Path () else if (sector
DestinationSector) Hande_Path_Found () else
CPathfindPortal portal NULL while (portal
sector-gtGet_Next_Portal (portal))
Process_Portal (portal)
33Robotic Paths
- The results of this path solve will often look
robotic. - Straight lines connecting points in the portals
along the path. - This path can be made more organic by creating a
spline which goes through its points.
34Smoothing the Path
- We chose to use a natural spline whose control
points are points along the path. - Unfortunately this can cause the path to stray
outside of valid pathfind sectors causing
characters to get stuck against walls for
example. - To solve this problem, we convert the spline into
a series of Bezier curves and constrain the
control points to our pathfind sectors. - A Bezier curve is guaranteed to be contained by
the convex shape defined by its control points.
35Visualizing the Spline
36Innate Waypaths
- Waypaths are hand-placed paths consisting of a
series of points. - Waypaths can be linear or splined, one-way,
two-way, and looping. - Each point on the waypath can encode specific
information such as speed up, slow down, jump,
crouch, slide, crawl, etc. - The path solver can bias towards these waypaths
to achieve complex results.
37Using Innate Waypaths
- Create a pathfind sector without position or
size. - Intersect each point on the waypath with sectors
that already exist in the world. - Create portals at each intersection point that
exit from the real-world sectors onto the
imaginary innate waypath sector. - Intersect each segment of the waypath with sector
boundaries that already exist in the world. - Create portals at these intersections as well.
- Flag these portals so the shortest path heuristic
can make them cheaper to follow.
38Waypath Demo
39Learning From the Player
- Players can conceive of more complicated actions
than AI. - By allowing the AI to copy some of the players
moves, they appear more intelligent.
40Implementing Learning
- Everytime the player jumps and lands
- Lookup the pathfind sector the player jumped from
and landed in. - Record the players orientation and velocity at
jump time. - Add a temporary jump portal from the start
sector to the land sector. - The AI will now seamlessly incorporate this move
into its pathsolve.
41Learning Demo
42Vehicle Pathfinding
- Vehicles are intrinsically more difficult.
- Vehicles are bigger than characters.
- Vehicles have turn radius.
- Vehicles do not stop on a dime.
- Vehicles can roll over.
- Vehicles behave differently in forwards and
reverse.
43Re-using Data
- Vehicles can reuse bipedal data.
- Take into consideration the vehicles turn radius
when evaluating portals. - If a vehicle cannot make a turn, coming from its
current portal to the destination portal, then
skip the destination portal.
44Vehicle Curves
- Vehicles need to turn out to make sharp
corners. - By creating a vehicle curve that is based on the
turn radius of the vehicle, the vehicle will
seamlessly follow its path. - Vehicle curve is composed of three parts
- The exit curve from the previous point.
- A straight line from the exit curve to the
entrance curve of the next point. - The entrance curve to the next point.
45Vehicle Curve Anatomy
- Here you can see the 3 distinct parts of the
vehicle curve.
46Vehicle Curve Results
- Here is a comparison of a linear (unsplined)
vehicle path and the post-processed vehicle
curve.
47Vehicle Demo
48Conclusion
- Floodfill solves static pathfinding.
- Kinks in the path arise due to the non-uniform
nature of the sectors. - Does not address dynamic objects.
- Innate waypaths and jump portals increase
intelligence. - Arbitrary vehicle pathfinding is difficult.
- Reusing data is possible, but not optimal.
- Vehicle curves simplify the path following logic.
49Q A