<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.xoreos.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Supermanu</id>
	<title>xoreos Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.xoreos.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Supermanu"/>
	<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Special:Contributions/Supermanu"/>
	<updated>2026-04-30T09:38:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.6</generator>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=344</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=344"/>
		<updated>2017-05-03T09:22:23Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* External libraries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== General considerations ==&lt;br /&gt;
=== 3D vectors ===&lt;br /&gt;
Both algorithms extensively use 3D vectors and related operations. Should we use &amp;lt;code&amp;gt;Common::Vector3&amp;lt;/code&amp;gt; generally or only when it is really needed and uses arrays for all the other cases?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A* algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;&#039;POC&#039;&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;&#039;SSFA&#039;&#039; is relatively straightforward technically. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;&#039;POC&#039;&#039; computes tangents between the circles around vertices.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=343</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=343"/>
		<updated>2017-05-03T09:19:57Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Show me the code! */ Add general considerations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== General considerations ==&lt;br /&gt;
=== 3D vectors ===&lt;br /&gt;
Both algorithms extensively use 3D vectors and related operations. Should we use &amp;lt;code&amp;gt;Common::Vector3&amp;lt;/code&amp;gt; generally or only when it is really needed and uses arrays for all the other cases?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A* algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;&#039;SSFA&#039;&#039; is relatively straightforward technically. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;&#039;POC&#039;&#039; computes tangents between the circles around vertices.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=342</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=342"/>
		<updated>2017-05-01T20:20:23Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Simple Stupid Funnel Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A* algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;&#039;SSFA&#039;&#039; is relatively straightforward technically. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;&#039;POC&#039;&#039; computes tangents between the circles around vertices.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=341</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=341"/>
		<updated>2017-05-01T20:19:56Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Simple Stupid Funnel Algorithm */ Fix italic style for POC&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A* algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;&#039;POC&#039;&#039; computes tangents between the circles around vertices.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=340</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=340"/>
		<updated>2017-05-01T20:18:45Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Estimation and heuristic function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A* algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=339</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=339"/>
		<updated>2017-05-01T20:16:42Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Creature&amp;#039;s size */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A.2A_algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered like in [1].&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=338</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=338"/>
		<updated>2017-05-01T20:15:31Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* A* Algorithm */ Add creature&amp;#039;s size check&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A.2A_algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== Creature&#039;s size ===&lt;br /&gt;
This is an ideal step to check if the creature will fit into the path. In the &#039;&#039;POC&#039;&#039;, each face &#039;&#039;A*&#039;&#039; tries to go is naively checked by the size of the crossing edge. If it is too small, a second check is done by looking the intersection between a segment the size of the creature and the faces around. The first check might get false-positive with flat triangles and something else should be considered.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=337</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=337"/>
		<updated>2017-05-01T20:02:25Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Estimation and heuristic function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in [[#A.2A_algorithm]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=336</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=336"/>
		<updated>2017-05-01T20:01:40Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Estimation and heuristic function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [[#A.2A_algorithm first image]]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=TODO&amp;diff=335</id>
		<title>TODO</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=TODO&amp;diff=335"/>
		<updated>2017-05-01T11:47:52Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* NWN */ Add link to pathfinding page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a long rambly list of things left to do in xoreos and xoreos-tools. Anybody is welcome to tackle any of these tasks, but please also read our [[Developer_Central|general contributor overview]], including our [[Code_Formatting_Conventions|Code Formatting Conventions]], [[Commit_Guidelines|Commit Guidelines]] and [https://github.com/xoreos/xoreos/blob/master/CODE_OF_CONDUCT.md Code of Conduct]. If you plan to do any of these tasks, please also [[Contact_us|contact us]] beforehand, so we can better coordinate multiple people interested in doing the same task, and discuss how to best solve the problem. Thanks. :)&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;&#039;See also:&#039;&#039;&#039; the Kanban-like &amp;quot;Projects&amp;quot; boards on GitHub: https://github.com/orgs/xoreos/projects, but they&#039;re not public and no way to make public at the moment. Boo.)&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
=== Developer information ===&lt;br /&gt;
* Extend the developer information on the wiki&lt;br /&gt;
** Explain how to get the xoreos sources on various platforms&lt;br /&gt;
** Expand GNU/Linux compiling instructions to cover more distributions&lt;br /&gt;
** Expand Mac OS X compiling instructions&lt;br /&gt;
*** Xcode&lt;br /&gt;
*** Homebrew/MacPorts/Fink&lt;br /&gt;
*** CMake, Libraries&lt;br /&gt;
** [http://wiki.arx-libertatis.org/Developer_Information Arx Libertatis] has an extensive dev page&lt;br /&gt;
* Document file formats on the wiki?&lt;br /&gt;
** Or integrate info into XentaxWiki?&lt;br /&gt;
** Both?&lt;br /&gt;
&lt;br /&gt;
=== User information ===&lt;br /&gt;
* More user information on the wiki&lt;br /&gt;
** How to download xoreos&lt;br /&gt;
** How to install the games on various platforms&lt;br /&gt;
** [http://wiki.arx-libertatis.org/Main_Page Arx Libertatis] does that pretty well&lt;br /&gt;
&lt;br /&gt;
=== Modder information ===&lt;br /&gt;
* Link to relevant modding resources&lt;br /&gt;
* Maybe even some kind of Modder&#039;s Handbook&lt;br /&gt;
** A big overview of modding Aurora games in general&lt;br /&gt;
*** Differences and commonalities between games&lt;br /&gt;
** Linking/Grouping engine functions between games&lt;br /&gt;
&lt;br /&gt;
== Website ==&lt;br /&gt;
&lt;br /&gt;
=== Design ===&lt;br /&gt;
* Better website design?&lt;br /&gt;
** It still should be static in the end&lt;br /&gt;
*** No PHP or Rails&lt;br /&gt;
*** Very light on JavaScript&lt;br /&gt;
*** No Flash!&lt;br /&gt;
** Maybe a bit more unique, graphical&lt;br /&gt;
** For legal reasons, we shouldn&#039;t directly use art or designs from the original games&lt;br /&gt;
*** Something inspired by the art of the orginal games would fit&lt;br /&gt;
&lt;br /&gt;
=== Octopress ===&lt;br /&gt;
* Move away from Octopress?&lt;br /&gt;
** Alternative should still produce static HTML somehow&lt;br /&gt;
** Octopress works rather well. It reads Markdown, which is a plus&lt;br /&gt;
* Octopress 3.0?&lt;br /&gt;
** Not finished yet, it seems&lt;br /&gt;
&lt;br /&gt;
== Standalone(ish) fixes/improvements ==&lt;br /&gt;
&lt;br /&gt;
=== Broken NWN2 XML ===&lt;br /&gt;
* Not standards-conforming XML. Need custom XML parser; stock XML parsing libraries will just throw errors.&lt;br /&gt;
** &amp;lt;nowiki&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;NWN2UI&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** No single root element&lt;br /&gt;
** Attribute values not enclosed in quotes most of the time&lt;br /&gt;
** Special characters in attribute values not properly escaped&lt;br /&gt;
** Unmatched quotes on several occasions&lt;br /&gt;
* Event functions&lt;br /&gt;
* Special values like PARENT_WIDTH&lt;br /&gt;
* [https://github.com/xoreos/xoreos-tools/pull/1 Altrite is working on a broken-XML fixer]&lt;br /&gt;
&lt;br /&gt;
=== CJK glyphs in the console ===&lt;br /&gt;
* The &amp;quot;system font&amp;quot; we use for our debug console, DejaVu Sans Mono Bold, does not feature any CJK (Chinese, Japanese, Korean) glyphs&lt;br /&gt;
* Not strictly necessary, but nice to have for printing, say, Witcher area names in Asian languages&lt;br /&gt;
* We could maybe integrate CJK glyphs from the [http://fonts.jp/hanazono/ Hanazono fonts] or other suitable libre fonts&lt;br /&gt;
* We need to match the height with DejaVu Sans Mono Bold&lt;br /&gt;
* CJK glyphs tend to be more complex and therefore wider. They&#039;re usually rendered twice as wide as Latin glyphs&lt;br /&gt;
* Our console code needs to take that into account&lt;br /&gt;
&lt;br /&gt;
=== Fuzzing ===&lt;br /&gt;
* Run our file readers, image decoders, etc. through a fuzzer, like [http://lcamtuf.coredump.cx/afl/ afl] (american fuzzy lop)&lt;br /&gt;
* Fix any cases where it crashes&lt;br /&gt;
* The xoreos-tools might be a good starting point for singular, standalone testing&lt;br /&gt;
** For image decoders, a slightly modified xoreostex2tga tool might work&lt;br /&gt;
* File formats already fuzzed:&lt;br /&gt;
** CBGT, CDPTH, DDS, NBFS, NCGR, NCLR, SBM, TGA, TPC, TXB&lt;br /&gt;
** 2DA, KEY/BIF, ERF, GFF3, GFF4, GDA, TLK, NSBTX, RIM, SMALL, SSF&lt;br /&gt;
&lt;br /&gt;
=== Script decompiler ===&lt;br /&gt;
* It might be quite useful to have a NWScript decompiler in xoreos-tools&lt;br /&gt;
* We have a script disassembler, ncsdis&lt;br /&gt;
** Which already does code flow analysis&lt;br /&gt;
* Missing:&lt;br /&gt;
** Code generation&lt;br /&gt;
** Collapsing of instruction chains into single-line NWScript code&lt;br /&gt;
*** For example, &amp;quot;int var = foo * bar + quux&amp;quot; compiles to a long chain with multiple temporaries&lt;br /&gt;
** Proper handling of structs and vectors&lt;br /&gt;
&lt;br /&gt;
=== Script compiler ===&lt;br /&gt;
* An NWScript compiler might be useful as well&lt;br /&gt;
** A script assembler might be an easy first step&lt;br /&gt;
&lt;br /&gt;
=== File format writers ===&lt;br /&gt;
* GFF3Writer, GFF4Writer&lt;br /&gt;
** Both necessary to create save games compatible with the original games&lt;br /&gt;
** Also useful for a xml2gff tool&lt;br /&gt;
* xml2tlk&lt;br /&gt;
** TalkTable_GFF::write02() and ::write05()&lt;br /&gt;
** Needs GFF4Writer&lt;br /&gt;
* Archive (ERF, RIM, KEY/BIF) packers?&lt;br /&gt;
&lt;br /&gt;
=== Config file ===&lt;br /&gt;
* Should be more preserving of the layout&lt;br /&gt;
** Especially empty lines&lt;br /&gt;
** UTF-8 Byte-Order-Mark when using native Windows editors&lt;br /&gt;
** \r is currently always stripped. Maybe preserve that too&lt;br /&gt;
*** Autodetect when \r is already used, and add it to new config lines too&lt;br /&gt;
** This basically needs a complete rewrite of the config parser&lt;br /&gt;
*** Don&#039;t just look for comments, just throw everything after &amp;quot;foo=bar&amp;quot; into the &amp;quot;comment&amp;quot; variable, including whitespace&lt;br /&gt;
*** And all whitespace before &amp;quot;foo=bar&amp;quot; into a &amp;quot;prefix&amp;quot; variable&lt;br /&gt;
** Maybe even always add BOM and \r when writing a new config file on Windows?&lt;br /&gt;
&lt;br /&gt;
=== Windows-specific / Wine-specific ===&lt;br /&gt;
* When running my mingw32 cross-compiled xoreos EXE in Wine, the menu button texts are partially cut off&lt;br /&gt;
** Z-fighting issue?&lt;br /&gt;
** Does that also occur on a real Windows?&lt;br /&gt;
&lt;br /&gt;
=== GUI ===&lt;br /&gt;
* xoreos could use a global GUI to start games from&lt;br /&gt;
* Should probably be similar to ScummVM&#039;s GUI, at least in effect&lt;br /&gt;
* Should read the config file, list all targets&lt;br /&gt;
** Press a &amp;quot;Play&amp;quot; button to play the game&lt;br /&gt;
** Press an &amp;quot;Edit&amp;quot; button to edit the entry&lt;br /&gt;
*** Dialog options to edit common settings&lt;br /&gt;
*** An additional free-form editor?&lt;br /&gt;
*** Game-specific options?&lt;br /&gt;
** A button to edit global settings (&amp;quot;xoreos&amp;quot; config domain)&lt;br /&gt;
** For the future, a way to immediately load a saved game?&lt;br /&gt;
** An &amp;quot;Add&amp;quot; button to add a game&lt;br /&gt;
*** File browser&lt;br /&gt;
**** Select directories for most game&lt;br /&gt;
**** Select file for Sonic Chronicles&lt;br /&gt;
*** View current saved games of a target?&lt;br /&gt;
* Probably implemented using OpenGL, just like, say, the console&lt;br /&gt;
* Theme-able/Skinable?&lt;br /&gt;
* Some potential stumbling blocks&lt;br /&gt;
** Displaying &amp;quot;uncommon&amp;quot; text in both game descriptions and file paths&lt;br /&gt;
*** &amp;quot;Decomposed&amp;quot; letters, i.e. base letter + combining glyphs&lt;br /&gt;
*** CJK&lt;br /&gt;
*** Arabic and other scripts where letters change depending on their place in the word&lt;br /&gt;
*** Right-to-left&lt;br /&gt;
** Shortening those strings when they don&#039;t fit in their fields is also potentially difficult&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
* Text in exceptions?&lt;br /&gt;
** At least the user-visible ones, like &amp;quot;Failed to detect game&amp;quot;&lt;br /&gt;
** Or maybe we should clean that up and split them into &amp;quot;program logic failure&amp;quot; and &amp;quot;user failure&amp;quot;, with only the latter translated&lt;br /&gt;
* Strings for the engine loader progress bar&lt;br /&gt;
* Debug console string&lt;br /&gt;
* GUI (see above) strings&lt;br /&gt;
* [http://www.gnu.org/software/gettext/ GNU gettext] would be one solution&lt;br /&gt;
&lt;br /&gt;
=== Unit tests ===&lt;br /&gt;
* A lot of the common code would really profit from unit tests&lt;br /&gt;
* Automake has [https://www.gnu.org/software/automake/manual/html_node/Tests.html built-in support for test scripts], if that&#039;s the way we want to go&lt;br /&gt;
* Alternatively, there&#039;s [https://en.wikipedia.org/wiki/CppUnit CppUnit]&lt;br /&gt;
* And loads of other alternatives&lt;br /&gt;
&lt;br /&gt;
=== Resource Explorer ===&lt;br /&gt;
* A portable, user-friendly graphical resource explorer could be useful&lt;br /&gt;
* [https://github.com/xoreos/phaethon Phaethon] is a start&lt;br /&gt;
** It can look into game archives, show textures and play sounds&lt;br /&gt;
** It uses [https://www.wxwidgets.org/ wxWidgets] to do the GUI&lt;br /&gt;
** Or possibly rewriting it to use [https://www.qt.io/ Qt] is better?&lt;br /&gt;
&lt;br /&gt;
=== Model converters ===&lt;br /&gt;
* Document the model formats&lt;br /&gt;
* Convert between the binary model formats and their ASCII equivalents&lt;br /&gt;
* Convert between the binary model formats and ones that can be opened by modelling tools&lt;br /&gt;
** 3D Studio Max&lt;br /&gt;
** Blender&lt;br /&gt;
&lt;br /&gt;
=== Full-fledged modding toolset ===&lt;br /&gt;
* Similar to the NWN, NWN2 or Witcher toolset, but portable and FLOSS&lt;br /&gt;
** Might also support other games?&lt;br /&gt;
* Out of scope for xoreos&lt;br /&gt;
** Still, such a thing would be welcome under the xoreos banner&lt;br /&gt;
* [http://sourceforge.net/projects/neveredit/ Neveredit] might still be worth a look&lt;br /&gt;
&lt;br /&gt;
== Build system ==&lt;br /&gt;
&lt;br /&gt;
=== CMake ===&lt;br /&gt;
* Current doesn&#039;t set the git version to &amp;quot;+unk&amp;quot; when git isn&#039;t found&lt;br /&gt;
* make install?&lt;br /&gt;
* make doxygen?&lt;br /&gt;
&lt;br /&gt;
=== Autotools ===&lt;br /&gt;
* Suppress the &amp;quot;fatal: not a git repository&amp;quot; when building gitstamp without a git directory&lt;br /&gt;
* Increased modularity&lt;br /&gt;
** Disabling engines&lt;br /&gt;
*** Dropping library dependencies when the still enabled engine don&#039;t need them&lt;br /&gt;
** Making library dependencies optional (and disabling certain features, then)&lt;br /&gt;
*** liblzma is only needed for the iOS version of KotOR&lt;br /&gt;
*** libxml2 is only needed for the two Dragon Age games&lt;br /&gt;
*** libxvidcore is only needed for the Mac version of KotOR&lt;br /&gt;
*** libvorbis/libogg are probably only needed for The Witcher&lt;br /&gt;
** When something is disabled, skip it, if possible&lt;br /&gt;
*** Like the videos in KotOR Mac&lt;br /&gt;
** If skipping is not possible, error out&lt;br /&gt;
** We should then show a summary of what is enabled/disabled at the end of the configure script&lt;br /&gt;
* Switch to a non-recursive make setup?&lt;br /&gt;
** We still want a Makefile.am for each directory, so with include&lt;br /&gt;
* Remove the need to list all subdirectories with AC_CONFIG_FILES() in the configure.ac&lt;br /&gt;
** Parse Makefile.am for SUBDIRS, recursively?&lt;br /&gt;
*** Needs to pick up conditionally added entries, like for glew&lt;br /&gt;
** Substitution needs to happen before automake is called!&lt;br /&gt;
*** https://stackoverflow.com/questions/18200733/use-shell-commands-to-find-makefile-am-in-configure-ac&lt;br /&gt;
*** &amp;lt;nowiki&amp;gt;AC_CONFIG_FILES(m4_esyscmd([find . -name Makefile.am | sed -e &#039;s/^\.\///;s/\.am$//&#039;]))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nitro ==&lt;br /&gt;
&lt;br /&gt;
* The Nintendo DS (Nitro) specific file formats should probably be moved out of src/aurora/ and into src/nitro&lt;br /&gt;
* nitrofile, cdpth, nsbtx, smallfile&lt;br /&gt;
** nsbtx needs to be split into a class accessing the textures in src/nitro/ and an archive class on top in src/aurora/&lt;br /&gt;
** This means src/aurora/ accesses src/nitro/, so libnitro.la needs to come after libaurora.la in the linking order&lt;br /&gt;
* ndsrom as well?&lt;br /&gt;
* What about nftrfont and model_sonic in src/graphics/aurora/?&lt;br /&gt;
** src/graphics/nitro/?&lt;br /&gt;
** This would have src/graphics/nitro/ access src/graphics/aurora/, so graphics/libnitro.la needs to come before graphics/libaurora.la in the linking order&lt;br /&gt;
** That would be the other way round than for src/nitro/. Too confusing?&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
&lt;br /&gt;
=== MDL supermodels and animations ===&lt;br /&gt;
* Mostly working in NWN thanks to jbowtie&#039;s work&lt;br /&gt;
* Might need some cleanup&lt;br /&gt;
* Animation scale is off in a lot of cases. Mostly visible in the talking and yawning animations in non-human characters&lt;br /&gt;
* Models should smoothly change between different animations&lt;br /&gt;
* The animation system probably needs to be a bit more complex, to allow for &amp;quot;overlaying&amp;quot; different animations onto each other. For example, for speaking while holding an object and keeping the head focused on the PC character.&lt;br /&gt;
&lt;br /&gt;
=== Lighting ===&lt;br /&gt;
* We don&#039;t yet have a proper light system&lt;br /&gt;
* I started working on it: [https://drmccoy.de/xoreos/20150809T223407.png], but my approach is seriously lacking. You can see the edges of the tiles that make up on NWN area in many cases ([https://drmccoy.de/xoreos/20150809T223507.png], [https://drmccoy.de/xoreos/20150809T223548.png])&lt;br /&gt;
** See the [https://github.com/xoreos/xoreos/tree/light light branch] in the git repository&lt;br /&gt;
** Of course, the actual glLight* stuff won&#039;t be relevant anymore as soon as shaders are there&lt;br /&gt;
** Lighting in several (ASCII?) area tiles is broken&lt;br /&gt;
*** The door in Prelude.nwm&#039;s &amp;quot;m0q1a&amp;quot; area&lt;br /&gt;
*** A water tile in Chapter2.nwm&#039;s &amp;quot;map_m2q1a&amp;quot; area&lt;br /&gt;
*** A sloped snow tile in XP2_Chapter3.nwm&#039;s &amp;quot;thecityoflostsou&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Materials ===&lt;br /&gt;
* Materials in The Witcher are closely tied to shaders&lt;br /&gt;
&lt;br /&gt;
=== OpenGL and Shaders ===&lt;br /&gt;
* mirv_ is currently working on a graphics system overhaul, complete with shader support&lt;br /&gt;
* All Aurora games use shaders in some form&lt;br /&gt;
* NWN uses ARB shaders. We probably need to rewrite them from scratch&lt;br /&gt;
* DirectX shaders might be automatically convertible with Cg?&lt;br /&gt;
* Otherwise, look at what Wine does with the shaders, and use that as a basis?&lt;br /&gt;
* All the games, even NWN, use some form of shaders. Still totally missing from xoreos, since we have no idea how to use them in general yet. Moreover, this was before GLSL, so they&#039;re in the old assembly-like language. We probably need to rewrite them from scratch&lt;br /&gt;
* We need shaders for tinting in NWN2 (objects and area geometry) and TexturePaint nodes in Witcher&lt;br /&gt;
&lt;br /&gt;
=== SDL 1.2 ===&lt;br /&gt;
* Optionally link against SDL 1.2 instead of SDL 2&lt;br /&gt;
* Should ideally use a configure flag to select between the two&lt;br /&gt;
** Maybe a CMake flag as well, if possible&lt;br /&gt;
* Assigned to clone2727, so anybody interested in this should coordinate with him&lt;br /&gt;
&lt;br /&gt;
== Videos ==&lt;br /&gt;
&lt;br /&gt;
=== XMV/WMV ===&lt;br /&gt;
* Used in Xbox versions of KotOR/KotOR2&lt;br /&gt;
* Our WMV decoder (for XMV videos used in Xbox versions) is missing P-frames and J-frame&lt;br /&gt;
** Code exists in ffmpeg, but is connected to the MPEG-4 family mess&lt;br /&gt;
&lt;br /&gt;
=== Actimagine VX ===&lt;br /&gt;
* Used in the Nintendo DS game Sonic Chronicles&lt;br /&gt;
* https://wiki.multimedia.cx/index.php?title=Actimagine_Video_Codec&lt;br /&gt;
&lt;br /&gt;
=== Sorenson 3 ===&lt;br /&gt;
* One single video in the Mac port of KotOR2, the Aspyr logo, uses the Sorenson 3 codec&lt;br /&gt;
** ffmpeg has a decoder, but it&#039;s connected to the MPEG-4 family mess (SVQ3 is similar to H.264)&lt;br /&gt;
* ScummVM needs that too&lt;br /&gt;
** While xoreos is GPLv3+, ScummVM is GPLv2+&lt;br /&gt;
** Somebody implementing Sorenson 3 for xoreos should ideally give explicit permission to relicense it GPLv2+ for ScummVM&lt;br /&gt;
*** Of course, if the decoder is based on prior work by other people, it has to be compatible with both GPLv2+ and GPLv3+&lt;br /&gt;
&lt;br /&gt;
=== Optimizations ===&lt;br /&gt;
* Optimize our simple BitStream interface&lt;br /&gt;
** See [https://fgiesen.wordpress.com/2016/01/02/end-of-buffer-checks-in-decompressors/ this blog post]&lt;br /&gt;
** Specifically, we don&#039;t do any peeking at all&lt;br /&gt;
** It still needs to handle different memory layouts, though&lt;br /&gt;
* Likewise, our Huffman class could probably be tuned a lot&lt;br /&gt;
* Pull in fft/rdft/dct/mdct optimizations from FFmpeg?&lt;br /&gt;
&lt;br /&gt;
== Sound ==&lt;br /&gt;
&lt;br /&gt;
=== FMOD ===&lt;br /&gt;
* Dragon Age: Origins uses FMOD for sound and music&lt;br /&gt;
* I have experimental FSB (FMOD sound bank) support working in a private branch&lt;br /&gt;
* FEV (FMOD events) format is still unknown to us&lt;br /&gt;
** Apparently, groups of event lists with events&lt;br /&gt;
** Event is everything from &amp;quot;play sound&amp;quot;, over &amp;quot;set volume&amp;quot; to &amp;quot;apply echo&amp;quot;&lt;br /&gt;
** Game areas specify the group to use for the area&lt;br /&gt;
** Scripts then probably tell FMOD to play event lists out of that group&lt;br /&gt;
&lt;br /&gt;
=== Wwise ===&lt;br /&gt;
* Dragon Age 2 uses Wwise for sound and music&lt;br /&gt;
* Should be similar in concept to FMD&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
=== Gamepad binding ===&lt;br /&gt;
* The Xbox versions of KotOR and KotOR2 don&#039;t use a mouse. We have basic support for joysticks/gamepads, but no real bindings to the engine or ideas how to handle that in general&lt;br /&gt;
* We might want to handle the controller support the new KotOR2 Steam update brought&lt;br /&gt;
** override folder contains a gamepad.txt then&lt;br /&gt;
* Also hack in controller support for a non-Steam KotOR2? And for KotOR?&lt;br /&gt;
* Controller support in Jade Empire&lt;br /&gt;
* Controller support for Sonic? It is a Nintendo DS game after all&lt;br /&gt;
* Controller support for the non-console versions of the Dragon Age games?&lt;br /&gt;
&lt;br /&gt;
== Network ==&lt;br /&gt;
* We need a network subsystem&lt;br /&gt;
** [https://www.libsdl.org/projects/SDL_net/ SDL_net]?&lt;br /&gt;
** [http://www.boost.org/doc/libs/release/libs/asio/ Boost.Asio]?&lt;br /&gt;
** More options here: http://stackoverflow.com/questions/118945/best-c-c-network-library&lt;br /&gt;
* Engines need to be split into client and server classes&lt;br /&gt;
** The original engines all still do that, even when not exposing anything to users&lt;br /&gt;
** NWN and NWN2 allow user multiplayer&lt;br /&gt;
&lt;br /&gt;
== Engines ==&lt;br /&gt;
&lt;br /&gt;
=== Script system ===&lt;br /&gt;
* ImperatorPrime had started on a script system rewrite&lt;br /&gt;
** Includes functions with real signatures&lt;br /&gt;
** Maybe switch to that, if it works&lt;br /&gt;
* Rounds, object heartbeat scripts&lt;br /&gt;
* KotOR2 and NWN2 have some extensions&lt;br /&gt;
** It seems like they don&#039;t need any extensions to the low-level bytecode stuff&lt;br /&gt;
* Witcher uses Lua scripts together with NWScript&lt;br /&gt;
* Sonic has no scripts at all, it seems&lt;br /&gt;
* Currently a script in an infinite loop locks the game thread&lt;br /&gt;
** Timeout? Asynchronous script execution?&lt;br /&gt;
&lt;br /&gt;
=== NWN ===&lt;br /&gt;
* Menus&lt;br /&gt;
** Basics are there, but needs fleshing out&lt;br /&gt;
** Supermanu is working on the character generator&lt;br /&gt;
* [[Pathfinding]], walkmesh&lt;br /&gt;
** &amp;quot;Moving&amp;quot; should move the PC, not the camera&lt;br /&gt;
** NPC walking&lt;br /&gt;
** Triggers, areas on the floor that calls scripts on enter/leave&lt;br /&gt;
* Models&lt;br /&gt;
** ASCII models need averaging of smooth group normals&lt;br /&gt;
* NWN objects need an inventory concept&lt;br /&gt;
** Player characters&#039; might be different&lt;br /&gt;
*** Inventory tetris&lt;br /&gt;
*** Inventory item icons&lt;br /&gt;
* Multi-page asian fonts&lt;br /&gt;
* LanguageID 0 is not necessarily &amp;quot;English&amp;quot;, but &amp;quot;The language of the game install&amp;quot;&lt;br /&gt;
** This is okay for languages with Latin characters&lt;br /&gt;
** Messes up strings in community modules with Asian languages that stuff strings in to languageID 0&lt;br /&gt;
** The original fails there too, though&lt;br /&gt;
&lt;br /&gt;
=== KotOR/KotOR2 ===&lt;br /&gt;
* Menus&lt;br /&gt;
** Basic structure is already there, just missing most of the specific widgets stuff&lt;br /&gt;
** Semi-hardcoded, with GFF files (hierachical data, similar to XML in spirit) describing the setup. The xoreos-tools repository has a tool for converting GFF files into XML for easy reading.&lt;br /&gt;
* Dialogues&lt;br /&gt;
** DLG files, similar to NWN&lt;br /&gt;
** Some extensions, like camera setup&lt;br /&gt;
** Dialogues are displayed very different than NWN&lt;br /&gt;
** KotOR2 has script extensions&lt;br /&gt;
*** Passing parameters to scripts&lt;br /&gt;
*** Call several scripts, combine with AND/OR for branching&lt;br /&gt;
* Animations&lt;br /&gt;
** Should be similar to NWN&lt;br /&gt;
** No player character shown&lt;br /&gt;
*** Needs character creator menus&lt;br /&gt;
*** Loading of character files in class Creature&lt;br /&gt;
* Minigames&lt;br /&gt;
** Swoop racing&lt;br /&gt;
** Pazaak&lt;br /&gt;
** Hardcoded, mostly removed from usual game logic&lt;br /&gt;
&lt;br /&gt;
=== Jade Empire ===&lt;br /&gt;
* Menus&lt;br /&gt;
** Apparently very similar to KotOR&#039;s menus&lt;br /&gt;
* Minigames&lt;br /&gt;
** Flyer, top-down shoot-em-up thing&lt;br /&gt;
** Hardcoded, mostly removed from usual game logic&lt;br /&gt;
* Player character&lt;br /&gt;
** Needs research&lt;br /&gt;
* Sound&lt;br /&gt;
** Uses an ASCII variant of the [http://wiki.multimedia.cx/index.php?title=XACT XACT formats]&lt;br /&gt;
*** Cues probably not as complex as FMOD/Wwise&lt;br /&gt;
*** Effects need extension of the Sound system, maybe&lt;br /&gt;
** Xbox version might use the binary format?&lt;br /&gt;
*** Sound banks could be handles as archives and indexed in the ResourceManager?&lt;br /&gt;
** [https://github.com/FNA-XNA/FNA/tree/master/src/Audio FNA] has an implementation of XACT. Probably quite useful to look at that&lt;br /&gt;
&lt;br /&gt;
=== NWN2 ===&lt;br /&gt;
* Menus&lt;br /&gt;
** Implemented using XML&lt;br /&gt;
** See [[#Broken NWN2 XML|Broken NWN2 XML]]&lt;br /&gt;
* Animations (Granny)&lt;br /&gt;
** [https://github.com/SkywingvL/nwn2dev-public nwn2-dev] contains some code working with Granny data&lt;br /&gt;
*** Call into the original Granny DLL to convert between binary and ASCII Granny data, though&lt;br /&gt;
** [https://github.com/berenm/xoreos-tools/tree/granny berenm started some Granny RE]&lt;br /&gt;
* Facial animations (FaceFX)&lt;br /&gt;
* Trees (SpeedTree)&lt;br /&gt;
* Proper evaluation of creature model parts (equipped items)&lt;br /&gt;
* Player character&lt;br /&gt;
** Reading of PC files in creature&lt;br /&gt;
&lt;br /&gt;
=== Sonic Chronicles ===&lt;br /&gt;
* Allow using the contents from an extracted NDS file?&lt;br /&gt;
* Menus&lt;br /&gt;
** GUI files that are GFF&lt;br /&gt;
** Actions in a state machine in GDA files?&lt;br /&gt;
* Music/Sound&lt;br /&gt;
** Music is apparently similar to MIDI, or to a tracker format?&lt;br /&gt;
** Sounds and instruments for music are in a sound_data.sadl archive&lt;br /&gt;
* Animations&lt;br /&gt;
** Bone animations, best implemented with shaders, blocked by the graphics subsystem rewrite&lt;br /&gt;
* Player character(s)&lt;br /&gt;
** Needs research&lt;br /&gt;
&lt;br /&gt;
=== The Witcher ===&lt;br /&gt;
* Menus&lt;br /&gt;
** Apparently build using Lua&lt;br /&gt;
** System/Scripts/ has gui*.luc files&lt;br /&gt;
* Animations&lt;br /&gt;
** Needs research&lt;br /&gt;
* Player character, Geralt&lt;br /&gt;
** Needs research&lt;br /&gt;
&lt;br /&gt;
=== Dragon Age: Origins / Dragon Age 2 ===&lt;br /&gt;
* Menus&lt;br /&gt;
** [https://en.wikipedia.org/wiki/Scaleform_GFx Scaleform GFx]&lt;br /&gt;
** [http://social.bioware.com/wiki/datoolset/index.php/UI_Tutorial_%28draft%29 UI Tutorial] on the Dragon Age toolset wiki&lt;br /&gt;
** Flash-based!&lt;br /&gt;
** A good starting point for a reimplementation might be [https://en.wikipedia.org/wiki/Gameswf Gameswf].&lt;br /&gt;
** [https://en.wikipedia.org/wiki/Gnash Gnash], [https://en.wikipedia.org/wiki/Lightspark Lightspark], [https://en.wikipedia.org/wiki/Swfdec Swfdec]&lt;br /&gt;
** [http://www.nowrap.de/flasm.html Flasm] can disassemble/assemble ActionScript, [http://www.nowrap.de/flare.html Flare] can decompile it&lt;br /&gt;
* Animations&lt;br /&gt;
** Bone animations, best implemented with shaders, blocked by the graphics subsystem rewrite&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=334</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=334"/>
		<updated>2017-04-26T16:04:03Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Simple Stupid Funnel Algorithm */ technical details&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [#A.2A_algorithm first image]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
The &#039;SSFA&#039; is relatively straighforward technicaly. The main difficulty is about creature&#039;s size. In order to take it into account, the &#039;POC&#039; computes tangents between the circles around vertices. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=333</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=333"/>
		<updated>2017-04-26T14:19:25Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* External libraries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [#A.2A_algorithm first image]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convince me at first sight.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=332</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=332"/>
		<updated>2017-04-26T11:06:19Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Add External libraries&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [#A.2A_algorithm first image]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
=== External libraries ===&lt;br /&gt;
Several geometric functions are needed to make everything work (intersections between different polygons, distances,…) though most of them in the &#039;POC&#039; are home-made/based on google results, some use Boost.geometry (at least one) for simplicity sake. I guess, we should use this library as most as possible from a maintenance, efficiency and performance perspective. There is also [http://www.cgal.org/ CGAL] that seems complete though it didn&#039;t convinced me at first sight.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=331</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=331"/>
		<updated>2017-04-19T16:11:13Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Restructure&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
= How pathfinding works? =&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
== A* algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
== Simple Stupid Funnel Algorithm ==&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
== Other steps ==&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
= Show me the code! =&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
== Walkmesh data format ==&lt;br /&gt;
&lt;br /&gt;
=== KotOR ===&lt;br /&gt;
&lt;br /&gt;
=== Nwn ===&lt;br /&gt;
&lt;br /&gt;
== A* Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
=== Graph structure ===&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
=== Open list ===&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
=== Estimation and heuristic function ===&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [#A.2A_algorithm first image]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=330</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=330"/>
		<updated>2017-04-19T15:45:01Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Estimation and heuristic function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
==== Graph structure ====&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
==== Open list ====&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
==== Estimation and heuristic function ====&lt;br /&gt;
The total estimation when &#039;&#039;A*&#039;&#039; tries to find the best next node, is given by the sum of two functions. The current cost function that gives the current length of the path. and the heuristic function that estimates the length to the end. In the &#039;&#039;POC&#039;&#039;, the former is measured by the path going through the middle of each edge it crosses (as seen in the [#A.2A_algorithm first image]). This could obviously changed, one can take the center of a face/triangle (incenter, centroid, …) for instance. The more naive heuristic function is simply the direct length to the endpoint. Again this could be improved in some specific cases, as the &#039;&#039;walkmesh&#039;&#039; is built from several parts (tiles, rooms,…), one can directly run &#039;&#039;A*&#039;&#039; on those by considering them as one big face. It could be a real improvement in maze like areas.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=329</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=329"/>
		<updated>2017-04-17T20:08:48Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Open list */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
==== Graph structure ====&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
==== Open list ====&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with big/complex walkmesh.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=328</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=328"/>
		<updated>2017-04-17T19:56:49Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Open list */ Link to boost.heap&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
==== Graph structure ====&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
==== Open list ====&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as [http://www.boost.org/doc/libs/1_63_0/doc/html/heap.html boost.heap] which is, imho, more complete. Though performance drops might only appear with &#039;&#039;big&#039;&#039; walkmesh.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=327</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=327"/>
		<updated>2017-04-17T19:55:33Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* Open list */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
==== Graph structure ====&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
==== Open list ====&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]]. The &#039;&#039;POC&#039;&#039; uses a &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; which is sorted whenever a node is added. This is obviously not the fastest way to do it. &amp;lt;code&amp;gt;std::priority_queue&amp;lt;/code&amp;gt; could be used as well as &amp;lt;code&amp;gt;boost.heap&amp;lt;/code&amp;gt; which is, imho, more complete. Though performance drops might only appear with &#039;&#039;big&#039;&#039; walkmesh.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=326</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=326"/>
		<updated>2017-04-17T19:44:05Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* A* Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
Though each game comes with it&#039;s own walkmesh dataformat, at the end we need an underlying structure that will store the walkmesh. In the &#039;&#039;POC&#039;&#039;, the walkmesh is stored in 5 &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;:&lt;br /&gt;
* A vector of float which contains the vertices,&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for each face of the walkmesh. It stores the related vertices and thus is three times the total number of faces (which are triangles).&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for adjacent faces. It stores for each side of a face, the adjacent face. &amp;lt;code&amp;gt;UINT32_MAX&amp;lt;/code&amp;gt; is used when there is no adjacent face.&lt;br /&gt;
* A vector of &amp;lt;code&amp;gt;UINT32&amp;lt;/code&amp;gt; for face property. It stores the kind of material the face is.&lt;br /&gt;
* A vector of [https://en.wikipedia.org/wiki/Bounding_volume AABB] trees. Each leaf of an AABB tree embeds a face. This allows to make fast face search based on coordinate.&lt;br /&gt;
&lt;br /&gt;
==== Graph structure ====&lt;br /&gt;
&#039;&#039;A*&#039;&#039; is graph based algorithm with nodes and edges. Different choices can be made on what nodes and edges are. Vertices and faces can be taken as nodes as well as a side of a face, the edges being what connects them. For simplicity sake, in the &#039;&#039;POC&#039;&#039;, face has been taken as node and face adjacency as edge. Other choices could lead to better or worst performances as regards of the length of the path and time spent.&lt;br /&gt;
&lt;br /&gt;
==== Open list ====&lt;br /&gt;
&#039;&#039;A* uses a priority queue to perform the repeated selection of minimum (estimated) cost nodes to expand&#039;&#039; [[https://en.wikipedia.org/wiki/A*_search_algorithm#Description Wikipedia]].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=325</id>
		<title>Pathfinding</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Pathfinding&amp;diff=325"/>
		<updated>2017-04-16T18:59:06Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Initial content for pathfinding page: How pathfinding works?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pathfinding =&lt;br /&gt;
&lt;br /&gt;
This is a collection of thoughts, documentations, mumbling, and explanation of the work done about pathfinding. Any ideas or comments are more than welcome.&lt;br /&gt;
&lt;br /&gt;
Up to now, only KotOR and nwn have been investigated. Any &amp;amp;quot;findings&amp;amp;quot; might not apply to other games.&lt;br /&gt;
&lt;br /&gt;
== How pathfinding works? ==&lt;br /&gt;
&lt;br /&gt;
The engine seems to use a [https://en.wikipedia.org/wiki/Navigation_mesh navigation mesh] or &#039;&#039;walkmesh&#039;&#039; as the underlying data structure. It is simply a polygon mesh where each face has a &#039;&#039;walk property&#039;&#039; to state if an agent/creature can walk on this particular face and what kind of material the face is (metal, carpet, grass,…).&lt;br /&gt;
&lt;br /&gt;
=== A* algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:walkmesh_path_search.png|center|thumb|none|550x344px|Walkmesh in KotOR. The green faces are unwalkable. The pink adjacent faces represent a path between two points.]]&lt;br /&gt;
&lt;br /&gt;
The first step in pathfinding, is to find a series of adjacent faces among the navigation mesh that constitutes a path between two points. Ideally, the path is the shortest one but it highly depends on the quality of the &#039;&#039;walkmesh&#039;&#039; and the kind of algorithm used. As we want to reuse what is already there – the &#039;&#039;walkmesh&#039;&#039; – our only leverage will be the algorithm part though some pre-processing steps on the &#039;&#039;walkmesh&#039;&#039; might be needed as explained later.&lt;br /&gt;
&lt;br /&gt;
There are several algorithms that tries to achieve that goal. [https://en.wikipedia.org/wiki/A*_search_algorithm &#039;&#039;A*&#039;&#039;] and all its variants is a widely used algorithm in games and real-time applications, it is both accurate and fast though it won’t necessarily give the best path but one of the bests. Basically, it will start from an endpoint of the path and try to go around, on another face, and estimates if it is closer to the other side of the path. The main area one can improve about the algorithm’s performance is on the way it thinks how closer it moves to the end. The function that gives this estimation is called the &#039;&#039;heuristic&#039;&#039; and will be discussed later.&lt;br /&gt;
&lt;br /&gt;
=== Simple Stupid Funnel Algorithm ===&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA.png|center|thumb|none|525x328px|Another pathfinding search in KotOR using A* and the Simple Stupid Funnel Algorithm.]]&lt;br /&gt;
&lt;br /&gt;
Once we have a series of adjacent faces, comes the second step: to have a nice line our creature can follow. Again, there are several algorithms able to address that kind of issue, though I will focus on the [http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html Simple Stupid Funnel Algorithm](&#039;&#039;SSFA&#039;&#039;) taken from Mikko Mononen blogpost and author of the Recast and Detour toolset. The idea behind &#039;&#039;SSFA&#039;&#039;, is like pulling two strings from the start to each border of the faces path. The algorithm goes from vertex to vertex that belongs to the border and must make the funnel formed by the two strings narrower at each iteration and lie inside the faces path. Otherwise, it has to pull the strings from a previous vertex. As an image is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_explained.png|center|thumb|297x327px]]&lt;br /&gt;
&lt;br /&gt;
On the above image, A-B-C-D steps narrow the funnel. In the E step, the red string cannot move since it would be outside the path. In the F step, the two strings are crossing so it has to restart from a previous vertex in the next iteration &#039;&#039;i.e.&#039;&#039; the G step.&lt;br /&gt;
&lt;br /&gt;
One thing that &#039;&#039;SSFA&#039;&#039; doesn’t directly take into account is creature’s size. In deed, it gives us a path that sticks to the border. To deal with it, one trick[1] is to consider a circle around each vertex that cannot be crossed by the funnel.&lt;br /&gt;
&lt;br /&gt;
[[File:SSFA_size.png|center|277x261px]]&lt;br /&gt;
[[File:pathfinding_smooth.png|center|503x320px]]&lt;br /&gt;
&lt;br /&gt;
=== Other steps ===&lt;br /&gt;
&lt;br /&gt;
While we can have &amp;lt;s&amp;gt;a beautiful&amp;lt;/s&amp;gt; an acceptable path with &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; algorithms, the job is far from being done. First, the &#039;&#039;walkmesh&#039;&#039; doesn’t take into account all static objects like crates or seats. Somehow, some of those static objects are included in the walkmesh and some don’t (screw you bioware!). An idea to deal with that, would be to add those static objects to the walkmesh directly as a pre-processing step or simply consider them as dynamic objects.&lt;br /&gt;
&lt;br /&gt;
Anyway, pathfinding also have to handle dynamic objects &#039;&#039;i.e.&#039;&#039; the ones that can move, be destroyed or spontaneously appear. Contrary to the previous steps, this needs to be done along the path a creature is taking. I guess it should be independent from &#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039; and done by scanning with rays or something else what’s in front of the creature in real-time.&lt;br /&gt;
&lt;br /&gt;
== Show me the code! ==&lt;br /&gt;
&lt;br /&gt;
A first proof of concept has been made in this [https://github.com/Supermanu/xoreos/tree/pathfinding branch]. It is an awful code with lot of dead code and stuff nobody should ever see. It only works (&#039;&#039;A*&#039;&#039; and &#039;&#039;SSFA&#039;&#039;) with KotOr but has some code for nwn. Also, it needs [http://www.boost.org/doc/libs/1_63_0/libs/geometry/doc/html/index.html Boost.Geometry] to run. Let’s try to explain the code in details and the choices made.&lt;br /&gt;
&lt;br /&gt;
=== Walkmesh data format ===&lt;br /&gt;
&lt;br /&gt;
==== KotOR ====&lt;br /&gt;
&lt;br /&gt;
==== Nwn ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A* Algorithm ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[1] &#039;&#039;&#039;Efficient Triangulation-Based Pathfinding&#039;&#039;&#039;, &#039;&#039;Douglas Demyen and Michael Buro&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=File:Pathfinding_smooth.png&amp;diff=324</id>
		<title>File:Pathfinding smooth.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=File:Pathfinding_smooth.png&amp;diff=324"/>
		<updated>2017-04-16T18:34:36Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Walkmesh in KotOR and path search with A*, SSFA with creature&amp;#039;s size.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Walkmesh in KotOR and path search with A*, SSFA with creature&#039;s size.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=File:SSFA_size.png&amp;diff=323</id>
		<title>File:SSFA size.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=File:SSFA_size.png&amp;diff=323"/>
		<updated>2017-04-16T18:31:53Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Illustration of the Simple Stupid Funnel Algorithm taking account creature&amp;#039;s size.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Illustration of the Simple Stupid Funnel Algorithm taking account creature&#039;s size.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=File:SSFA_explained.png&amp;diff=322</id>
		<title>File:SSFA explained.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=File:SSFA_explained.png&amp;diff=322"/>
		<updated>2017-04-16T18:10:03Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Different steps of Simple Stupid Funnel Algorithm from Mikko Mononen&amp;#039;s blog post http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Different steps of Simple Stupid Funnel Algorithm from Mikko Mononen&#039;s blog post http://digestingduck.blogspot.be/2010/03/simple-stupid-funnel-algorithm.html&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=File:SSFA.png&amp;diff=321</id>
		<title>File:SSFA.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=File:SSFA.png&amp;diff=321"/>
		<updated>2017-04-16T18:03:25Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Walkmesh and path search with the Simple Stupid Funnel Algorithm.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Walkmesh and path search with the Simple Stupid Funnel Algorithm.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=File:Walkmesh_path_search.png&amp;diff=320</id>
		<title>File:Walkmesh path search.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=File:Walkmesh_path_search.png&amp;diff=320"/>
		<updated>2017-04-15T19:52:55Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Walkmesh in KotOR and an A* path search.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Walkmesh in KotOR and an A* path search.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=284</id>
		<title>Neverwinter Nights/Research</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=284"/>
		<updated>2016-06-23T18:56:23Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: How walkmesh may work&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Lighting ==&lt;br /&gt;
&lt;br /&gt;
original NWN for linux uses: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_DIFFUSE, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_SPECULAR, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_POSITION, params = {14.99999, 4.999998, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_DIFFUSE, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_SPECULAR, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_POSITION, params = {14.02705, 2.55035, 4, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.18)&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_POSITION, params = {14.9855, 1.83074, 1.62787, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.09183674)&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_POSITION, params = {5, 15, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_DIFFUSE, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_SPECULAR, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_POSITION, params = {5, 5, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for light0 the following is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_DIFFUSE, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_POSITION, params = {0, 0, 742.4, 1})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Walkmesh ==&lt;br /&gt;
&lt;br /&gt;
The way nwn determines where a character/creature can or cannot walk seems to involve two different parts: a mesh and AABB[https://en.wikipedia.org/wiki/Bounding_volume] for collision detection. Those two parts can be found in a tile model &amp;quot;.mdl&amp;quot; and is associated &amp;quot;.wok&amp;quot; file (an ASCII file). The data in the model and in the wok seems to be almost redundant: slightly different at the mesh level.&lt;br /&gt;
&lt;br /&gt;
=== Mesh ===&lt;br /&gt;
&lt;br /&gt;
The mesh can be found in both the mdl and the wok. In the mdl, it can be found as a normal mesh in the node that contains both AABB and mesh flags. Each face of the mesh have a smooth property that can be related to a specific material. The material properties is in the &amp;quot;surfacemat.2da&amp;quot; file where the index is the smooth value. The 2da file contains two columns with boolean values, &amp;quot;Walk&amp;quot; and &amp;quot;WalkCheck&amp;quot;, that should surely indicates where one can walk or not.&lt;br /&gt;
&lt;br /&gt;
=== AABB ===&lt;br /&gt;
&lt;br /&gt;
Similarly to the mesh, AABBs can be found in the model in the same node and directly in the wok file. AABBs come as a binary tree, each leaf from that tree is related to a specific face from the walkmesh and surrounds it. It is the &#039;&#039;part_number_leaf_face&#039;&#039;[https://github.com/xoreos/xoreos-docs/blob/master/templates/NWN1MDL.bt#L601] property that relates to the face.&lt;br /&gt;
&lt;br /&gt;
=== Difference between mdl and wok ===&lt;br /&gt;
&lt;br /&gt;
The shape of the mesh in the mdl and the wok are the same though the number of vertices differs. In deed, in the mdl one can find more or less three times the number of vertices regarding the wok. In fact, almost each face in the mdl has its own vertices, only a few share some vertices.&lt;br /&gt;
&lt;br /&gt;
About AABB, it seems they are the same in both files.&lt;br /&gt;
&lt;br /&gt;
=== How it could work ===&lt;br /&gt;
&lt;br /&gt;
There are two cases. First, when the user want to know where he can/cannot go by moving the cursor. In this case, the intersection between the ray coming from the camera and the AABB tree will give a AABB leaf node, its related face and thus if it is walkable or not. Second, when a creature want to move, it needs to know if it can, what sound should be played and the vertical position of the creature. The intersection in the XY plan of the creature&#039;s bounding box and the AABB tree should give similarly as the former case if the creature can be moved. For the vertical position, one hypothesis would be that it is given from the intersection between the XY position of the creature and the related face from the AABB leaf node.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=283</id>
		<title>Neverwinter Nights/Research</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=283"/>
		<updated>2016-03-16T10:57:04Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: /* AABB */  Add info about leaf face property&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Lighting ==&lt;br /&gt;
&lt;br /&gt;
original NWN for linux uses: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_DIFFUSE, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_SPECULAR, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_POSITION, params = {14.99999, 4.999998, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_DIFFUSE, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_SPECULAR, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_POSITION, params = {14.02705, 2.55035, 4, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.18)&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_POSITION, params = {14.9855, 1.83074, 1.62787, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.09183674)&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_POSITION, params = {5, 15, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_DIFFUSE, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_SPECULAR, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_POSITION, params = {5, 5, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for light0 the following is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_DIFFUSE, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_POSITION, params = {0, 0, 742.4, 1})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Walkmesh ==&lt;br /&gt;
&lt;br /&gt;
The way nwn determines where a character/creature can or cannot walk seems to involve two different parts: a mesh and AABB[https://en.wikipedia.org/wiki/Bounding_volume] for collision detection. Those two parts can be found in a tile model &amp;quot;.mdl&amp;quot; and is associated &amp;quot;.wok&amp;quot; file (an ASCII file). The data in the model and in the wok seems to be almost redundant: slightly different at the mesh level.&lt;br /&gt;
&lt;br /&gt;
=== Mesh ===&lt;br /&gt;
&lt;br /&gt;
The mesh can be found in both the mdl and the wok. In the mdl, it can be found as a normal mesh in the node that contains both AABB and mesh flags. Each face of the mesh have a smooth property that can be related to a specific material. The material properties is in the &amp;quot;surfacemat.2da&amp;quot; file where the index is the smooth value. The 2da file contains two columns with boolean values, &amp;quot;Walk&amp;quot; and &amp;quot;WalkCheck&amp;quot;, that should surely indicates where one can walk or not.&lt;br /&gt;
&lt;br /&gt;
=== AABB ===&lt;br /&gt;
&lt;br /&gt;
Similarly to the mesh, AABBs can be found in the model in the same node and directly in the wok file. AABBs come as a binary tree, each leaf from that tree is related to a specific face from the walkmesh and surrounds it. It is the &#039;&#039;part_number_leaf_face&#039;&#039;[https://github.com/xoreos/xoreos-docs/blob/master/templates/NWN1MDL.bt#L601] property that relates to the face.&lt;br /&gt;
&lt;br /&gt;
=== Difference between mdl and wok ===&lt;br /&gt;
&lt;br /&gt;
The shape of the mesh in the mdl and the wok are the same though the number of vertices differs. In deed, in the mdl one can find more or less three times the number of vertices regarding the wok. In fact, almost each face in the mdl has its own vertices, only a few share some vertices.&lt;br /&gt;
&lt;br /&gt;
About AABB, it seems they are the same in both files.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
	<entry>
		<id>https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=282</id>
		<title>Neverwinter Nights/Research</title>
		<link rel="alternate" type="text/html" href="https://wiki.xoreos.org/index.php?title=Neverwinter_Nights/Research&amp;diff=282"/>
		<updated>2016-03-09T15:47:02Z</updated>

		<summary type="html">&lt;p&gt;Supermanu: Add info about walkmesh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Lighting ==&lt;br /&gt;
&lt;br /&gt;
original NWN for linux uses: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;4.5e-10)&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.02543954)&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_DIFFUSE, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_SPECULAR, params = {1.3, 1.92, 1.82, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_POSITION, params = {14.99999, 4.999998, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT3, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_DIFFUSE, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_SPECULAR, params = {2, 0.5, 0.2, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_POSITION, params = {14.02705, 2.55035, 4, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT4, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.18)&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_POSITION, params = {14.9855, 1.83074, 1.62787, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT5, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.09183674)&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_POSITION, params = {5, 15, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT6, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_DIFFUSE, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_SPECULAR, params = {0.196573, 0.1474298, 0.05897192, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_POSITION, params = {5, 5, 5, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT7, pname = GL_QUADRATIC_ATTENUATION, params = &amp;amp;0.045)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for light0 the following is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_AMBIENT, params = {0, 0, 0, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_DIFFUSE, params = {1, 1, 1, 1})&lt;br /&gt;
glLightfv(light = GL_LIGHT0, pname = GL_POSITION, params = {0, 0, 742.4, 1})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Walkmesh ==&lt;br /&gt;
&lt;br /&gt;
The way nwn determines where a character/creature can or cannot walk seems to involve two different parts: a mesh and AABB[https://en.wikipedia.org/wiki/Bounding_volume] for collision detection. Those two parts can be found in a tile model &amp;quot;.mdl&amp;quot; and is associated &amp;quot;.wok&amp;quot; file (an ASCII file). The data in the model and in the wok seems to be almost redundant: slightly different at the mesh level.&lt;br /&gt;
&lt;br /&gt;
=== Mesh ===&lt;br /&gt;
&lt;br /&gt;
The mesh can be found in both the mdl and the wok. In the mdl, it can be found as a normal mesh in the node that contains both AABB and mesh flags. Each face of the mesh have a smooth property that can be related to a specific material. The material properties is in the &amp;quot;surfacemat.2da&amp;quot; file where the index is the smooth value. The 2da file contains two columns with boolean values, &amp;quot;Walk&amp;quot; and &amp;quot;WalkCheck&amp;quot;, that should surely indicates where one can walk or not.&lt;br /&gt;
&lt;br /&gt;
=== AABB ===&lt;br /&gt;
&lt;br /&gt;
Similarly to the mesh, AABB can be found in the model in the same node and directly in the wok file.&lt;br /&gt;
&lt;br /&gt;
=== Difference between mdl and wok ===&lt;br /&gt;
&lt;br /&gt;
The shape of the mesh in the mdl and the wok are the same though the number of vertices differs. In deed, in the mdl one can find more or less three times the number of vertices regarding the wok. In fact, almost each face in the mdl has its own vertices, only a few share some vertices.&lt;br /&gt;
&lt;br /&gt;
About AABB, it seems they are the same in both files.&lt;/div&gt;</summary>
		<author><name>Supermanu</name></author>
	</entry>
</feed>