コード例 #1
0
        /// <summary>
        /// Returns the closest point on the navmesh (UNTESTED! EXPERIMENTAL! WILL GO SUPERNOVA ON USE! MAYBE!?)
        /// </summary>
        public Task <Vector3?> GetClosestPointAsync(Zone zone, Vector3 position, float xRange = 256f, float yRange = 256f, float zRange = 256f)
        {
            if (!_navmeshPtrs.ContainsKey(zone.ClientID))
            {
                return(Task.FromResult <Vector3?>(position)); // Assume the point is safe if we don't have a navmesh
            }
            GSStatistics.Paths.Inc();

            return(Task.Factory.StartNew(() =>
            {
                var ptrs = _navmeshPtrs[zone.ClientID];
                var center = (position + Vector3.zAxis * 8).ToRecastFloats();
                var outVec = new float[3];

                var defaultInclude = (dtPolyFlags.ALL ^ dtPolyFlags.DISABLED);
                var defaultExclude = (dtPolyFlags)0;
                var filter = new dtPolyFlags[] { defaultInclude, defaultExclude };

                var polyPickEx = new Vector3(xRange, yRange, zRange).ToRecastFloats();

                var status = FindClosestPoint(ptrs[1], center, polyPickEx, filter, outVec);

                if ((status & dtStatus.DT_SUCCESS) == 0)
                {
                    return (Vector3?)null;
                }

                return new Vector3(outVec[0] * INV_FACTOR, outVec[2] * INV_FACTOR, outVec[1] * INV_FACTOR);
            }, TaskCreationOptions.LongRunning));
        }
コード例 #2
0
        /// <summary>
        /// Returns a path that prevents collisions with the navmesh, but floats freely otherwise
        /// </summary>
        /// <param name="zone"></param>
        /// <param name="start">Start in GlobalXYZ</param>
        /// <param name="end">End in GlobalXYZ</param>
        /// <returns></returns>
        public static PathPoint[] GetPathStraight(Zone2 zone, Vector3 start, Vector3 end, dtPolyFlags includeFilter = dtPolyFlags.ALL ^ dtPolyFlags.DISABLED, dtPolyFlags excludeFilter = 0, float polyExtX = 64.0f, float polyExtY = 64.0f, float polyExtZ = 256.0f, dtStraightPathOptions options = dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(null);
            }

            var ptrs        = _loadedZones[zone.ID];
            var startFloats = (start + zAxis * 8).ToRecastFloats();
            var endFloats   = (end + zAxis * 8).ToRecastFloats();

            var numNodes = 0;
            var buffer   = new float[MAX_POLY * 3];
            var flags    = new dtPolyFlags[MAX_POLY];
            var filter   = new[] { includeFilter, excludeFilter };

            PathStraight(ptrs.queryPtr, startFloats, endFloats, new Vector3(polyExtX, polyExtY, polyExtZ).ToRecastFloats(), filter, options, ref numNodes, buffer, flags);

            var points    = new PathPoint[numNodes];
            var positions = Vector3ArrayFromRecastFloats(buffer, numNodes);

            for (var i = 0; i < numNodes; i++)
            {
                points[i].Position = positions[i];
                points[i].Flags    = flags[i];
            }

            return(points);
        }
コード例 #3
0
        /// <summary>
        /// Returns a random point on the navmesh around the given position
        /// </summary>
        /// <param name="zone">Zone</param>
        /// <param name="position">Start in GlobalXYZ</param>
        /// <param name="radius">End in GlobalXYZ</param>
        /// <returns>null if no point found, Vector3 with point otherwise</returns>
        public async Task <Vector3?> GetRandomPointAsync(Zone zone, Vector3 position, float radius)
        {
            if (!_navmeshPtrs.ContainsKey(zone.ClientID))
            {
                return(null);
            }

            GSStatistics.Paths.Inc();

            return(await Task.Factory.StartNew(() =>
            {
                var ptrs = _navmeshPtrs[zone.ClientID];
                var center = (position + Vector3.zAxis * 8).ToRecastFloats();
                var cradius = (radius *CONVERSION_FACTOR);
                var outVec = new float[3];

                var defaultInclude = (dtPolyFlags.ALL ^ dtPolyFlags.DISABLED);
                var defaultExclude = (dtPolyFlags)0;
                var filter = new dtPolyFlags[] { defaultInclude, defaultExclude };

                var polyPickEx = new float[3] {
                    2.0f, 4.0f, 2.0f
                };

                var status = FindRandomPointAroundCircle(ptrs[1], center, cradius, polyPickEx, filter, outVec);

                if ((status & dtStatus.DT_SUCCESS) == 0)
                {
                    return (Vector3?)null;
                }

                return new Vector3(outVec[0] * INV_FACTOR, outVec[2] * INV_FACTOR, outVec[1] * INV_FACTOR);
            }, TaskCreationOptions.LongRunning));
        }
コード例 #4
0
        public static bool SetPolyFlags(Zone2 zone, uint polyRef, dtPolyFlags flags)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(false);
            }

            var ptrs   = _loadedZones[zone.ID];
            var status = SetPolyFlags(ptrs.meshPtr, polyRef, flags);

            if ((status & dtStatus.DT_FAILURE) == dtStatus.DT_FAILURE)
            {
                return(false);
            }
            return(true);
        }
コード例 #5
0
        public static bool GetPolyAt(Zone2 zone, Vector3 center, Vector3 extents, dtPolyFlags includeFilter, dtPolyFlags excludeFilter, ref uint polyRef, ref Vector3 point)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(false);
            }

            float[] outPoint = new float[3];

            var ptrs   = _loadedZones[zone.ID];
            var status = GetPolyAt(ptrs.queryPtr, center.ToRecastFloats(), extents.ToRecastFloats(), new dtPolyFlags[] { includeFilter, excludeFilter }, ref polyRef, outPoint);

            point = new Vector3(outPoint[0] * INV_FACTOR, outPoint[2] * INV_FACTOR, outPoint[1] * INV_FACTOR);
            if ((status & dtStatus.DT_FAILURE) == dtStatus.DT_FAILURE)
            {
                return(false);
            }
            return(true);
        }
コード例 #6
0
        /// <summary>
        /// Returns the closest point on the navmesh (UNTESTED! EXPERIMENTAL! WILL GO SUPERNOVA ON USE! MAYBE!?)
        /// </summary>
        public static Vector3?GetClosestPoint(Zone2 zone, Vector3 position, float xRange = 256f, float yRange = 256f, float zRange = 256f)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(position);
            }

            var ptrs   = _loadedZones[zone.ID];
            var center = (position + zAxis * 8).ToRecastFloats();
            var outVec = new float[3];

            var defaultInclude = (dtPolyFlags.ALL ^ dtPolyFlags.DISABLED);
            var defaultExclude = (dtPolyFlags)0;
            var filter         = new dtPolyFlags[] { defaultInclude, defaultExclude };

            var polyPickEx = new Vector3(xRange, yRange, zRange).ToRecastFloats();

            FindClosestPoint(ptrs.queryPtr, center, polyPickEx, filter, outVec);

            var result = new Vector3(outVec[0] * INV_FACTOR, outVec[2] * INV_FACTOR, outVec[1] * INV_FACTOR);

            return(result == Vector3.Zero ? null : (Vector3?)result);
        }
コード例 #7
0
        /// <summary>
        /// Returns a random point on the navmesh around the given position
        /// </summary>
        /// <param name="zone">Zone</param>
        /// <param name="position">Start in GlobalXYZ</param>
        /// <param name="radius">End in GlobalXYZ</param>
        /// <returns></returns>
        public static Vector3 GetRandomPoint(Zone2 zone, Vector3 position, float radius)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(Vector3.Zero);
            }

            var ptrs    = _loadedZones[zone.ID];
            var center  = (position + zAxis * 8).ToRecastFloats();
            var cradius = (radius * CONVERSION_FACTOR);
            var outVec  = new float[3];

            var defaultInclude = (dtPolyFlags.ALL ^ dtPolyFlags.DISABLED);
            var defaultExclude = (dtPolyFlags)0;
            var filter         = new dtPolyFlags[] { defaultInclude, defaultExclude };

            var polyPickEx = new float[3] {
                2.0f, 4.0f, 2.0f
            };

            FindRandomPointAroundCircle(ptrs.queryPtr, center, cradius, polyPickEx, filter, outVec);

            return(new Vector3(outVec[0] * INV_FACTOR, outVec[2] * INV_FACTOR, outVec[1] * INV_FACTOR));
        }
コード例 #8
0
        /// <summary>
        /// Returns a path that prevents collisions with the navmesh, but floats freely otherwise
        /// </summary>
        /// <param name="zone"></param>
        /// <param name="start">Start in GlobalXYZ</param>
        /// <param name="end">End in GlobalXYZ</param>
        /// <returns></returns>
        public async Task <WrappedPathingResult> GetPathStraightAsync(Zone zone, Vector3 start, Vector3 end)
        {
            if (!_navmeshPtrs.ContainsKey(zone.ClientID))
            {
                return new WrappedPathingResult {
                           Error  = PathingError.NoPathFound,
                           Points = null,
                }
            }
            ;
            GSStatistics.Paths.Inc();

            return(await Task.Factory.StartNew(() =>
            {
                var ptrs = _navmeshPtrs[zone.ClientID];
                var startFloats = (start + Vector3.zAxis * 8).ToRecastFloats();
                var endFloats = (end + Vector3.zAxis * 8).ToRecastFloats();

                var numNodes = 0;
                var buffer = new float[MAX_POLY * 3];
                var flags = new dtPolyFlags[MAX_POLY];
                dtPolyFlags includeFilter = dtPolyFlags.ALL ^ dtPolyFlags.DISABLED;
                dtPolyFlags excludeFilter = 0;
                float polyExtX = 64.0f;
                float polyExtY = 64.0f;
                float polyExtZ = 256.0f;
                dtStraightPathOptions options = dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS;
                var filter = new[] { includeFilter, excludeFilter };
                var status = PathStraight(ptrs[1], startFloats, endFloats,
                                          new Vector3(polyExtX, polyExtY, polyExtZ).ToRecastFloats(), filter, options, ref numNodes, buffer, flags);
                if ((status & dtStatus.DT_SUCCESS) == 0)
                {
                    return new WrappedPathingResult
                    {
                        Error = PathingError.NoPathFound,
                        Points = null,
                    };
                }

                var points = new WrappedPathPoint[numNodes];
                var positions = Vector3ArrayFromRecastFloats(buffer, numNodes);

                for (var i = 0; i < numNodes; i++)
                {
                    points[i].Position = positions[i];
                    points[i].Flags = flags[i];
                }

                ImprovePath(zone, points);

                if ((status & dtStatus.DT_PARTIAL_RESULT) == 0)
                {
                    return new WrappedPathingResult
                    {
                        Error = PathingError.PathFound,
                        Points = points,
                    };
                }
                else
                {
                    return new WrappedPathingResult
                    {
                        Error = PathingError.PartialPathFound,
                        Points = points,
                    };
                }
            }, TaskCreationOptions.LongRunning));
        }
コード例 #9
0
        public override async Task <PathingResponse> GetPathStraight(PathingRequest request, ServerCallContext context)
        {
            // NOTE: Consider using GetPathStreamed instead
            Navmesh mesh;

            if (!Navmeshes.TryGetValue(request.Navmesh, out mesh))
            {
                Metrics.QPSByResult["NavmeshUnavailable"].Increment();
                return(new PathingResponse {
                    ResultCode = PathingResult.NavmeshUnavailable
                });
            }
            var onDequeue = Metrics.Record("Path", request.Navmesh);

            return(await Task.Factory.StartNew(() => {
                lock (mesh) {
                    onDequeue();
                    var startFloats = ToRecastFloats(request.StartingPoint.X, request.StartingPoint.Y, request.StartingPoint.Z + 8);
                    var endFloats = ToRecastFloats(request.DestinationPoint.X, request.DestinationPoint.Y,
                                                   request.DestinationPoint.Z + 8);

                    var numNodes = 0;
                    var buffer = new float[MAX_POLY * 3];
                    var flags = new dtPolyFlags[MAX_POLY];
                    var includeFilter = dtPolyFlags.ALL ^ dtPolyFlags.DISABLED;
                    var excludeFilter = (dtPolyFlags)0;
                    var filter = new[] { includeFilter, excludeFilter };
                    var polyExt = ToRecastFloats(64f, 64f, 256f);
                    var options = dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS;

                    var status = PathStraight(mesh.QueryPtr, startFloats, endFloats, polyExt, filter, options, ref numNodes, buffer, flags);
                    if ((status & dtStatus.DT_SUCCESS) == 0)
                    {
                        Metrics.QPSByResult["NoPathFound"].Increment();
                        return new PathingResponse {
                            ResultCode = PathingResult.NoPathFound
                        };
                    }

                    var points = new PathPoint[numNodes];
                    var positions = Vector3ArrayFromRecastFloats(buffer, numNodes);

                    for (var i = 0; i < numNodes; i++)
                    {
                        points[i] = new PathPoint {
                            Flags = (uint)flags[i], Position = positions[i]
                        };
                    }

                    if ((status & dtStatus.DT_PARTIAL_RESULT) == 0)
                    {
                        Metrics.QPSByResult["PathFound"].Increment();
                        return new PathingResponse {
                            ResultCode = PathingResult.PathFound,
                            Path = { points }
                        };
                    }
                    Metrics.QPSByResult["PartialPathFound"].Increment();
                    return new PathingResponse {
                        ResultCode = PathingResult.PartialPathFound,
                        Path = { points }
                    };
                }
            }, TaskCreationOptions.LongRunning));
        }
コード例 #10
0
        private unsafe PathingResponse GetPathForStreaming(PathingRequest request)
        {
            Navmesh mesh;

            if (!Navmeshes.TryGetValue(request.Navmesh, out mesh))
            {
                Metrics.QPSByResult["NavmeshUnavailable"].Increment();
                return(new PathingResponse()
                {
                    SequenceID = request.SequenceID,
                    ResultCode = PathingResult.NavmeshUnavailable,
                });
            }
            var onDequeue = Metrics.Record("PathStreamed", request.Navmesh);

            lock (mesh)
            {
                onDequeue();
                var startFloats = ToRecastFloats(request.StartingPoint.X, request.StartingPoint.Y, request.StartingPoint.Z + 8);
                var endFloats   = ToRecastFloats(request.DestinationPoint.X, request.DestinationPoint.Y,
                                                 request.DestinationPoint.Z + 8);

                var numNodes      = 0;
                var buffer        = new float[MAX_POLY * 3];
                var flags         = new dtPolyFlags[MAX_POLY];
                var includeFilter = dtPolyFlags.ALL ^ dtPolyFlags.DISABLED;
                var excludeFilter = (dtPolyFlags)0;
                var filter        = new[] { includeFilter, excludeFilter };
                var polyExt       = ToRecastFloats(64f, 64f, 256f);
                var options       = dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS;

                var status = PathStraight(mesh.QueryPtr, startFloats, endFloats, polyExt, filter, options, ref numNodes, buffer, flags);
                if ((status & dtStatus.DT_SUCCESS) == 0)
                {
                    Metrics.QPSByResult["NoPathFound"].Increment();
                    return(new PathingResponse()
                    {
                        SequenceID = request.SequenceID,
                        ResultCode = PathingResult.NoPathFound,
                    });
                }


                var code = PathingResult.PathFound;
                if ((status & dtStatus.DT_PARTIAL_RESULT) != 0)
                {
                    Metrics.QPSByResult["PartialPathFound"].Increment();
                    code = PathingResult.PartialPathFound;
                }
                else
                {
                    Metrics.QPSByResult["PathFound"].Increment();
                }

                // Create nodes
                var    positions     = Vector3ArrayFromRecastFloats(buffer, numNodes);
                var    oneStructSize = Marshal.SizeOf <PathPointStruct>();
                var    oneStruct     = Marshal.AllocHGlobal(oneStructSize);
                byte[] buf           = new byte[oneStructSize * numNodes];
                for (int i = 0; i < numNodes; i++)
                {
                    var vec = positions[i];
                    var pp  = new PathPointStruct {
                        Flags = flags[i],
                        X     = (float)vec.X,
                        Y     = (float)vec.Y,
                        Z     = (float)vec.Z,
                    };
                    Marshal.StructureToPtr(pp, oneStruct, false);
                    Marshal.Copy(oneStruct, buf, i * oneStructSize, oneStructSize);
                }

                return(new PathingResponse()
                {
                    SequenceID = request.SequenceID,
                    PathNodes = (uint)numNodes,
                    ResultCode = code,
                    SerializedNodes = ByteString.CopyFrom(buf, 0, buf.Length)
                });
            }
        }
コード例 #11
0
ファイル: LocalPathingMgr.cs プロジェクト: JVirant/DOLSharp
 private static extern dtStatus SetPolyFlags(IntPtr meshPtr, uint polyRef, dtPolyFlags flags);
コード例 #12
0
        public static bool QueryPolygons(Zone2 zone, Vector3 center, Vector3 polyPickExt, dtPolyFlags includeFlags, dtPolyFlags excludeFlags, ref uint[] results, int maxResults = 32)
        {
            if (!_loadedZones.ContainsKey(zone.ID))
            {
                return(false);
            }

            var resultIdBuffer = new uint[maxResults];
            var resultCount    = 0;

            var ptrs   = _loadedZones[zone.ID];
            var status = QueryPolygons(ptrs.queryPtr, center.ToRecastFloats(), polyPickExt.ToRecastFloats(), new dtPolyFlags[] { includeFlags, excludeFlags }, resultIdBuffer, ref resultCount, maxResults);

            if ((status & dtStatus.DT_FAILURE) == dtStatus.DT_FAILURE)
            {
                return(false);
            }

            results = new uint[resultCount];
            Array.Copy(resultIdBuffer, results, resultCount);

            return(true);
        }