barsonax / pathfindax Goto Github PK
View Code? Open in Web Editor NEWPathfinding framework
License: GNU Affero General Public License v3.0
Pathfinding framework
License: GNU Affero General Public License v3.0
Even though the MinHeap is called MinHeap the first element does not actually have the smallest value but instead has the largest value. Because of this rename the MinHeap to MaxHeap.
There should be a getting started guide for making your own Pathfinder and using it in duality
Cleanup the nodenetwork interfaces and make it clearer that there is a source node network and a node network for each thread:
Remove properties from node networks that simply return their value by looking at the source node network. The source node network itself should be used for this. This should make some interfaces quite a bit smaller.
In the Pathfinder it should be clear what is a source node network and what not.
Interface structure should be consistent
This applies to the Pathfindax.Duality project.
In order to integrate pathfindax with duality it needs to be easily accessible from other components. The following steps have to be done to achieve this:
This makes it possible for other classes to easily request a path.
In some of the refactorings in #35 the logic that created the request in the pathfindproxies has been moved to the pathfindalgorithms. So currently the pathfindproxies do nothing but get a reference to a pathfinder.
This could be done alternatively by getting a reference to a pathfindcomponent (with GetComponent or just setting it in the duality editor) so there is no longer a need for pathfindproxies.
Currently the MouseClickPathfinder has implementations for both grid and non grid pathfinding. A OnGrid Boolean controls which implementation is active. These should be separated in 2 different components as they most likely wont be used at the same time in real scenarios.
While at it provide additional comments explaining what each property/method does.
As this is not included in the nuget package there is no need to make a new release.
Add support for await to PathRequest. This can be done by implementing a GetAwaiter method that returns a class that implements INotifyCompletion, a GetResult method and a Status property.
Awaiting a pathrequest will symantically be the same as adding a callback to a pathrequest and therefore should also call AddCallback behind the scenes.
Add a astar pathfinder that works on non grid maps
Duality tilemaps can have multiple collision layers. The pathfinding has to support this aswell.
-There will be a new enum called 'PathfindaxCollisionCategory'. This is a flag enum that is a copy of the duality 'CollisionCategory' flag enum.
-The path request class should have a extra variable added for this new enum.
-There will be a new object called 'NodeConnection' which will have a node object and a variable of type 'PathfindaxCollisionCategory' called CollidesWith for the collisions.
-The pathfinding algorithm has to be modified to take this into account. This can be done by checking for any intersection between the PathfindaxCollisionCategory of the request and the CollidesWith flag enum in the NodeConnection object.
-The visualization of the nodes should be changed too to reflect this.
-This also means that the ISourceNodeNetworkProvider interface will no longer be returning a list of nodenetworks but just a single one.
Currently there is a PathRequest object to request a path and a pathcompleted object for when a path is completed. These could be merged into a single object which would also make it easier to provide a Status property for a user who would like to poll if a path is finished already or not.
Add hierarchical pathfinding to the framework. This will be a optional feature that is not required. A more detailed description can be found here: http://aigamedev.com/open/review/near-optimal-hierarchical-pathfinding/. This would be implemented in the Pathfinder.Process method.
A huge performance boost can be achieved at the cost of losing path optimality.
The source node network will be responsible for creating the less detailed node arrays. The Pathprocesser has to be modified to support this aswell and implement the hierarchical algorithm. These should all be optional.
Currently every time a new path has been solved amongst other objects a new maxheap is created and allocated. It might be better to reuse a already created object here to avoid having to reallocate memory every time and reduce the GC pressure.
Separate the code to visualize paths and node networks into separate components
The current tilemap node generation code is quite messy and hard to read. While rewriting this the following functionality could be added:
Instead of using references consider using a int to reference a item in an array in the maxheap.
Nodes should have a flat cost that will make it 'costlier' to traverse by adding it to the GCost.
The pathfinding algorithm should take this into account when finding the shortest path.
This will allow agents to avoid parts of the map that will be hard to traverse (like a swamp area, jungle etc) and try stick to parts of the map that are easier to traverse (like roads).
The hashset can be replaced with an array lookup. Use a byte here so it can be easily cleared by upping a 'generation' variable instead of zeroing the entire array. This will be much faster than a hashset and use less memory.
Implement flow and potential field pathfinding. The flowfield should be created by using the potential field.
Both:
PotentiaField:
FlowField:
There are several private fields used in pathfindax duality components that are currently being serialized. This is not needed and can even cause nasty bugs. Add a [DontSerialize] attribute to these fields.
Change the node classes to structs and use the new maxheap as the old one did not supported structs. This will use less memory and can lead to better performance due to better memory locality.
It should be possible to convert a duality tilemap to a node grid that can be used for pathfinding
This will make it much easier to use the Pathfinder with tilemap based games
Add overloads for float, Vector2 and Vector3 as start and end position.
Change NodeConnection to use a int index to point to the node instead of a reference to the node.
There is no need to store a reference to the node itself as you could look this up in the nodearray if you have the index. This index is the same for both sourcenodes and the nodes that are used on each thread.
By using rectangular symmetry reduction one can achieve a speedup of a order of magnitude without sacrificing path optimality. This requires some preprocessing and some memory overhead in order to generate and store the 'rectangular node groups'. However the memory overhead could be offset by the fact its possible to move the clearances to these groups so its no longer needed to store them per node.
The basic idea is to group nodes which have the same clearances (and later on weights) together in a group. We know this group has a rectangular shape and thus we only need to expand from the nodes at the border of the rectangle. This is the part that gives a huge speed boost since alot of nodes are pruned and do not have to be inserted into the heap during the search. Especially in maps with large open areas the speed boost could be more than a order of magnitude.
https://harablog.wordpress.com/2011/09/01/rectangular-symmetry-reduction/#4
Nodenetworks shouldnt be serialized by default by duality due to the amount of data involved and the fact they are currently generated from other data. Add surrogates that will prevent serializing them.
Currently there is a clearance float for this but it's unused. The Pathfinder should be able to take the agents size into account.
This could be implemented by adding a list of clearances per node with a clearance value and a collisionmask. The clearance will be the true clearance which can be found here: https://aigamedev.com/open/tutorials/clearance-based-pathfinding/. This will all be precalculated.
The exact clearance will be calculated at runtime by getting all the clearances that have a collision with the collisionlayer provided and then taking the smallest one.
This should provide a balance between memory usage and cpu usage as its not practical to store all possible combinations of clearances and collisionlayers beforehand.
There are cases in which you want to wait synchronously till the path is completed. Currently the PathRequest class does not support this out of the box. Exposing a WaitHandle which is set when the path is finished would make this a lot easier and even make it possible to wait for multiple PathRequests.
-Usually unit tests have to wait till the PathRequest is finished
-There can be cases in which a user desires to wait till a PathRequest is finished
Visual studio 2017 seems to have broken the sandcastle documentation. This might be because visual studio 2017 targets v75 instead of v111 for PCL's and something weird is going on here atm.
Documentation project does not build
Replace the current imperative way of rendering with a model based way. This should allow most logic to be moved to the core library and make it easier to test while at the same time reducing code duplication.
Currently its possible to specify a agent size. This is then used in the pathfinder to prevent calculating a path that goes through nodes with not enough clearance.
However currently its up to the end user to supply the correct offset. The pathfinder itself should manage this.
There should be a tutorial how to use pathfindax with the duality tilemaps
The MaxHeap plays a major role in the performance of the pathfinding algorithms as its used as a priority queue. Some micro benchmarking has shown that storing the result of a property in a local variable can significantly increase performance of the MaxHeap. The compiler probably cannot guarantee the values of the properties do not change and thus cannot optimize them properly.
See if there are any redundant property accesses and optimize these away. Microbenchmarks already have shown significant improvement so measure the result by measuring the performance gains in the pathfind algorithms.
Currently pathfinding uses the same nodenetwork to do the pathfinding for all collision layers. Change this to a separate nodenetwork for each collision layer.
Add a benchmark project that can run benchmarks with benchmarkdotnet
Add a unit test that checks if a zeroed out potential field returns zero vectors. If this is not the case fix this.
Currently version 2.9.8.0 of duality is used but the latest version is 2.13.3 already. Other packages can be updated as well.
It should be possible to add multiple callbacks to the PathRequest which will all be called when the PathRequest is finished. If its already finished the callback can be called immediately.
-Allows users to call multiple methods
Add unit tests for the following functionality:
The following things need better error messages:
TilemapNodeGridGenerator needs to provide a proper warning when it cannot find a tilemap.
PathfinderProxy needs to provide a warning if it cannot find a pathfinder.
The functionality of the GridTransformer class should be splitted into 2 classes:
-A Transformer class that simply transforms a position to local or world space
-A GridTransformer class that inherits from Transformer and adds grid related transformations to this.
Lastly add unit tests that check if these classes behave properly.
The compiler does not use generic type inference in constructors. When using a normal method the compiler will try to use inference to figure out the generic types. Create a factory class with a static method to create the following types:
-NodeConnection
-MultithreadedPathfinder
Currently the offset and scale is not properly calculated for the tilemap
Currently there is a foreach loop in which the workers are checked if they are busy or not. If not it will give them new work to do. When the queue is empty the thread will already wait for new work.
However when there is work and all workers are busy it will keep checking them constantly which eats alot of cpu. The thread should also wait if all workers are busy.
There is no check if the provided x is valid on the 2 dimensional indexer.
Also add unit tests for this.
Currently when no path is found the pathrequest status is set to Solved while this should be NoPathFound. This is because the dijkstra algorithm that runs over the graph always succeeds unless the target node is not traversible. A additional check is needed that checks if the potential field has a non zero heading for the startposition.
This class is no longer used
Add a example of using pathfindax in a console application. The goal is to help make ppl understand better what pathfindax is doing.
While at it this would also be a opportunity to see if there are any easy usability improvements.
Currently DynamicPotentialField is updated completely on the mainthread. This is done in the following way:
So currently the work that has to be done scales both with gridsize and the amount of agents/complexity of the PotentialFunctions. Without separate threads this could be improved in the following ways:
If this is not enough a final change would be doing most of the work in a separate thread. This way there is no longer a hard 16ms frametime restriction. Broadly speaking this could be achieved in the following way:
Using this approach the work on the mainthread will only scale with the amount of agents and most of that work might already be done in a precalculation.
Tilemapnodemapgenerator currently only looks at children gameobjects when searching for tilemaps. Make it also look at the current gameobject so that it will work with single layer tilemaps as well without having to add another parent gameobject.
Currently the node model is not compatible with the duality tilemap. It should be possible to manually define the neighbours.
The INode interface will expose a IList of INode called Neighbours so it can be modified. These must also be generic so it's possible to use different kind of nodes. This is needed for the duality tilemap integration.
While we are modifying the node model anyway. There will also be a new interface called IGridNode. This interface implements the INode interface and the GridX and GridY variables will move to this interface. This will make the base INode interface not have a dependency on the concept of a grid.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.