-
Posts
7 -
Joined
-
Last visited
Posts posted by chansey
-
-
I have reproduced the issue which Ykkrosh mentioned.
When the point precisely on the edge, we will get a very bad path.
I modify some code in previous patch.
It seems fixed now.
//------------Modified Begin//If this is an axis-aligned shape, discard non-silhouette points easily.if (vertexes[n].quadInward == QUADRANT_BL) if ((vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y > npos.Y) || (vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y < npos.Y)) continue; if (vertexes[n].quadInward == QUADRANT_TR) if ((vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y < npos.Y) || (vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y > npos.Y)) continue; if (vertexes[n].quadInward == QUADRANT_TL) if ((vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y < npos.Y) || (vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y > npos.Y)) continue; if (vertexes[n].quadInward == QUADRANT_BR) if ((vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y > npos.Y) || (vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y < npos.Y)) continue;//------------Modified End
- 1
-
a unit starts from slightly inside a shape or precisely on the edge, and the silhouette-point-detection thing will mean it doesn't see any of the points on that shape at all.
"silhouette-point-detection thing will mean it doesn't see any of the points"
why? Fixed point precision problem? (I have not stress test it yet.)
I think if it is a rare problem, can we do some dirty trick (eg: add some delta, if it is a precision problem?) and ensure most of time its behavior correct?
-
There is a little typo line 777 ontinue, instead of continue, apart from that you should come on IRC #0ad-dev.
OK, Thanks,
(But there is some time difference.... I will sleep )
-
After read short-range path source code deeply.
I found a small problem which maybe cause performance degradation.
The root cause is current algorithm can't discard non-silhouette points.
I also read some books.
In GPG2 "Optimizing Points-of-Visibility Pathfinding", it mentioned two optimizations:
"Optimization #1": Only Consider Paths to Silhouette Points
"Optimization #2": Only Consider Paths that Go Around the Corner
So "Optimization #1" may be what we are missing.
Implement "Optimization #1" is very easy, because there are axis-aligned box.I have written some code in CCmpPathfinder_Vertex.cpp
// Check that the new vertex is in the right quadrant for the old vertexif (!(vertexes[curr.id].quadOutward & quad)){ // Hack: Always head towards the goal if possible, to avoid missing it if it's // inside another unit if (n != GOAL_VERTEX_ID) { continue; }}//------------Modified Begin//If this is an axis-aligned shape, discard non-silhouette points easily.if (vertexes[n].quadInward == QUADRANT_BL) if ((vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y) || (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y)) continue;if (vertexes[n].quadInward == QUADRANT_TR) if ((vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y) || (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y)) continue;if (vertexes[n].quadInward == QUADRANT_TL) if ((vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y) || (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y)) continue;if (vertexes[n].quadInward == QUADRANT_BR) if ((vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y) || (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y)) continue;//------------Modified Endbool visible = CheckVisibilityLeft(vertexes[curr.id].p, npos, edgesLeft) && CheckVisibilityRight(vertexes[curr.id].p, npos, edgesRight) && CheckVisibilityBottom(vertexes[curr.id].p, npos, edgesBottom) && CheckVisibilityTop(vertexes[curr.id].p, npos, edgesTop) && CheckVisibility(vertexes[curr.id].p, npos, edges);
it seems faster than before.
Has anyone here could review this code?
Sorry for my broken english...- 1
-
but it needed integrating with the short-range pathfinder (which needed redesigning itself)
Thank Ykkrosh.
Following #1756, I found that the short path is also a new enhancement. (#1942)
It's a very great idea for short path performance improvement which make O(N^3) -> O(N^2) ! (http://www.wildfiregames.com/forum/index.php?showtopic=13042&&page=3#entry216735)
Has this feature been integrated into the current short-range pathfinder?
I am very sorry I have not deeply read current short path source code.
-
After researched 0 A.D's source code (excellent work!),
I have some confusion about long-range pathfinder's current implementation.In my understanding, each terrain tile should be split into 4x4 small cells for AStar. (This will make long path more accurately)
And when a unit start a longpath, all static obstruction's tiles (small cells) will be expanded by this unit's clearnce.Has this feature be implemented now?
I cant find any code about "obstruction's tile expanded by unit's clearnce in long path".I read the code:
CCmpPathfinder_Tile.cpp
void CCmpPathfinder::ComputePath(entity_pos_t x0, entity_pos_t z0, const Goal& goal, pass_class_t passClass, cost_class_t costClass, Path& path)
The params seem not to relate unit's raduis or clearnce.....and where to expand tiles?
Very thanks.
Discussion about: UnitAI (approaching and ranged unit's max range)
in Game Development & Technical Discussion
Posted · Edited by chansey
When a ranged unit attack a enemy, current UnitAI behavior is :
(1) Handle attack order
(2) CheckInRange. if enemy not in range, goto (3)
(3) MoveToTargetRange (min/max range)
(4) When move is completed, goto (2)
-------------------
My question is:
The MoveToTargetRange (especially max range!) is really useful to the ranged unit's approaching behavior?
I found some faults:
Situation 1:
There are two units (A and B, A is ranged unit whose max range is 20).
Let A attack B and B attack A.
You will find that A often approach B but overstep and then walk back.
It's only a bug and it could be fixed by adding some CheckInRange code in approaching timer.
Situation 2:
There are two units (A and B, A is ranged unit whose max range is 58).
A is on one the side of river, B is on the other side.
Now let A attack B and B flee A along the river bank.
You will find A will lost B. (A won't go across bridge...)
Is this behavior normally?
After some thought, I've come to some conclusion: (maybe wrong)
(1) The max range in approaching is only useful to the unit which has a very long range (eg: catapult) or target is a building.
(2) Archer should be look as melee and not use weapon range as motion's maxrange to approach.
It should use maxrange=0 approach and check its weapon range(maxrange) repeatly to decide attack.