pathfinding in an entity cluttered 3d virtual environment · pathfinding in an entity cluttered 3d...
TRANSCRIPT
The candidate confirms that the work submitted is their own and the appropriate credit has been given where reference has been made to the work of others. I understand that failure to attribute material which is obtained from another source may be considered as plagiarism. (Signature of student) ___________________________________________
Pathfinding in an Entity Cluttered 3D Virtual
Environment Matt Hall
BSc Computing 2004/2005
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
i
Summary
This report explores the history of pathfinding, and the implementation and consequences of
pathfinding in an entity cluttered 3D virtual environment. The main focus is on pathfinding, particularly
the A* pathfinding algorithm, as well as the environment which the pathfinding is conducted on.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
ii
Acknowledgments
Many thanks to my supervisor Professor D.C. Hogg, for giving me countless ideas for improving my
project, and to my assessor Dr R.A. Ruddle for giving me useful feedback and suggestions at the
Demo Session.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
iii
Contents
1. Introduction - 1
1.1. Aim of the Project - 1
1.2. Requirements of the Project - 1
2. Design & Research - 2
2.1. The History of Pathfinding - 2
2.2. Terms Used in Pathfinding - 3
2.3. Existing Solutions to the problem - 4
2.4. Representing the Problem in a Virtual Environment - 5
2.5. Improving the Partition - 7
2.6. Search Techniques - 8
2.6.1. Breadth-First Search - 8
2.6.2. Depth-First Search - 9
2.6.3. Best-First Search - 10
2.6.4. A* Algorithm - 11
2.7. Graphical APIs - 13
2.8. Programming Languages - 14
2.9. Design Methodology - 15
2.10. Project Schedule - 16
3. Implementation - 17
3.1. Prototype - 17
3.1.1. Stage 1 (Graphics) - 17
3.1.2. Stage 2 (Pathfinding Algorithm) - 18
3.1.3. Stage 3 (Scale of the Environment) - 18
3.2. Final Project - 19
3.2.1. Version History - 20
3.2.2. Input Code - 21
3.2.3. Quadtree Implementation - 22
3.2.4. Searchtree Implementation - 24
3.2.5. Pathfinding Code - 26
3.2.6. Rendering Code - 27
3.2.6.1. Textures Used - 27
3.2.6.2. Models Used - 28
3.2.7. Graph Code - 29
3.3. Post Demo Session - 30
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
iv
4. Evaluation - 31
4.1. Evaluation against the Minimum Requirements - 31
4.2. Evaluation against the Possible Extensions - 34
4.3. Comparison with Existing Solutions - 35
4.4. Changes in the Schedule - 37
4.5. Conclusion - 38
5. References - 39
6. Appendices - 41
6.1. Appendix A - Reflection - 41
6.2. Appendix B - Borrowed Code - 41
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
1
1 - Introduction
Pathfinding is essentially finding a path between two locations, in a given subspace. It is essentially
an Artificial Intelligence (AI) problem, since the problem is easy for a human to understand and solve,
but much more difficult for a logical machine to determine.
1.1 - Aim of the Project
The aim of this project is to design, implement and analyse the efficiency of a path-finding algorithm
in an entity populated 3D virtual environment.
1.2 - Requirements of the Project
There are 5 minimum requirements for the project. These are:
• To assess the current state of pathfinding technology in programs, researching into the history and
various uses of pathfinding.
• To design a 3D graphical entity populated environment system, complete with a pathfinding algorithm
which the entities use to navigate the environment. The user will be able to view the entities and the
environment in real time.
• To implement and produce the 3D virtual environment system, using the research and design of the
system in previous stages.
• To run a series of tests on the system and analyse the pathfinding algorithm compared to previous
iterations of the algorithm, using those test results to attempt to improve upon the algorithm for this
problem space.
• To evaluate on the effectiveness of the pathfinding algorithm, and the comparison between these agents
and how a real-life agent may move in the same circumstance.
The project involves producing a 3D graphical environment, which has obstacles and agents who
find paths around the environment. As well as these minimum requirements, there are several
extensions which could be pursued:
• Continue increasing the amount of entities pathfinding simultaneously, and comment on any problems
encountered by this, and possible solutions.
• Let the 3D terrain affect the pathfinding algorithm by placing a cost on travelling up-hill.
• Extend the user’s controls by allowing the user to navigate the world by zooming in/out, rotating, or the
ability to click on entities.
• Improve the graphics engine by creating more detailed landscapes, and other graphical outputs such as
the current status of entities.
• Allow communication between the entities, so they can pass on pathfinding results to one another to
avoid repetitive tasks.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
2
2 - Design & Research
As dictated by the first requirement of the project, research into the current state of pathfinding
technology and general pathfinding theory was conducted.
2.1 - The History of Pathfinding
Pathfinding is like any other Artificial Intelligence problem that has to be solved. Predominately the
problem is “Find the shortest path from A to B”, but other forms of pathfinding issues also exist,
such as “Find any path from A to B” or “Find a path from A to B via C”. All these pathfinding
problems basically equate to the same problem; a Search problem. Graph search problems in
particular date all the way back to 1736, with Leonhard Euler’s Königsburg Bridges, where Euler
proved it was impossible for someone to walk across Königsburg’s 7 bridges without travelling over
the same bridge more than once, and return to the same place that you started.
Another famous historical problem is the Travelling Salesman Problem (TSP), where a salesman
wishes to visit a specified number of cities, one at a time. The salesman cannot visit the same city
twice, and must visit all of the cities using the cheapest solution (i.e. the solution where the
salesman travels the least distance overall). In 1954, George Dantzig et al calculated the solution to
49 cities, and over the years as computational power has increased, so have the number of cities
that have been calculated (24,978 cities by D. Applegate et al in 2004).
Pathfinding is used in many forms in a variety of different programs. In Route Generation programs
such as AutoRoute 2005 (Microsoft, 2004), pathfinding is used to find the shortest path from one
real world location to another on a 2 dimensional map. In Computer Games, pathfinding is
extensively used by A.I. opponents to traverse around virtual obstacles and across virtual worlds to
reach the player, for example Half-Life 2 (Valve Software, 2004). Half-Life 2’s artificial intelligence
for instance uses both nodes placed by the level designer, and short pathfinding for travelling
around dynamic obstacles. In computer networking, algorithms can map a network and send
packets down the shortest path found, by applying costs to each of the routers on the network,
depending on how busy those routers are. These algorithms help to solve the problem of keeping
the network congestion to a minimum.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
3
2.2 - Terms Used in Pathfinding
Pathfinding is usually always thought of as being conducted in a Search Tree (Poole et al, 1998,
p.114). In a search tree, there are several key terms which describe different parts of the search
tree. A Branch refers to a section of the search tree, which is made up of several nodes. Any
particular branch contains a ‘parent’ node (the stem of the branch), and children nodes (the other
nodes attached directly/indirectly to the parent node. A Node is a point where two or more lines
meet it (i.e. a sort of junction). In project terms, a node refers to a single square in the tile based
environment. The Root refers to the highest Node in the tree.
Root Node
Branch
Node
Figure 1 - Example Search Tree
There are several other phrases used when conducting searches. When we speak of the Cost in
pathfinding terms, we refer to the time to get from one node to another. The cost can be anything
from being derived from the distance between the two nodes, to a uniform cost. The term Heuristic
has several different meanings, which have developed over the years that AI has been around.
According to Norvig, R (1995. p.94), Heuristics has meant everything from “the study of methods for
discovering and inventing problem solving techniques”, to “the opposite of algorithmic”. For this
report, the definition of heuristic will mean “a function that provides an estimate of solution cost”.
This means that a heuristic algorithm must be able to work out an estimation of the solution in
relation to the start, as a limiter to the search algorithm.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
4
2.3 - Existing Pathfinding Solutions
There are many pathfinding algorithm programs available on the internet. The majority of those
available are developed using JavaScript, and can be run directly from the websites. Figure 2
(Pulkkinen, A. 2004) and figure 3 (Doe, J H. 2004) shows examples of these programs. They both
show a clear visual representation of what the final path is for the entity, by colouring the tiles which
the entity would travel along to reach the destination.
Figure 2 (Left) - A JavaScript program showing an A* algorithm in action
Figure 3 (Right) - A different A* JavaScript program in action
However, the level of quality of these programs varies between websites. The majority of them,
although showing the final path, do not show the steps in how to do so (such as the tiles which have
been checked by the algorithm). Virtually all of the pathfinding algorithms also only deal with one
entity, while this project focuses primarily on the problem of multiple entities pathfinding in the same
problem space at the same time. The speed at which these programs find a path also varies, with
some being taking up to 10 seconds, while others complete the problem in only 2 seconds.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
5
2.4 - Representing the Problem in a Virtual Environment
There are several steps to achieve pathfinding in a virtual environment. The virtual environment
must first be partitioned, where each section of the environment corresponds to a node which the
pathfinding algorithm can use to navigate. This, as suggested by Poole et al (1998, p.114); “forms
an appropriate level of abstraction”, which makes it easier for pathfinding to take place, since a tree
structure is simpler to navigate than an open area. Heuristics will secondly determine how each
node is rated in importance to the solution (e.g. a node far away from the start and goal will receive
a very low rating). Finally, one must choose the most effective search algorithm for the job at hand.
Partitioning the virtual environment is vital for being able to achieve pathfinding, and can be done in
several different ways. It can be partitioned as a Grid (or Tile); a uniform splitting process down to
the lowest level where the smallest obstacle takes up one tile. The degrees of freedom that the
entities can enjoy must also be decided, either the 4-way adjacency, where the entity can only
move forward, backwards, left or right, or alternatively an entity would be allowed to travel in any of
the 8 directions (diagonally or straight movements), which would cut down on the distance the entity
would have to travel. The figure below shows an example of a grid based world, containing an
obstacle.
Obstacle
Figure 4 - Tile Based world with graph overlay
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
6
Another partitioning type includes Polygon partitioning, where each surface polygon is a node. This
proves easier to create more realistic looking virtual obstacles, since there is not an ordered tile
structure (obstacles can be of any geometrical shape rather than a square). However, polygon
partition requires the cost of each link to be calculated, which is a costly process if there are a large
number of links (in grid partitioning each cost is uniform). It can also leads to the problem that if
there is a large polygon, applying only one node to the large polygon area means that detail in the
graph is lost, which makes it harder to path-find to a specific location within the large polygon. The
figure below shows an example of a grid based world, containing an obstacle. Note that the bottom
left node, due to its large size, has lost some detail in the graph overlay, compared to the bottom
right nodes, which are densely packed and so offer a good level of detail.
Obstacle
Figure 5 - Polygon Based world with graph overlay
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
7
2.5 - Improving the Partition
In a small virtual environment, it is okay to split the world into tiles, as there are not many nodes to
search. However, as the search space increases, uniform sized tiles begin to be a limitation. For
example, in a 1024x1024 tiled world, there would be over a million nodes, which would make
searching take a considerable time to complete (1024 x 1024 = 1,048,576). Therefore, something
needs to be done to limit the numbers of nodes. One way of doing this is by the use of Quadtrees,
by merging tiles which have no obstacles or entities together.
Figure 6 - An example of a Quadtree
Quadtree splitting and joining allows a dynamic representation of the map that is also efficient when
it comes to pathfinding. Merging tiles together means that there are fewer tiles for the search
algorithm to search through, which means that the pathfinding runs faster. Unfortunately, there is a
down side to this, when it comes to the precision of the paths which are calculated. As some
squares are larger than others (because they have merged together) this limits where the entities
can move to, resulting in a more jagged path as it attempts to travel to the middle of each square in
turn.
Figure 7 (Left) - Quadtree splitting
Figure 8 (Right) - Accompanying Searchtree
The path of the entity is severely affected by the splitting, as it rates the large node a lot lower than
going around it, because of the attached cost of such a large square.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
8
2.6 – Search Techniques
There are a number of search algorithms that can be adopted for use in pathfinding from A to B.
The major search techniques are discussed in the following few pages.
2.6.1 - Breadth-First Search
Level 0
1
2
Figure 9 - Breadth-First Search
A Breadth-First search (Norvig, R. 1995. p.74) searches all the root nodes of the previous nodes
before deepening the search another level. This way, relatively shallow solutions (i.e. close goals)
can be found quickly. However, deeper solutions take longer to discover than the depth-first
search. They also use a lot of memory, as each level the algorithm progresses, the nodes that are
to be checked increase exponentially. It may also only find a local solution, rather than the optimal
solution, unless an exhaustive search is conducted of the entire search tree. The figure above
shows a breadth-first search in action, where it searches each node on the level before working
on the next level. In the example it is currently working through level 3, and has one more node
left to complete before moving onto level 4.
A way to find the optimal solution is to modify the breadth-first search into a Uniform Cost search.
This expands the lowest cost node before expanding the other ones in the level, totalling up the
cost of the branch. This way, if the algorithm finds a branch that leads to a goal, it knows a limit to
place upon the other branches’ costs, and if the other branches have higher costs and have not
found the goal, that means that the branch with the goal is the optimal solution.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
9
2.6.2 - Depth-First Search
Figure 10 - Depth-First Search
A Depth-First search (Norvig, 1995, p.77) expands nodes towards the deepest levels of the
search tree. This search does well when the solution is located quite far down the search tree.
However, one of the problems with depth-first is that if it makes a mistake and takes the wrong
path early on in the tree, it may take a lot longer to recover and go on the right track. Figure 2
shows an example depth-first search, where it searches down the left most branch nodes first,
before working its way to the right of the search tree.
There are a couple of modifications to counter this, as described by Norvig (1995) as being
‘Depth-Limited’ search, and ‘Iterative deepening search’. Depth-Limited (p.78) does exactly as
the title suggests; it limits how deep that the search algorithm is allowed to search before giving
up on that branch and pursuing another one. This has the advantage of if it sets off on a wrong
branch which could in theory be of infinite deepness, it will be able to search along a different
branch of the tree if it reaches the limit of the search instead of continuing indefinitely. Iterative
Deepening (p.79) searches for the solution in an ever-increasing depth limit, similarly to a
Breadth-First search, but without the large memory usage.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
10
2.6.3 - Best-First search
133 away from the goal
Goal
Figure 11 - Best-First search
A Best-First search (Norvig, 1995, p.92) expands the nodes which appear to be the best choice
(i.e. the closest node to the solution, or the lowest cost solution). An example of a Best-First
search is called a Greedy Search, (p.93) named so because it attempts to take the largest
‘chunk’ out of the remaining distance to the solution by choosing the node which gets the closest
to the solution in the short term (not necessarily the best solution in the entire search space). This
leads to problems where dead-ends are involved, as if a dead-end exists that is closer to the
solution than another node which leads round to the solution, the greedy search will always
choose the shortest path, not knowing it leads to a dead end. Even worse, if the search algorithm
doesn’t remember which nodes it has checked, it would endlessly cycle back and forth between
the dead end and it’s neighbour. The figure above shows an example of a Best-First greedy
search, with the algorithm simply picking the closest node to the goal at each choice.
200
133 167
96 76
0 56
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
11
2.6.4 - A* Algorithm
The A* (A Star) pathfinding algorithm is the combination of a best-first search’s efficiency and the
uniform-cost search’s completeness, as described by Norvig (1995, p.96). It was first presented
by Hart et al in 1968, and it finds the shortest, most complete path in any graph. The input of the
A* Algorithm are the start and end points; as long as it knows where to start and where to finish, it
can work out a path if there is one. The basics of the A* algorithm are that for each node of the
search tree, it calculates that node’s Goal cost (the cost to get from the starting node to this
particular node), the Heuristic (the estimated cost to get from this particular node to the goal) and
the Fitness (the sum of the goal and the heuristic, basically assigning a cost value to this path).
There are two other parts of the A* Algorithm; the Open and Closed lists. The Open list holds all
the nodes which have not yet been expanded by the algorithm (i.e. the possible options left
available to the pathfinder), and the Closed list holds all the nodes which have been expanded
already (some nodes may be part of the path, while others are expanded paths which may have
led to dead ends. The Closed list is used so the algorithm knows where it has searched so far, so
it doesn’t loop between two nodes. To better explain the algorithm, below is the pseudo-code of
the A* algorithm, adapted from Matthew’s code (Rabin, S, 2002, p.106):
Get the Start Node and assign Goal, Heuristic & Fitness values to it
Add the Starting Node to the Open list
Work out the Best Node from the current Open list:
If the Best Node is the Goal Node - Quit (a path has been found)
If the Open List is empty - Quit (no nodes left to search – no path)
For each Neighbour of the current Best Node:
Assign Goal, Heuristic & Fitness values to the current Neighbour
If the current Neighbour is on the Open or Closed lists:
If Path is more efficient - Update the Path
Else - Add the current Neighbour to the Open list
Repeat for each Neighbour
Repeat
The algorithm starts by putting the starting node into the open list. It then takes the starting node,
since it is the best node (there are no other nodes currently), and find’s the best node’s
neighbours. For each neighbour, it works out that particular neighbour’s fitness, goal and heuristic
values, and then adds it to the Open list if it is not already on the Open list (unless it is more
efficient, meaning it has a lower fitness) or on the Closed list (the algorithm has looked at that
node before). It then researches the entire Open list for the next Best node (which may be either a
neighbour of the last Best node or an entirely different node if the current path is no longer viable
(e.g. it hits a dead end)).
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
12
The costs of the nodes and the heuristic determination are very important for the algorithm, and
depend entirely upon how the environment is structured. Should they be inaccurate, the
weightings of the nodes become discrepant, resulting in the algorithm producing inaccurate paths.
There are many different versions of the A* Algorithm, because it is so flexible in applying it to
whatever problem you have (since it can backtrack and search along another path if it gets stuck
along a current path). One hybrid of the algorithm include the IDA* (Iterative Deepening A*), as
described by Norvig, R (1995, p.106). The IDA algorithm can pick up where the A* algorithm fails
in terms of its overuse of memory (with having to remember all the Open and Closed lists until the
end). This iterative deepening cuts memory usage, and so the IDA* performs well in many
circumstances except when the search domain becomes more complex, such as the TSP
(Travelling Salesperson Problem). On the other end of the spectrum, the SMA* (Simplified
Memory Bounded A*) search, also described by Norvig, R (1995, p.107), is designed to use as
much memory as it is allocated (and therefore in theory it can work where the IDA* fails due to
lack of memory). When it runs out of memory, it discards a node, which is known as a ‘forgotten
node’ (node with the highest cost to the goal). This gives the advantage of being able to work in a
variety of situations where memory may be restricted (for other programs & processes for
example).
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
13
2.7 - Graphical APIs
A graphical Application Programming Interface is used to generate the front end of a program in
either 2D or 3D. In this case, the graphical API must be able to support 3D, as the project aims to
construct a 3D Virtual Environment. Below are two options which have been considered as suitable
APIs, as discussed by Roy, P. (2002).
• OpenGL was developed by Silicon Graphics in 1992, and is described by OpenGL (2004) as
‘the premier environment for developing portable, interactive 2D and 3D graphics applications’.
Advantages include it’s portability to both UNIX and Windows operating systems, as well as
being a recognised industry standard. It is also a popular choice, meaning that there are many
books and tutorials available for programming in OpenGL.
• Direct3D was developed by Microsoft as a move to get developers to produce programs for
Windows rather than simply DOS. Several iterations of Direct3D came out before industry
accepted the API, and today a majority of computer games are built using Direct3D, due to its
advanced rendering techniques.
For the project I decided on using OpenGL. The reasoning behind this is that the project must be
portable since it will be developed on a windows machine at home, and brought into University for
the demo session. Being a popular choice for academics for 3D rendering means that the many
tutorials available will ease the implementation so in theory not too many problems should arise that
cannot be researched and dealt with. Direct3D has some advanced rendering techniques that are
faster and more superior to OpenGL’s, but this project does not have a need for a fancy graphical
display, just a functional useable one since this project focuses on AI pathfinding.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
14
2.8 - Programming Languages
Deciding on which programming language to use depends upon what the requirements of the
project. For example, Java (which runs in a virtual machine to ensure compatibility with a variety of
operating systems), because of the fact it runs in a virtual machine and has to be decoded as such
to work on the current machine, runs slower than compiled C++ code. So in this case it is a choice
between interoperability, or faster runtime code.
Since this project will be using OpenGL as the graphical API, C++ immediately springs to mind, due
to the lasting connection between the two languages through the years, and the large number of
OpenGL tutorials available which are coded in C++. The programming language C# was considered,
but after initial research it was discovered that only unofficial support of OpenGL is found in C#.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
15
2.9 - Design Methodology
The project will be designed and implemented by using the Iterative Waterfall Cycle (Bennet et al,
1999), which means that the project will employ a feedback at each stage of the system (see
diagram below). This ensures that the project is constantly evolving to meet problems which arise
while analysis, design, implementation and testing take place.
Development
Feedback
Figure 12 - The Iterative Waterfall cycle
As part of this iterative development cycle, Prototypes with specific objectives will be written to
identify potential problems with parts of the program. Failure to specify the objectives of the
prototype results in “an ill-focused and unstructured activity producing poorly designed software”
(Bennet et al, 1999). As the prototype develops and improves through feedback, the end result is a
clear idea for the final project implementation. There are of course disadvantages to prototyping,
one being the time it takes to produce a prototype. It can be argued however that the time taken
prototyping saves time re-implementing sections of the final program due to an error which would
have been picked up by a prototype earlier in development.
Analysis
Design
Implementation
Testing
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
16
2.10 - Project Schedule
The schedule has been designed to take into account the holiday periods and the exam period after
Christmas. The figure below shows the schedule, slightly altered from the Mid-Term report schedule.
2004 2005
November December January February March April
01 08 15 22 29 06 13 20 27 03 10 17 24 31 07 14 21 28 07 14 21 28 04 11 18 25
Research
Design
Implementation
Testing
Writeup
Figure 13 - Mid-Term Schedule of the Project
Research will be conducted during the month of November to ensure that information about
pathfinding is obtained, so design and implementation of the prototype can take place. After the
exams in January, design and implementation of the prototype will take place, before completing
the final year report.
Prototype
Mid-Term Report
Exams
Final Report
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
17
3 - Implementation
As the aim of the project is to produce a 3D virtual environment with pathfinding, a program was
needed to succeed this aim.
3.1 - Prototype
The aim of the prototype was to identify any potential pitfalls which could plague the final
implementation. It also allowed mock screenshots to be built to give an idea of what the final
implementation would look like. It was conducted in two stages.
3.1.1 - Stage 1 (Graphics)
The aim of this prototype stage was to produce the 3D environment in which the entities operated.
The environment could be rotated around the middle point. The image on the right shows the
completed graphics stage. The entities and obstacles were loaded from text files, to allow a
greater degree of freedom to take place without having to re-compile the code each time an
obstacle was moved.
Figure 14 - First screenshot of the 3D virtual environment
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
18
3.1.2 - Stage 2 (Pathfinding Algorithm)
This stage aimed to implement a pathfinding algorithm. The simplest pathfinding algorithm, the
Depth-First algorithm, was used to calculate a path between an entity, and the entities’ goal. The
pathfinding algorithm itself was very crude and slow, and on areas larger than 16x16 squares
would simply take too long to complete. It did however give a good idea of how the final
implementation would operate. Figure 15 shows the pathfinding algorithm successfully finding a
path for the Red Entity from its starting location to a node which was designated the goal (the
bottom node on figure 15).
Figure 15 (Left) - Depth-First search in action
Figure 16 (Right) - A close-up of the red agent at the start of his path
3.1.3 - Stage 3 (Scale of the Environment)
The final stage explored the size of the environment which could be created, more specifically
determining the maximum size that was realistically possible. A virtual environment the size of
4096x4096 squares was rendered, but this was only when the environment was sparse with
obstacles. It was concluded that a smaller number would be far more realistic.
Figure 17 - Scale that the environment engine could render (4096x4096 squares), and a close-up of a section to show the
size of the environment.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
19
3.2 - Final Project
The final project was produced via the use of an iterative waterfall cycle. Various parts of the final
project, as shown in the diagram below (Figure 18) are discussed in more detail over the next few
pages.
Figure 18 - UML Activity Diagram of the program running
Main Main Program Loop
Graph Draws graph showing results of pathfinding
Render Handles OpenGL
drawing calls
Pathfinder Holds pathfinding
algorithm
Input Deals with input from keyboard & mouse
Quadtree Holds Quadtree and
Searchtree algorithms
Loader Loads entity details
from a text file
Libraries Holds libraries used by
the program
Classes Holds classes used by
the program
Entity text file
OpenGL API
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
20
3.2.1 - Version history
The final project was implemented iteratively. During the implementation, for backup reasons if
new features were added to the latest version I would move onto the next version number.
Various parts of the final project are discussed in more detail over the next few pages. Below
shows the different versions of the Final Project:
v0.1 This version loaded the entities and obstacles from text files.
v0.2 The Quadtree and Searchtree was implemented.
v0.5 The Breadth-First search algorithm was implemented. Unfortunately it
is slow and inefficient, but it finds a path in a small environment.
v0.6 The Breadth-First search algorithm was improved, but it is still
inefficient.
v0.7 The A* algorithm was implemented, and implemented code which allowed
the entities to follow their paths in real time.
v0.8 The textures were vastly improved (they were brightened and
sharpened).e
The 'Large Rock' Obstacle was added to the program.
Shadows were added to all the objects in the environment, for added
effect.
v0.81 After discovering a bug in the A* algorithm, the A* algorithm was
fixed.
v0.82 A bug in the Quadtree not redisplaying properly was fixed.
v0.83 Another bug in the A* algorithm was fixed.
A graphical representation of the entities’ goal (a 2D diamond) was
added so the user can understand what is going on better.
v0.84 A third problem discovered in the pathfinding was fixed.
The user can pick up and move any obstacle, and the Quadtree and
Searchtree automatically redisplay themselves.
v0.85 The graphical representation of the entities’ goal was improved (3D
short cylinder).
The user can pick up and move the entities as well as any obstacle.
The Obstacles are now randomly generated (they were loaded from text
file before).
v0.86 Implemented a simple graph which outputs the results of the
pathfinding.
v0.90 Pre-Demo version. Code comments were overhauled. Readme written.
Graph graphics were improved
Breadth-First algorithm was removed (as it was too inefficient to cope
with the environment).
v1.0 Post-Demo version. Display List implemented.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
21
3.2.2 - Input Code
Originally, input was purely using the keyboard, since only the viewpoint could be rotated and
zoomed. However, as the project developed, mouse selection was needed to be able to adapt the
environment in real time (move the agents and obstacles around). This was going to be done by
the use of a right-click menu, which would allow the user to add or remove objects, as well as left-
clicking the mouse and holding the button to move the selected object around the environment.
However, the code proved inflexible and I was unable to successfully pass information from the
right-click menu to the selected object in order to move it, so the menu was taken out and
replaced with a command-based interfaced which allowed the addition of objects. The project also
allows graphical options to be toggled on or off, including the Quadtree, Searchtree, and
calculated paths. Below shows the keyboard controls for the inputs, taken from the readme.
Movement:
W - Move forward
S - Move backwards
A - Strafe Left
D - Strafe Right
T - Raise Camera view
G - Lower Camera view
Q - Rotate Scene Left
E - Rotate Scene Right
Graphical Options:
J - Toggle pathfinding results graph.
I - Toggle Quadtree
O - Toggle Search Tree
P - Toggle display Path
M - Move entities
H - Add an obstacle (console)
Del - delete an object (while one is selected)
Esc - Quit
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
22
3.2.3 - Quadtree Implementation
The Quadtree is used to calculate the Search Tree graph easier, by splitting the environment into
Areas. Originally, an external code was going to be used, so more focus could be placed on the
pathfinding side of the project, but after having difficulties in obtaining the Open Source code, the
Quadtree code was written by me. Below is the pseudo-code for the Quadtree code that was
implemented:
Erase previous Quadtree
Create 2D vector of lowest level, adding Obstacles and Entities to it
While not finished
Set as finished
For each Area
If Area contains Entities or Obstacles and is not at lowest level
Set finished to false (in case further iterations needed)
Split Area (by building 4 more Areas and discarding the old Area)
Repeat for each area
Repeat
The Quadtree code starts by adding all the obstacles and entities to a 2D matrix, which is
essentially the lowest level of detail. It then creates an area which encompasses the entire area.
With this matrix, it enters a recursive check to see if there is an obstacle or entity inside the
environment (which there will be on the first iteration). If it finds an obstacle or entity, it splits the
area into 4 areas and deletes the original area (the larger one). It then checks each of those 4
areas for obstacles or entities. It carries on until it reaches the lowest level (1x1 squares), where
only one entity or obstacle can be contained in that area. The areas are stored in a dynamic
vector, which is handy for adding the new areas. The Quadtree is represented by the Area Class.
Below is the code for the Area class code:
Figure 19 (Left) - Area class code
Figure 20 (Right) - Dimensions of the Area
class Area
{
public:
Area()
bool obstacle;
float x1,y1,x2,y2;
};
y
x
x1, y1
x2, y2
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
23
The Area class code, the Area() is the constructor which builds the empty Area to begin with.
The obstacle boolean stores if the area contains an obstacle (which is decided at the start of
the program, and each time the user moves an object around the environment). Finally the
x1,y1,x2 and y2 floating point numbers refer to the real locations of the bottom left and top right
co-ordinates of this particular area. All of the Area objects are stored in a standard vector called
Quadtree, and their unique id is their position within this vector.
The Quadtree runs every time an obstacle or entity is moved, because if any objects move in the
scene, the Search Tree graph needs to be recalculated to take that into account, and thus the
Quadtree needs to be recalculated for the Search Tree. The Quadtree code is very fast due to the
simplicity of the code. It uses what is known as the Top Down, or Divide & Conquer approach.
The image below shows the Quadtree splitting in the project. Note that squares which contain an
object (tree, rock) have been broken down to their lowest level, while sparse areas (the left most
area) haven’
Figure 21 - Environment with Quadtree Splitting
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
24
3.2.4 - Searchtree Implementation
The Search Tree is used by the pathfinding algorithm to calculate a path through the virtual
environment. It uses the Quadtree to calculate which areas are neighbours of which other areas.
Below is the pseudo-code for the Search Tree calculation. Note the complexity of the algorithm,
nested in several for loops:
For each area
For each neighbour of the current area
For the length of the current area
For each other area
If a neighbour of the neighbour is found, build a link
For the width of the current area
For each other area
If a neighbour of the neighbour is found, build a link
Repeat
Repeat
For each area that the search tree searches in, it finds the neighbour of the current area by
running checks along the edges of the area to see if there are any other areas which have the
same borders. The diagram below explains the algorithm:
Figure 22 – Diagram showing the borders checked to see if the area that we are checking (number 4 in this case) borders with any other area. In this particular example, the area 4 actually borders with all the other areas.
Area we are currently
checking
3 2
4 5
1
6 7
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
25
If the Searchtree finds a link between two particular areas, it builds a Link object, and stores it in
a standard vector called SearchTree. The figure below shows the code for the Link class. In the
code, node1 and node2 integers refer to the two Area’s position within their vector (i.e. their
unique ID). The cost integer refers to how much it costs to travel between these two particular
nodes, which is determined by the Search Tree calculations.
Figure 23 (Left) - Link class code
Figure 24 (Right) - Graphical representation of one link between Node1 and Node2, with a cost of ‘2’
Below is a screenshot of the Search Tree rendering in real time. The circles are the nodes (each
Area is a node), and the lines connecting the circles are the links.
Figure 25 - The Searchtree uses the Quadtree’s areas to calculate itself
class Link
{
public:
Link()
int node1, node2;
int cost;
};
1
2
2
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
26
3.2.5 - Pathfinding Code
The pathfinding code holds the entire A* algorithm implementation. The algorithm itself stores the
parts of the path as a vector of AStarNodes. The id integer refers to the unique id of the area
which this node represents, while the parented integer holds the id of the node’s parent node
(the node before itself). This allows code to piece together the path after the algorithm finishes
choosing the nodes which the path occupies. Finally, the f, g and h integers refer to the node’s
unique fitness, goal and heuristic values, that are needed by the A* algorithm. The figure below
(Left) shows the AStarNode class. The cost of a particular node’s heuristic is calculated by
Pythagoras theory (Right).
Figure 26 (Left) - The AStarNode Class
Figure 27 (Right) - Calculating the estimated heuristic between the current node and the goal
The main problems in implementing the pathfinding code originated from bugs when calculating
the Heuristic, Fitness and Goal values. The figure below on the left (Figure 28) shows the
pathfinding algorithm incorrectly assigning these values to the node circled in red, thus making
the pathfinding algorithm believe that the other node was a better choice, even though the first is
closer to the goal.
Figure 28 (Left) - Pathfinding with an incorrect heuristic, resulting in an inefficient path
Figure 29 (Right) - Incorrect sorting of the nodes after pathfinding them, resulting in a strange path
class AStarNode
{
public:
AStarNode()
int id;
int parentid;
int f,g,h;
};
Current Node
Goal Node
Heuristic
X
Y
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
27
3.2.6 – Rendering Code
The rendering code holds the graphics and displays the loaded textures on the models.
3.2.6.1 - Textures Used
Most of the textures were originally photos, with the exception of the Grass and the Entity
textures. All the textures where edited using Paint Shop Pro (Jasc Software). All the textures
are 256x256 pixels in measurement, kept small to ensure that loading times are minimal. All the
images are in bitmap (BMP) format. There are two types of Grass texture (with and without
borders), so that the user can either have Quadtrees on (where the borders are shown), or off
(where there are no borders and just a repeating grass texture).
Tree Trunk Tree Leaves Grass (With No Border)
Grass (With Black Border) Rock Entity (Base Texture)
Figure 30 - Textures used in the 3D virtual environment
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
28
3.2.6.2 - Models Used
All of the models are hard-coded into the program, and are called by their relevant function
names (e.g. DrawEntity(), etc ). They call three OpenGL primitives (gluSphere(),
gluCylinder() & gluDisk()) to draw themselves. The shadows are simple dark
gluDisk()’s with a grass texture applied to them. The cylinders were kept to 8 sided to
improve rendering speeds at larger environments, rather than a smoother amount of sides (e.g.
32 sided). The rocks are deliberately low sided cylinders to give them a jagged look, like rocks
should have (rather than smooth). A lot of time was spent on making the obstacles and entities
more aesthetically pleasing.
Small Rock Obstacle (2x2) Large Rock Obstacle (4x4) Tree Obstacle (1x1)
Figure 31 – Obstacles created for the 3D graphical environment
The entities are coloured according to their RGB value, specified in the file Entities.txt. This
allows a greater degree of flexibility, as virtually any colour can be chosen. The text file also
allows the entities to be placed at specific positions in the environment at the start (although
they can be moved around the environment by mouse when the program is running).
Agent (Yellow) Agent’s Goal (Yellow)
Figure 32 – Entities created for the 3D graphical environment
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
29
3.2.7 – Graph Code
The graph class was only started near the end of the project. Certain pieces of data are collected
when pathfinding is completed, and stored in a Results vector, which is called by the graph code,
which outputs the graph onscreen. The diagram below shows the class that stored the results.
The algorithm integer held which type of algorithm was used (to allow more algorithms to be
used in the future). The integer length held how long the path that was calculated was, in nodes,
and the floating point number timetaken stored how long it took to calculate the path.
Figure 33 - The Results Class
When the user presses the graph key, the graph code collects the results from the pathfinding
algorithm, sorts it into order, and then shows the graph screen, which shows a simple graph of
how the time taken to calculate the Searchtree increases as the number of nodes increases.
Figure 29 shows the graph code running.
Figure 34 - Results of the pathfinding algorithm outputted by the Graph code.
X-Axis shows the length of the paths vs. the Y-Axis time taken.
The dots on the graph represent the individual results.
class Result
{
public:
Result()
int algorithm;
int length;
float timetaken;
};
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
30
3.3 - Post Demo Session
During the demo session, my assessor was shown the features of the project. It was noted that in
largely populated areas, the Frames per Second (FPS) would reduce considerably, resulting in
jerky movement when the camera was moved around the scene or the agents moved about their
environment.
The FPS problem was solved by the use of Display Lists. According to the OpenGL Red Book
(Davis, T et al, 1994), a Display List is “…a group of OpenGL commands that have been stored for
later execution” (Chapter 4). This means that objects can be pre-processed before the program
enters the refresh loop, so that when the objects are called it takes a fraction of the time to render
as it has already been processed. In this project, the obstacles, entities, and the Search Tree were
placed in a Display List, due to the potential problems that these on a large/complex scale would
result in. The average rendering speed was doubled by implementing Display Lists of the objects in
the scene (see figures 30 and 31 below). This particular scenario was benchmarked on a size
128x128 environment with 1000 randomly populated objects and 8 entities. The FPS counter was
an external program called Fraps (www.fraps.com).
Figure 35 (Left) - The Demo version, with an FPS of 17 Figure 36 (Right) - Afterwards with the implemented display list, and an FPS of 36
As well as the slowdown in larger environments, the assessor also noted that on occasion the
pathfinding would perform incorrectly (i.e. it would not find the shortest path). This was due to an
error in the heuristics calculation of the pathfinding.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
31
4 - Evaluation
The best way to evaluate a project is to compare it with the minimum requirements of the project, to
ascertain if they have been met. In addition to this, As well as this, the possible enhancements of the
project can be evaluated against to see where the project surpassed the minimum requirements.
4.1 – Evaluation against the Minimum Requirements
• To assess the current state of pathfinding technology in programs, researching into the
history and various uses of pathfinding.
The Design and Research section of this report outlines the research conducted into the history
and uses of pathfinding. Additionally, the Existing Pathfinding Programs shows some uses of
pathfinding in academic terms, detailing how the pathfinding is conducted.
• To design a 3D graphical entity populated environment system, complete with a
pathfinding algorithm which the entities use to navigate the environment. The user will be
able to view the entities and the environment in real time.
The 3D virtual environment was first designed using a prototype to ensure it was viable. After the
prototype reached its full potential, the final program was designed, and implemented.
• To implement and produce the 3D virtual environment system, using the research and
design of the system in previous stages.
The final program was written using the 3D graphical API OpenGL. Entities occupy the
environment, ranging from static entities (obstacles) to dynamic entities (agents). The pathfinding
algorithm used was the A* algorithm. The environment was viewable in real time, and the agents
could move in real time. Diagrams throughout this report show the 3D virtual environment system
running. The screenshot below shows an agent moving along their path.
Figure 37 - Yellow agent moving along its path to its goal in the distance
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
32
• To run a series of tests on the system and analyse the pathfinding algorithm compared to
previous iterations of the algorithm, using those test results to attempt to improve upon
the algorithm for this problem space.
During the development cycle, various types of pathfinding algorithm were used. In the prototype,
the Best-First algorithm was used as pathfinding. This was an inefficient pathfinding algorithm, as
it was neither the most optimal, nor is complete. In the final implementation, the A* algorithm was
implemented. This is far more complete, and more importantly optimal. During the final project
implementation, the A* algorithm was improved several times, by improving the Heuristic for the
algorithm.
• To evaluate on the effectiveness of the pathfinding algorithm, and the comparison between
these agents and how a real-life agent may move in the same circumstance.
Agents in this simplified virtual world have a few similarities with people finding paths. A person
who has an overall view of a maze could navigate it as easily as the A* algorithm can find a path,
and often decide in advance what route to take through a particular set of obstacles. However,
there are also several differences between virtual agents and real life people pathfinding. The
agents in this project can decide on a route faster than real life counterparts, especially in large
scale environments. As well as this, due to the splitting of the virtual environment, the path has to
be generalised in several places, which results in unsmooth paths, while a real life agent will take
into account their current location, and avoid other agents by sub-consciously calculating where
they will be, and changing their direction so they do not bump into them. The effectiveness of the
pathfinding algorithm is discussed in the testing section (4.3). On the next page is a screenshot of
an agent who has discovered a path through the maze. Note that the path contains many corners
and straight lines, while a real-life agent would walk around these obstacles in a more curved
movement.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
33
Figure 38 - Complex paths can be determined in a matter of milliseconds. Here, a
Yellow agent successfully finds a path through a set up maze
Generally the longer the path, the longer it takes to calculate the path. This is supported by Figure
29 in the Graph Code section (3.2.7), which shows a rough increase of time as the number of
nodes in the path increase.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
34
4.2 – Evaluation against the Possible Extensions
Although the minimum requirements were all fully realised, some of these possible extensions were
not, and thus could be used as possible improvements to the project.
• Continue increasing the amount of entities pathfinding simultaneously, and comment on
any problems encountered by this, and possible solutions.
When the amount of entities is increased, it has detrimental effects on the program. As well as the
slowdown in graphically rendering more entities, the pathfinding calculation time becomes more of
an issue as more and more entities call the pathfinding code. To combat this problem, entities
could remember their pathfinding results, so that if another entity wanted to travel along the same
path, the entity could be given the pathfinding result, which would mean that the path wouldn’t
have to be recalculated again, saving computational time.
• Let the 3D terrain affect the pathfinding algorithm by placing a cost on travelling up-hill.
Unfortunately this possible extension was placed lower on the list of things to do, and there was
no time to implement this.
• Extend the user’s controls by allowing the user to navigate the world by zooming in/out,
rotating, or the ability to click on entities.
A simple set of input keys were assigned to allowing the user to navigate the world by rotating the
environment about it’s central point, as well as raising or lowering the environment (effectively
zooming in and out). The user can click on entities to move them around to different locations.
• Improve the graphics engine by creating more detailed landscapes, and other graphical
outputs such as the current status of entities.
The final implementation shows several graphical improvements over the prototype. The textures
and models were improved to give additional eye-candy to the user. Graphical output of entity
status was not implemented.
• Allow communication between the entities, so they can pass on pathfinding results to one
another to avoid repetitive tasks.
This was not implemented, but would be an interesting topic to pursue had more time been
available.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
35
4.3 - Comparison with Existing Solutions
Testing of the pathfinding algorithm was conducted to determine the computational speed of the
algorithm. The tests were conducted along-side existing solutions as a comparison. Unfortunately,
Pulkkinen’s A* solution (Pulkkinen, 2004) was unable to allow the construction of user-designed
worlds, so had to be removed from the testing process. Pulkkinen’s solution did however offer a fast
pathfinding time of under a second in its environment, which is about 100x50 squares large. This is
about the same time to compute as this project’s pathfinding algorithm in a 128x128 square
environment. Doe’s Astar algorithm doesn’t support multiple agents pathfinding, so a test with
multiple agents had to be left out, as no comparison could be found.
Test 1
This test determines how long it takes for a straight line to be calculated in a small empty environment (16x16)
3D Pathfinding Engine
Time taken – 0 seconds
Doe’s Astar Pathfinding Engine
Time taken – 4.72 seconds
Test 2
This test determines how long it takes for a more complex maze to be calculated in a small environment (16x16)
3D Pathfinding Engine
Time taken – 0.016 seconds
Doe’s Astar Pathfinding Engine
Time taken – 10.82 seconds
The tests show that the A* algorithm produced for this project is immensely fast, able to calculate
paths in a very short amount of time. On test 1, the project A* algorithm scored a time of 0 seconds.
This was due to the limitations in the time.h header, which unfortunately doesn’t record timers
which are less than approximately 0.015 seconds. However, it completed faster than the stopwatch
could be started and stopped, so it was probably around the 0.01 second mark. Doe’s Astar
algorithm scores 4.72 seconds, which was recorded using a stopwatch as no timer is present in his
program. Test 2 shows that the project A* algorithm can deal with more complex situations in a
lightning-fast speed, while Doe’s Astar algorithm takes 10 seconds to calculate the same path.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
36
Things to note are that the project algorithm is searching in a smaller graph than Doe’s Astar
Pathfinding algorithm, due to the project’s Quadtree calculations, which is one reason for the fast
calculation of the path. Although purely speculation, a reason why Doe’s pathfinding takes so long
is possibly more to do with the Java code than the algorithm itself, as Doe’s algorithm is embedded
on a webpage. However at the end of the day, this project does combine the speed of Pulkkinen’s
algorithm with the versatility of Doe’s pathfinding system in allowing custom mazes to be created.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
37
4.4 - Changes in the Schedule
Overall, the schedule remained fairly similar to the schedule which was reported on the Mid-term
report. The exception was that the schedule had failed to take into account the ongoing testing
needed for the iterative waterfall cycle. The prototype took far longer to implement that originally
thought, as did the final project, but the prototype did help the final year project to be implemented
at a faster pace, which was its saving grace.
2004 2005
November December January February March April
01 08 15 22 29 06 13 20 27 03 10 17 24 31 07 14 21 28 07 14 21 28 04 11 18 25
Research
Design
Implementation
Testing
Writeup
2004 2005
November December January February March April
01 08 15 22 29 06 13 20 27 03 10 17 24 31 07 14 21 28 07 14 21 28 04 11 18 25
Research
Design
Implementation
Testing
Writeup
Figure 39 (Top) - Mid-Term Schedule of the Project Figure 40 (Bottom) - Actual Schedule of the Project
Implementation was the primary cause for slowdown in the project schedule. This was due to the
unexpected additions to the program that were required, an example being having to learn and
implement standard vectors for holding the Searchtree, as the C++ array cannot handle 2000+
elements in a single array. Additional problems were discovered such as the many bugs in the A*
algorithm which only showed on run-time, requiring time to locate and fix each bug. This was why
testing and implementation ran alongside one another for the duration. The slowdown of
implementation also led to a delay in writing the Final Report.
Prototype
Mid-Term Report
Exams
Final Report
Prototype
Mid-Term Report
Exams
Final Report
Final Project
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
38
4.5 - Conclusion
Since all of the project’s minimum requirements have been met, it can certainly be said that the
project has been a success. A 3D virtual environment has been created that allows the placement
of obstacles and agents. The agents themselves can also freely conduct pathfinding around the
environment, avoiding obstacles and reaching their goal. All the objects in the environment can be
moved by the user by clicking and dragging.
However, not all of the extensions have been implemented, which means that there is possible
future work for this project. Being able to click on agents to review their status was something that
could have been used to allow the user to have a greater understanding of pathfinding, by seeing
what they are ‘thinking’ at any moment in time. The user control system, although stable enough to
offer the user a degree of freedom, does not offer the full degrees of freedom that a camera that
was controlled by mouse movement could offer. The 3D virtual environment could have been more
impressive with realistic 3D terrain instead of essentially a 2 dimensional world in a 3D virtual space.
If more time was available, the graph could have been implemented more efficiently.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
39
6 - References
• Bennet, S. McRobb, S. & Farmer, R. (1999) Object Oriented System Analysis and Design using
UML. McGraw-Hill Publishing
• Davis, T. Neider, J. & Woo, M. (1994) The Official Guide to Learning OpenGL, Release 1 (a.k.a.
‘The Red Book’). Addison-Wesley Publishing Company
• Doe, J H. (2004) A* Pathfinding Algorithm [Online]. [Accessed 8th Dec 2004]. Available from
World Wide Web: <http://www.premise.org/main/astar/>
• Manley, K. (2003) Pathfinding: From A* To LPA. [Online]. [Accessed 24th Nov 2004]. Available
from World Wide Web:
<http://csci.mrs.umn.edu/UMMCSciWiki/pub/CSci3903s03/KellysPaper/seminar.pdf>
• Norvig, R. (1995) Artificial Intelligence - A Modern Approach. London: Prentice-Hall
International (UK). p. 92-117.
• OpenGL (2004) [Online] [Accessed 20th April 2005] Available from World Wide Web:
<www.opengl.org>
• Patel, A J. (2004) Amit’s Thoughts on Path-Finding and A-Star [Online]. [Accessed 24th Nov
2004]. Available from World Wide Web:
<http://theory.stanford.edu/~amitp/GameProgramming/index.html>
• Poole, D. Mackworth, A. Goebel, R. (1998) Computational Intelligence - a logical approach.
New York: Oxford University Press, Inc.
• Pulkkinen, A. (2004) Pathfinding Using A* Algorithm [Online]. [Accessed 8th Dec 2004].
Available from World Wide Web: <http://www.cs.helsinki.fi/u/apipulkk/astar>
• Rabin, S. (2002) AI Game Programming Wisdom. Massachusetts: Charles River Media, Inc. p.
105-152.
• Reese, B. Stout, B. (1999) Finding a Pathfinder. [Online]. [Accessed 22th Nov 2004], p. 69-71.
Available from World Wide Web: <http://home1.stofanet.dk/breese/aaai99.pdf>
• Rich, E. Knight, K. (1991) Artificial Intelligence. New York: McGraw-Hill, Inc. p. 63-98.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
40
• Roy, P. (2002) Direct3D vs. OpenGL: Which API to Use When, Where, and Why [Online]
[Accessed 25th Nov 2004] Available from World Wide Web:
<http://www.gamedev.net/reference/articles/article1775.asp>
• TSP Bibliography (2004) [Online]. [Accessed 30th Nov 2004]. Available from World Wide Web:
<http://www.tsp.gatech.edu/milestone.html>
• Valve Software. (2004) Half-Life 2 [Online] [Accessed 06th Dec 2004] Available from World
Wide Web: <http://www.steampowered.com>
• Wright, R S Jr. Lipchak, B. OpenGL Super Bible 3rd Edition. Indiana: Sams Publishing.
Pathfinding in an entity cluttered 3D virtual environment Matt Hall
41
7 - Appendices
7.1 - Appendix A - Reflection
I originally chose to do a project on AI pathfinding because I had no prior experience in
implementing a pathfinding algorithm, and wished to learn to better prepare myself for future work. I
was initially discouraged when I started to run into problems while trying to implement one of the
most basic of pathfinding algorithms (the Depth-First algorithm) for my prototype. AI pathfinding
algorithms are strange in that they are easy to follow and understand, but much harder to actually
implement unless you are fluent in the programming language. However, through sheer
determination I finally implemented the basic algorithm, followed by the A* algorithm and everything
fell into place. This is one of the most difficult projects I’ve had to do to date, but the rewards have
far outweighed the problems as I have learnt so much.
On hindsight I would have preferred to implement a more detailed 3D graphical engine, with the
height of the terrain affecting the path (i.e. going uphill is more of a cost), rather than being tied up
with the improvement of the search graph by applying Quadtree splitting to it. That in itself was a
very worthwhile part of the project as again I had no prior experience on how to actually code half
the things that have been coded for this project. Overall I am extremely pleased with myself for what
I have written in the time-scale allowed, and what I have learnt, particularly the coding.
The main advice that I would offer to students about to start their final year project is to organise
and plan, allowing plenty of time to deal with unexpected situations (especially while programming).
It sounds obvious, but to get a clear idea of what you wish to do with your project is paramount to a
successful project. Most importantly is to not get into the habit of putting off working on your project
– the more work you do now, the less you have to do when the report is due in less than 24 hours
time! When there is a gap in the coursework, do a little of the final year project because trust me, it
will help in the end.
7.2 – Appendix B - Borrowed Code
The texture loading code was borrowed and heavily adapted from Nehe’s OpenGL tutorials, which
can be found online at: <http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06> [26th April
2005]. It was borrowed because the focus of this project was not primarily on
the background workings of the system, such as texture loading. Additionally,
it would have been a waste to spend time implementing texture loading
when an ideal solution is freely available.