-
-
Notifications
You must be signed in to change notification settings - Fork 583
Flowfield & collision avoidance #3078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
e16f113 to
b49ff83
Compare
7d22197 to
e45b9c4
Compare
|
Calculation of reciprocal N-body collision becomes pretty complicated for large number of units. Steering (boids) behaviors are very simple to implement but pretty painful to tweak. I've spent a ton of time for both during my small gamedev career. I would like to try continuum crowds. Maybe it will need some mixture with more "modern" tricks from D*/lifelong A* to keep only a part of flow/continuum field updated. Generally, I came here to try flowfield things, but surprisingly found your MR with most work already done. |
|
|
@dkargin I still have much work not pushed here, because I wasn't sure I am moving in right direction/ using right approach; and since you seem to have some real gamedev experience (which I don't), maybe worth get in touch? Sometimes it helps just to talk in order to clarify ideas. Obviously we ll post here every valuable conclusion. |
|
Another possible direction to solve dynamic collision avoidance problems, while maintaining reasonable performance, is Anytime Dynamic A*, which may be easier to integrate since it builds upon the existing A* framework. Although, I haven't done any in-depth analysis of how well this algorithm can perform compared to both flow fields or the existing solution, so it needs more thought and careful analysis to evaluate this solution against other previously proposed algorithms. |
|
Yet another way to solve traffic jams is to keep the current path finding, and give droids a way to push others away. I propose a model where each droid has a bounding circle. When 2 bounding circles overlap, a force is applied to both proportional to the distance of overlap. This pushing physics would require low friction over the ground however, but I think fun play >> realism. Structures could also be given radii, and we could mathematically think of them as having "infinite mass", aka, only apply the push-away force on the droid. To keep the feature where you can roadblock an enemy, perhaps apply more friction when the 2 droids are not the same alliance. Circle-circle overlap is very cheap, since you can cancel the square root on both sides when calculating euclidian distance, but it would still be O(n²). To make this collision detection scale well, a BVH could be used, or a quad tree (which would align nicely with the already built in grid, as a side effect it would provide a spatial index for units). That makes it scale O(nlog(n)). Such a structure takes no more than 100 lines of code. Another irritation is units that need to slowly turn to some direction before they start moving. I realize it's only barely related, but I also suggest getting rid of that as well, and doing the turn while moving. This is less realistic but would be way more fun to play as it solves a major point of "MOVE you stupid ####" frustration for me. |
replaces the (dead? I guess) PR: #1213, I don't have the rights to modify it anyway.
Compiles and merges cleanly with latest master.
(I only added logging, and fixed the debugDraw to use the right perspective matrix)
UPDATE, I am dumping what I came up to here so that I am not alone carrying those heavy thoughts:
Zoran Popović, 2 Electronic Arts" 1 .
If you read another suggested paper (Crowd Pathfinding and Steering using Flow Field tiles) 2 ,
out of 10 pages, only 1 (one) sentence on two lines briefly mentions dynamic obstacles. Not the best source for inspiration!
We need to combine globally optimal Flow field solution, to local solution to dynamic problem. Note, that because it's local, there is no way to ensure that droid will always take the correct path (which kinda mimics the real life: you can't know how far a wall goes unless you follow it). This is against what is described in the book 1 , as they do search for a global solution in even with dynamic obstacles. I don't think this limits us in any way, going from local solution to global is easy: just run cost-minimizing function over the full field.
Compute costs for flow field (at coarse grained resolution of 1 tile), but do not compute directions yet. Assume minimum cost is 4, not 1. This is for easier interpolation later. Flow field result can be cached, and they should be valid for targets of different radius. When a structure is built/destroyed it triggers recalculation of all flow fields for ground propulsions (DONE).
This can be optimized, somewhat easily, for ex by delaying re-computation of FF only to when a droid actually stumbles upon a new, unknown static obstacle.
But this optimization is only possible for newly built structures.
Another solution would be to delay re-computation by N logical ticks, so that we update only once per multipe structures built/destroyed.
Each logical tick, create a fresh, high resolution (1/16 of a tile, let's call it "cell": so that each tile is 4x4 cells) array. For each moving droid, populate high-resolution array with an area of discomfort in the approximate direction the unit is currently moving, (do not create a circle area around it, that make movement decision look pretty dumb: I tried it). Continuous direction (uint16_t) are sampled to fit into 8 predefined directions. (DONE)
For each moving droid, calculate the sum of comfort fields, and discomfort fields (so our flow field cost is a "discomfort"), but subtract the part of the droid itself (DONE). Notice that our flow field has lower resolution, so interpolate its cost (per tile) for each cell. (this is annoying and error prone, because interpolation is different for 8 discreet directions... IN PROGRESS)
Now, calculate the path N cells ahead, aka, choose the direction of least discomfort N times. I don't know yet how large N should be, I am thinking about between 1 (=one cell) and 8 (=2 full tiles) (TODO).
Now that we know what is the discreet path along high-resolution comfort field, interpolate the angles of all N calculated directions, so that we move Direction back to continuous values from discreet (EDIT: or use those points as control points in Bézier curve describing the path). This is crucial to make droid behave naturally, otherwise they abruptly change their movement vector on the seems between cells/tiles. Note that movement behaviors inherent to propulsions (like wheels making circles and hovers drifting around) should be prioritized over directions suggested by our "pathfinder+avoidance" logic: I think the directions obtained above should only be used to gently steer droids in the right direction, instead of assigning it directly (TODO) (EDIT: again, consider using Bézier curves)
Use (dis)comfort fields to create "activity zones" of different types: for ex, artificially increase comfort values around a building under constructions so that Trucks automatically choose the next closest possible emplacement, instead of being stuck behind each other; or add discomfort for droids with full health which are next to a repair station: this will automatically push them away; add more discomfort for areas known to be reachable by enemy fire so that low-health droids will avoid them, etc... (TODO)
If someone knows this stuff better, and/or sees some incoherence: please do leave a comment, I am not a bloody expert in robotics 💯