示例#1
0
        public override async Task <GetRandomPointResponse> GetRandomPoint(GetRandomPointRequest request, ServerCallContext context)
        {
            Navmesh mesh;

            if (!Navmeshes.TryGetValue(request.Navmesh, out mesh))
            {
                Metrics.QPSByResult["NavmeshUnavailable"].Increment();
                return(new GetRandomPointResponse());
            }

            var onDequeue = Metrics.Record("RandomPoint", request.Navmesh);

            return(await Task.Factory.StartNew(() => {
                lock (mesh) {
                    onDequeue();
                    var center = ToRecastFloats(request.Position.X, request.Position.Y, request.Position.Z + 8);
                    var cradius = request.Radius *CONVERSION_FACTOR;
                    var outVec = new float[3];

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

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

                    var status = FindRandomPointAroundCircle(mesh.QueryPtr, center, cradius, polyPickEx, filter, outVec, () => (float)mesh.Random.NextDouble());

                    if ((status & dtStatus.DT_SUCCESS) == 0)
                    {
                        Metrics.QPSByResult["NoRandomPointFound"].Increment();
                        return new GetRandomPointResponse();
                    }

                    Metrics.QPSByResult["RandomPointFound"].Increment();
                    return new GetRandomPointResponse {
                        Point = new Vec3 {
                            X = outVec[0] * INV_FACTOR, Y = outVec[2] * INV_FACTOR, Z = outVec[1] * INV_FACTOR
                        }
                    };
                }
            }, TaskCreationOptions.LongRunning));
        }
示例#2
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));
        }
示例#3
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)
                });
            }
        }