Robmaister / SharpNav

Advanced Pathfinding for C#
sharpnav.com
Other
537 stars 129 forks source link

Missing NavMeshQuery.FindNearestPoly, need functionality to find the closest ref of the specified point #9

Closed AqlaSolutions closed 10 years ago

AqlaSolutions commented 10 years ago

In the example you retrieve the start point ref like this: navMeshQuery.FindRandomPoint(ref startRef, ref startPos);

I can find a random point and its ref but I can't simple use a concrete point and find the closest point and ref.

Basically, I need a possibility to find the path from point A to point B, not from one random point to another...

Robmaister commented 10 years ago

Assigned to @xrj800

Should be implemented soon.

FreedomJack-X commented 10 years ago

Yep, I am working on it, but i find one function which occurred in findnearestpoint like queryPolygens didn’t implement, so I am trying to implement that firstly.

Renjie Xie On Feb 12, 2014, at 7:40 PM, Robert Rouhani notifications@github.com wrote:

Assigned to @xrj800

Should be implemented soon.

— Reply to this email directly or view it on GitHub.

Robmaister commented 10 years ago

Implemented in f087ae8. I looked over it (though I have yet to test it), seems to be good. There are some bugs in PolyMeshDetail I'm working through that may give you wrong height values in this step. I also made a few changes to the navigation API and will make several more in the next few weeks.

Just another warning that we're still in a development phase and the API shouldn't be considered stable yet.

I'll close this issue once either I test it or you confirm that it works.

FreedomJack-X commented 10 years ago

When I implement this function, it seems that the editor of C++ version is still modifying function now.

On Feb 19, 2014, at 2:33 PM, Robert Rouhani notifications@github.com wrote:

Implemented in f087ae8. I looked over it (though I have yet to test it), seems to be good. There are some bugs in PolyMeshDetail I'm working through that may give you wrong height values in this step. I also made a few changes to the navigation API and will make several more in the next few weeks.

Just another warning that we're still in a development phase and the API shouldn't be considered stable yet.

I'll close this issue once either I test it or you confirm that it works.

— Reply to this email directly or view it on GitHub.

AqlaSolutions commented 10 years ago

While I was checking it I've found that in the ClosestPointOnPoly you are directly assigning closest = pos and it returns the same point as input every time! After that you don't check the bool result of ClosestPointOnPoly at all (shouldn't you do "continue" if false?) Next: you are checking "if (nearestPt.Length() != 0) nearestPt = closestPtPoly;" - it returns (0, 0, 0) every time! And the "diff" is always (0,0,0) because ClosestPointOnPoly always returns the same point as input => it selects the resulting nearest point from the first poly. It doesn't work and it can't work...

Robmaister commented 10 years ago

That commit fixed a lot of small bugs from the method being ported over. Mostly a bit of confusion between checking whether a pointer isn't NULL vs. checking whether it's value is 0.

And the bool result of ClosestPointOnPoly should only return false in an exceptional state (at least at a quick glance). The method should probably return void instead of bool and throw exceptions, which is something I'll do when I have some free time (and also enhance the Examples project to let you click on positions you want to navigate between at the same time).

AqlaSolutions commented 10 years ago

Found a bug in FindNearestPoly: in case where QueryPolygons returns true but polys list is empty it returns inconsistent results.

AqlaSolutions commented 10 years ago

Query polygons doesn't find anything even if the input point have been taken from the poly itself with FindRandomPoint:

public class TestNav
{
        public void Test()
        {
            var navMeshQuery = new NavMeshQuery(_tiledNavMesh, 2048);

            SVector3 startPt = new SVector3();
            int startRef = 0;

            if (!navMeshQuery.FindRandomPoint(ref startRef, ref startPt))
                throw new CantFindPointOnPolyException();

            SVector3 endPt = new SVector3();
            int endRef = 0;

            if (!navMeshQuery.FindRandomPoint(ref endRef, ref endPt))
                throw new CantFindPointOnPolyException();

            FindPath(startPt, endPt);
        }

        public void FindPath(SVector3 from, SVector3 to)
        {
            var navMeshQuery = new NavMeshQuery(_tiledNavMesh, 2048);
            // !!! QueryPolygons inside returns empty list
            int startRef;
            SVector3 startPos;
            if (!GetClosestPoint(navMeshQuery, from, out startPos, out startRef))
                throw new CantFindPointOnPolyException();
            int endRef;
            SVector3 endPos;
            if (!GetClosestPoint(navMeshQuery, to, out endPos, out endRef))
                throw new CantFindPointOnPolyException();
        }

        static bool GetClosestPoint(NavMeshQuery navMeshQuery, SVector3 startPos, out SVector3 pt, out int ptRef)
        {
            var extents = new SVector3(5f, 5f, 5f);
            return navMeshQuery.FindNearestPoly(ref startPos, ref extents, out ptRef, out pt);
        }

        readonly TiledNavMesh _tiledNavMesh;
        public TestNav(TiledNavMesh tiledNavMesh) { _tiledNavMesh = tiledNavMesh; }
        public class CantFindPointOnPolyException : Exception { }
}
Robmaister commented 10 years ago

Fixed bug where QueryPolygons returns true if it doesn't find any polygons. Investigating it not finding a suitable poly.

Currently, if you provide a massive extends vector, it'll get you a poly within the extends box, but definitely not the nearest poly. Bug is narrowed down to QueryPolygonsInTile. If I can't figure it out tonight I'll look whenever I have some more free time.

Robmaister commented 10 years ago

Alright, it works for me now. In the Examples project, I replaced the randomly chosen start point and replaced it with the point nearest (10, 0, 0) with an extent of (5, 5, 5). You should be able to mess with those numbers and get a point as long as the bounds are within the level. It'll throw an exception a little bit further on if it can't find a start point, but that's another issue for another time, one that I'll likely fix through the design of the API.

Anyways, give it a whirl. I'll leave the issue open until you confirm it works for you.

Also, in case you were curious what the bug was, PolyMesh's vertices are stored in voxel units (they're supposed to be ushorts, but were kept as Vector3's in the port). I assumed that Vector3 meant it would be in world units. I re-added the quantization factor that converts world units to voxel units. Before, the comparison of bounding boxes was failing for all polys since the bounding volume tree is also in voxel units and the query bounding volume is in world units.

AqlaSolutions commented 10 years ago

I confirm, it works. Thanks =)