static bool getSteerTarget(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos, float minTargetDist, dtPolyRef[] path, int pathSize, float[] steerPos, ref byte steerPosFlag, ref dtPolyRef steerPosRef, ref float[] outPoints, ref int outPointCount) { // Find steer target. const int MAX_STEER_POINTS = 3; float[] steerPath = new float[MAX_STEER_POINTS * 3]; byte[] steerPathFlags = new byte[MAX_STEER_POINTS]; dtPolyRef[] steerPathPolys = new dtPolyRef[MAX_STEER_POINTS]; int nsteerPath = 0; navQuery.findStraightPath(startPos, endPos, path, pathSize, steerPath, steerPathFlags, steerPathPolys, ref nsteerPath, MAX_STEER_POINTS, 0); if (nsteerPath == 0) { return(false); } //if (outPoints && outPointCount) //{ outPointCount = nsteerPath; for (int i = 0; i < nsteerPath; ++i) { Detour.dtVcopy(outPoints, i * 3, steerPath, i * 3); } //} // Find vertex far enough to steer to. int ns = 0; while (ns < nsteerPath) { // Stop at Off-Mesh link or when point is further than slop away. if ((steerPathFlags[ns] & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 || !inRange(steerPath, ns * 3, startPos, 0, minTargetDist, 1000.0f)) { break; } ns++; } // Failed to find good point to steer to. if (ns >= nsteerPath) { return(false); } Detour.dtVcopy(steerPos, 0, steerPath, ns * 3); steerPos[1] = startPos[1]; steerPosFlag = steerPathFlags[ns]; steerPosRef = steerPathPolys[ns]; return(true); }
public static StraightPath ComputeStraightPath(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos, float distance = 10) { //m_ComputedPathType = PathType.Straight; StraightPath path = new StraightPath(); float[] extents = new float[3]; for (int i = 0; i < 3; ++i) { extents[i] = distance; } dtPolyRef startRef = 0; dtPolyRef endRef = 0; float[] startPt = new float[3]; float[] endPt = new float[3]; Detour.dtQueryFilter filter = new Detour.dtQueryFilter(); navQuery.findNearestPoly(startPos, extents, filter, ref startRef, ref startPt); navQuery.findNearestPoly(endPos, extents, filter, ref endRef, ref endPt); int pathCount = -1; navQuery.findPath(startRef, endRef, startPt, endPt, filter, path.m_RawPathPolys, ref pathCount, StraightPath.MAX_POLYS); path.m_RawPathLength = pathCount; if (pathCount > 0) { // In case of partial path, make sure the end point is clamped to the last polygon. float[] epos = new float[3]; Detour.dtVcopy(epos, endPt); if (path.m_RawPathPolys[pathCount - 1] != endRef) { bool posOverPoly = false; navQuery.closestPointOnPoly(path.m_RawPathPolys[pathCount - 1], endPt, epos, ref posOverPoly); } navQuery.findStraightPath(startPt, endPt, path.m_RawPathPolys, pathCount, path.m_straightPath, path.m_straightPathFlags, path.m_straightPathPolys, ref path.m_straightPathCount, StraightPath.MAX_POLYS, path.m_straightPathOptions); } return(path); }
public Queue <Position> FindPathBetween(Position start, Position end, bool useStraightPath = false) { var path = new Queue <Position>(); if (dtNavMesh == null) { return(path); } var startDetourPosition = start.ToDetourPosition(); var endDetourPosition = end.ToDetourPosition(); var queryFilter = new Detour.dtQueryFilter(); var navMeshQuery = new Detour.dtNavMeshQuery(); var status = navMeshQuery.init(dtNavMesh, MAX_PATH); if (Detour.dtStatusFailed(status)) { return(path); } queryFilter.setIncludeFlags(0xffff); queryFilter.setExcludeFlags(0x0); uint startRef = 0; uint endRef = 0; float[] startNearest = new float[3]; float[] endNearest = new float[3]; float[] extents = new float[] { 10.0F, 25.0F, 10.0F }; status = navMeshQuery.findNearestPoly(startDetourPosition, extents, queryFilter, ref startRef, ref startNearest); if (Detour.dtStatusFailed(status)) { return(path); } status = navMeshQuery.findNearestPoly(endDetourPosition, extents, queryFilter, ref endRef, ref endNearest); if (Detour.dtStatusFailed(status)) { return(path); } if (!dtNavMesh.isValidPolyRef(startRef) || !dtNavMesh.isValidPolyRef(endRef)) { return(path); } uint[] pathPolys = new uint[MAX_PATH]; int pathCount = 0; float[] straightPath = new float[MAX_PATH * 3]; byte[] straightPathFlags = new byte[MAX_PATH]; uint[] straightPathPolys = new uint[MAX_PATH]; int straightPathCount = 0; status = navMeshQuery.findPath( startRef, endRef, startNearest, endNearest, queryFilter, pathPolys, ref pathCount, MAX_PATH ); if (Detour.dtStatusFailed(status)) { path.Enqueue(start); path.Enqueue(end); return(path); } status = navMeshQuery.findStraightPath( startNearest, endNearest, pathPolys, pathCount, straightPath, straightPathFlags, straightPathPolys, ref straightPathCount, MAX_PATH, (int)Detour.dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS ); if (Detour.dtStatusFailed(status)) { path.Enqueue(start); path.Enqueue(end); return(path); } if (straightPathCount > 0) { if (Detour.dtStatusFailed(status)) { return(path); } for (int i = 3; i < straightPathCount * 3;) { float[] pathPos = new float[3]; pathPos[0] = straightPath[i++]; pathPos[1] = straightPath[i++]; pathPos[2] = straightPath[i++]; var position = ToFFXIPosition(pathPos); path.Enqueue(position); } } else { for (int i = 1; i < pathCount; i++) { float[] pathPos = new float[3]; bool posOverPoly = false; if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPoly(pathPolys[i], startDetourPosition, pathPos, ref posOverPoly))) { return(path); } if (path.Count < 1) { if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPolyBoundary(pathPolys[i], startDetourPosition, pathPos))) { return(path); } } var position = ToFFXIPosition(pathPos); path.Enqueue(position); } } if (path.Count < 1) { path.Enqueue(end); } return(path); }
public Queue <Position> FindPathBetween(Position start, Position end, bool useStraightPath = false) { var path = new Queue <Position>(); if (dtNavMesh == null) { EasyFarm.ViewModels.LogViewModel.Write("FindPathBetween: Unable to path due to lacking navigation mesh for zone " + _zone.ToString()); return(path); } var startDetourPosition = start.ToDetourPosition(); var endDetourPosition = end.ToDetourPosition(); var queryFilter = new Detour.dtQueryFilter(); var navMeshQuery = new Detour.dtNavMeshQuery(); var status = navMeshQuery.init(dtNavMesh, 256); if (Detour.dtStatusFailed(status)) { return(path); } queryFilter.setIncludeFlags(0xffff); queryFilter.setExcludeFlags(0x0); uint startRef = 0; uint endRef = 0; float[] startNearest = new float[3]; float[] endNearest = new float[3]; float[] extents = new float[] { 10.0F, (float)EasyFarm.UserSettings.Config.Instance.HeightThreshold, 10.0F }; status = navMeshQuery.findNearestPoly(startDetourPosition, extents, queryFilter, ref startRef, ref startNearest); if (Detour.dtStatusFailed(status)) { return(path); } status = navMeshQuery.findNearestPoly(endDetourPosition, extents, queryFilter, ref endRef, ref endNearest); if (Detour.dtStatusFailed(status)) { return(path); } if (!dtNavMesh.isValidPolyRef(startRef) || !dtNavMesh.isValidPolyRef(endRef)) { return(path); } uint[] pathPolys = new uint[256]; int pathCount = 0; status = navMeshQuery.findPath(startRef, endRef, startNearest, endNearest, queryFilter, pathPolys, ref pathCount, 256); if (Detour.dtStatusFailed(status)) { return(path); } if (path.Count < 1) { float[] straightPath = new float[256 * 3]; byte[] straightPathFlags = new byte[256]; uint[] straightPathPolys = new uint[256]; int straightPathCount = 256 * 3; status = navMeshQuery.findStraightPath( startNearest, endNearest, pathPolys, pathCount, straightPath, straightPathFlags, straightPathPolys, ref straightPathCount, 256, 0 ); if (straightPathCount > 1) { if (Detour.dtStatusFailed(status)) { return(path); } path.Clear(); // i starts at 3 so the start position is ignored for (int i = 3; i < straightPathCount * 3;) { float[] pathPos = new float[3]; pathPos[0] = straightPath[i++]; pathPos[1] = straightPath[i++]; pathPos[2] = straightPath[i++]; var position = ToFFXIPosition(pathPos); path.Enqueue(position); } } } else { // i starts at 3 so the start position is ignored for (int i = 1; i < pathCount; i++) { float[] pathPos = new float[3]; bool posOverPoly = false; if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPoly(pathPolys[i], startDetourPosition, pathPos, ref posOverPoly))) { return(path); } if (path.Count < 1) { if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPolyBoundary(pathPolys[i], startDetourPosition, pathPos))) { return(path); } } var position = ToFFXIPosition(pathPos); path.Enqueue(position); } } return(path); }