/// <summary>
        /// Returns all events by tick range [from..to] (including from and to)
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        HistoryStorage IStatesHistoryModuleBase.GetHistoryStorage(Tick from, Tick to)
        {
            var list = PoolListCopyable <HistoryEvent> .Spawn(100);

            foreach (var data in this.events)
            {
                var tick = data.Key;
                if ((from != Tick.Invalid && tick < from) ||
                    (to != Tick.Invalid && tick > to))
                {
                    continue;
                }

                var values = data.Value.Values;
                for (int i = 0, cnt = values.Count; i < cnt; ++i)
                {
                    var evt = values[i];
                    if (evt.storeInHistory == true)
                    {
                        list.Add(evt);
                    }
                }
            }

            var storage = new HistoryStorage();

            storage.events = list.ToArray();
            PoolListCopyable <HistoryEvent> .Recycle(ref list);

            return(storage);
        }
        public static ListCopyable <Vector3> Bezier(ListCopyable <Vector3> points, int subdivisions = 2, float tangentLength = 0.5f)
        {
            subdivisions = Mathf.Max(subdivisions, 0);

            var segmentsCount = 1 << subdivisions;
            var outputPoints  = PoolListCopyable <Vector3> .Spawn(points.Count *segmentsCount + 1);

            for (int i = 0; i < points.Count - 1; i++)
            {
                var t1 = (points[i + 1] - points[i == 0 ? i : i - 1]) * tangentLength;
                var t2 = (points[i] - points[i == points.Count - 2 ? i + 1 : i + 2]) * tangentLength;

                var p0 = points[i];
                var p1 = p0 + t1;
                var p2 = points[i + 1];
                var p3 = p2 + t2;

                for (int j = 0; j < segmentsCount; j++)
                {
                    outputPoints.Add(CubicBezier(p0, p1, p3, p2, (float)j / segmentsCount));
                }
            }

            outputPoints.Add(points[points.Count - 1]);

            return(outputPoints);
        }
        public override void ApplyBeforeConnections(Graph graph)
        {
            var layer  = this.gameObject.layer;
            var bounds = this.bounds;

            bounds.center += this.transform.position;

            var nodes = PoolListCopyable <Node> .Spawn(10);

            graph.GetNodesInBounds(nodes, bounds);
            foreach (var node in nodes)
            {
                var ray = new Ray(node.worldPosition + Vector3.up * 10f, Vector3.down);
                if (Physics.Raycast(ray, out var hit, 1000f, this.layerMask) == true)
                {
                    if (hit.collider.gameObject.layer == layer)
                    {
                        var dt = this.penaltyDelta;
                        if (dt < 0)
                        {
                            node.penalty -= (uint)(-this.penaltyDelta);
                        }
                        else
                        {
                            node.penalty += (uint)this.penaltyDelta;
                        }

                        node.tag = this.tag;
                    }
                }
            }
            PoolListCopyable <Node> .Recycle(ref nodes);
        }
Exemple #4
0
        private ListCopyable <Node> RetracePath(int threadIndex, Node endNode)
        {
            var path = PoolListCopyable <Node> .Spawn(10);

            path.Add(endNode);
            while (endNode.parent[threadIndex] != null)
            {
                endNode = endNode.parent[threadIndex];
                path.Add(endNode);
            }
            path.Reverse();
            return(path);
        }
        public override void ApplyAfterConnections(Graph graph)
        {
            var nodes = PoolListCopyable <Node> .Spawn(10);

            var bounds = this.bounds;

            bounds.center += this.transform.position;
            graph.GetNodesInBounds(nodes, this.bounds);
            foreach (var node in nodes)
            {
                if (this.modifyWalkability == true)
                {
                    node.walkable = this.walkable;
                }
            }
        }
Exemple #6
0
        public override void ApplyAfterConnections(Graph graph)
        {
            var halfOffset = new Vector3(this.tilemap.cellSize.x, 0f, this.tilemap.cellSize.z) * 0.5f;

            var visited = PoolHashSet <Node> .Spawn();

            foreach (var pos in this.bounds.allPositionsWithin)
            {
                var worldPos = pos + halfOffset;
                var cellPos  = this.tilemap.layoutGrid.WorldToCell(worldPos);
                var tile     = this.tilemap.GetTile(cellPos);
                for (int i = 0; i < this.items.Length; ++i)
                {
                    var item = this.items[i];
                    if (item.modifyWalkability == false)
                    {
                        continue;
                    }

                    if (item.requiredTile == null || item.requiredTile == tile)
                    {
                        if (item.checkSprite == true)
                        {
                            var idx = System.Array.IndexOf(item.spriteOneOf, this.tilemap.GetSprite(cellPos));
                            if (idx < 0)
                            {
                                continue;
                            }
                        }

                        var result = PoolListCopyable <Node> .Spawn(1);

                        graph.GetNodesInBounds(result, new Bounds(worldPos, this.tilemap.cellSize * 0.5f));
                        foreach (var node in result)
                        {
                            if (visited.Contains(node) == false)
                            {
                                visited.Add(node);
                                node.walkable = item.walkable;
                            }
                        }
                        PoolListCopyable <Node> .Recycle(ref result);
                    }
                }
            }
            PoolHashSet <Node> .Recycle(ref visited);
        }
        public override void ApplyAfterConnections(Graph graph)
        {
            var visited = PoolHashSet <Node> .Spawn();

            {
                var gridGraph = (GridGraph)graph;
                var result    = PoolListCopyable <Node> .Spawn(1);

                graph.GetNodesInBounds(result, new Bounds(graph.graphCenter, (Vector3)gridGraph.size * gridGraph.nodeSize), Constraint.Empty);
                {
                    foreach (var node in result)
                    {
                        var worldPos = node.worldPosition;
                        var cellPos  = this.tilemap.layoutGrid.WorldToCell(worldPos);
                        var tile     = this.tilemap.GetTile(cellPos);
                        for (int i = 0; i < this.items.Length; ++i)
                        {
                            var item = this.items[i];
                            if (item.modifyWalkability == false)
                            {
                                continue;
                            }

                            if (item.requiredTile == null || item.requiredTile == tile)
                            {
                                if (item.checkSprite == true)
                                {
                                    var idx = System.Array.IndexOf(item.spriteOneOf, this.tilemap.GetSprite(cellPos));
                                    if (idx < 0)
                                    {
                                        continue;
                                    }
                                }

                                if (visited.Contains(node) == false)
                                {
                                    visited.Add(node);
                                    node.walkable = item.walkable;
                                }
                            }
                        }
                    }
                }
                PoolListCopyable <Node> .Recycle(ref result);
            }
            PoolHashSet <Node> .Recycle(ref visited);
        }
Exemple #8
0
        public virtual bool IsSuitable(Constraint constraint)
        {
            if (constraint.checkWalkability == true && this.walkable != constraint.walkable)
            {
                return(false);
            }
            if (constraint.checkArea == true && (constraint.areaMask & (1 << this.area)) == 0)
            {
                return(false);
            }
            if (constraint.checkTags == true && (constraint.tagsMask & (1 << this.tag)) == 0)
            {
                return(false);
            }
            if (constraint.graphMask >= 0 && (constraint.graphMask & (1 << this.graph.index)) == 0)
            {
                return(false);
            }

            if (constraint.tagsMask > 0L &&
                (constraint.agentSize.x > 0f ||
                 constraint.agentSize.y > 0f ||
                 constraint.agentSize.z > 0f))
            {
                var result = PoolListCopyable <Node> .Spawn(10);

                this.graph.GetNodesInBounds(result, new Bounds(this.worldPosition, constraint.agentSize));
                for (int e = 0, cnt = result.Count; e < cnt; ++e)
                {
                    var node = result[e];
                    var constraintErosion = constraint;
                    constraintErosion.agentSize = Vector3.zero;
                    if (node.IsSuitable(constraintErosion) == false)
                    {
                        return(false);
                    }
                }
                PoolListCopyable <Node> .Recycle(ref result);
            }

            return(true);
        }
        public override void ApplyAfterConnections(Graph graph)
        {
            var nodes = PoolListCopyable <Node> .Spawn(10);

            var bounds = this.bounds;

            bounds.center += this.transform.position;
            graph.GetNodesInBounds(nodes, this.bounds, Constraint.Empty);
            foreach (var node in nodes)
            {
                if (this.modifyWalkability == true)
                {
                    var ray = new Ray(node.worldPosition + Vector3.up * 10f, Vector3.down);
                    if (Physics.Raycast(ray, out var hit, 1000f, this.layerMask) == true)
                    {
                        node.walkable = this.walkable;
                    }
                }
            }
        }
Exemple #10
0
        public virtual void UpdateGraph(GraphUpdateObject graphUpdateObject)
        {
            var bounds = graphUpdateObject.GetBounds();
            var nodes  = PoolListCopyable <Node> .Spawn(10);

            this.GetNodesInBounds(nodes, bounds, Constraint.Empty);
            for (int i = 0, cnt = nodes.Count; i < cnt; ++i)
            {
                var node = nodes[i];
                if (graphUpdateObject.checkRadius == true)
                {
                    if ((node.worldPosition - graphUpdateObject.center).sqrMagnitude > graphUpdateObject.radius * graphUpdateObject.radius)
                    {
                        continue;
                    }
                }

                graphUpdateObject.Apply(node);
            }
            PoolListCopyable <Node> .Recycle(ref nodes);
        }
        public void ApplyForced(bool disabled = false)
        {
            if (this.pathfinding == null)
            {
                return;
            }

            var prevBounds = this.prevBounds;

            prevBounds.center += this.prevPosition;
            var prevNodes = PoolListCopyable <Node> .Spawn(10);

            this.pathfinding.GetNodesInBounds(prevNodes, prevBounds);
            foreach (var node in prevNodes)
            {
                if (this.prevModifyWalkability == true)
                {
                    node.walkable = true;
                    this.pathfinding.BuildNodePhysics(node);
                }
            }

            if (disabled == false)
            {
                var bounds = this.bounds;
                bounds.center += this.transform.position;
                var nodes = PoolListCopyable <Node> .Spawn(10);

                this.pathfinding.GetNodesInBounds(nodes, bounds);
                foreach (var node in nodes)
                {
                    if (this.modifyWalkability == true)
                    {
                        node.walkable = this.walkable;
                        this.pathfinding.BuildNodePhysics(node);
                    }
                }
            }
        }
        partial void EndRestoreEntitiesPlugin5()
        {
            if (this.debugSettings.createGameObjectsRepresentation == true)
            {
                var unused = PoolListCopyable <Entity> .Spawn(100);

                foreach (var entKv in this.debugEntities)
                {
                    if (this.used.Contains(entKv.Key) == false)
                    {
                        unused.Add(entKv.Key);
                    }
                }

                for (int i = 0; i < unused.Count; ++i)
                {
                    this.DestroyEntityPlugin5(unused[i]);
                }

                PoolListCopyable <Entity> .Recycle(ref unused);

                PoolHashSet <Entity> .Recycle(ref this.used);
            }
        }
        public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0, bool burstEnabled = true, bool cacheEnabled = false) where TMod : struct, IPathModifier
        {
            if (threadIndex < 0)
            {
                threadIndex = 0;
            }
            threadIndex = threadIndex % Pathfinding.THREADS_COUNT;

            var constraintStart = constraint;

            constraintStart.checkWalkability = true;
            constraintStart.walkable         = true;
            var startNode = graph.GetNearest(from, constraintStart);

            if (startNode == null)
            {
                return(new Path());
            }

            var constraintEnd = constraintStart;

            constraintEnd.checkArea = true;
            constraintEnd.areaMask  = (1 << startNode.area);

            var endNode = graph.GetNearest(to, constraintEnd);

            if (endNode == null)
            {
                return(new Path());
            }

            System.Diagnostics.Stopwatch swPath = null;
            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                swPath = System.Diagnostics.Stopwatch.StartNew();
            }

            //UnityEngine.Debug.Log(endNode.worldPosition + " :: " + ((GridNode)endNode).erosion);
            //UnityEngine.Debug.DrawLine(endNode.worldPosition, endNode.worldPosition + Vector3.up * 10f, Color.red, 3f);

            var key = MathUtils.GetKey(constraint.GetKey(), endNode.index);

            //UnityEngine.Debug.Log("Build path cache: " + cacheEnabled + ", burst: " + burstEnabled);
            if (cacheEnabled == true)
            {
                if (PathfindingFlowFieldProcessor.pathCache.TryGetValue(key, out var buffer) == true)
                {
                    var pathCache = new Path()
                    {
                        graph        = graph,
                        result       = PathCompleteState.Complete,
                        flowField    = buffer,
                        cacheEnabled = cacheEnabled,
                    };

                    if ((pathfindingLogLevel & LogLevel.Path) != 0)
                    {
                        Logger.Log(string.Format("Path result {0}, cache in {1}ms. \nThread Index: {2}", pathCache.result, swPath.ElapsedMilliseconds, threadIndex));
                    }

                    return(pathCache);
                }
            }

            var flowField = PoolArray <byte> .Spawn(graph.nodes.Count);

            int statVisited = 0;

            if (burstEnabled == true)   // burst

            {
                this.FlowFieldBurst(ref statVisited, (GridGraph)graph, ref flowField, (GridNode)endNode, constraint, pathModifier);
                if (cacheEnabled == true)
                {
                    if (PathfindingFlowFieldProcessor.pathCache.Count > PathfindingFlowFieldProcessor.CACHE_SIZE)
                    {
                        const int size = PathfindingFlowFieldProcessor.CACHE_SIZE / 10;
                        for (int i = 0; i < size; ++i)
                        {
                            var idx = PathfindingFlowFieldProcessor.pathCacheQueue.Dequeue();
                            PathfindingFlowFieldProcessor.pathCache.Remove(idx);
                        }

                        PathfindingFlowFieldProcessor.pathCacheQueue.Clear();
                    }

                    PathfindingFlowFieldProcessor.pathCache.Add(key, flowField);
                    PathfindingFlowFieldProcessor.pathCacheQueue.Enqueue(key);
                }
            }
            else     // no burst

            {
                var visited = PoolListCopyable <Node> .Spawn(10);

                for (int i = 0; i < graph.nodes.Count; ++i)
                {
                    graph.nodes[i].Reset(threadIndex);
                }

                this.CreateIntegrationField(graph, visited, endNode, constraint, threadIndex);
                this.CreateFlowField(graph, ref flowField, endNode, constraint, threadIndex);

                statVisited = visited.Count;
                for (int i = 0; i < visited.Count; ++i)
                {
                    visited[i].Reset(threadIndex);
                }
                PoolListCopyable <Node> .Recycle(ref visited);
            }

            var path = new Path();

            path.graph        = graph;
            path.result       = PathCompleteState.Complete;
            path.flowField    = flowField;
            path.cacheEnabled = cacheEnabled;

            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: (visited: {2})\nThread Index: {3}", path.result, (swPath.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond).ToString("0.##"), statVisited, threadIndex));
            }

            return(path);
        }
        public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 fromPoint, Vector3 toPoint, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0,
                               bool burstEnabled = true, bool cacheEnabled = false) where TMod : struct, IPathModifier
        {
            var path         = new Path();
            var pathResult   = new PathInternal();
            var navMeshGraph = (NavMeshGraph)graph;

            var areas = -1;

            if (constraint.checkArea == true)
            {
                areas = (int)constraint.areaMask;
            }

            System.Diagnostics.Stopwatch swPath = null;
            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                swPath = System.Diagnostics.Stopwatch.StartNew();
            }

            var statLength  = 0;
            var statVisited = 0;

            var query = new UnityEngine.Experimental.AI.NavMeshQuery(UnityEngine.Experimental.AI.NavMeshWorld.GetDefaultWorld(), Unity.Collections.Allocator.TempJob, PathfindingNavMeshProcessor.POOL_SIZE);

            if (burstEnabled == true)
            {
                var results     = new Unity.Collections.NativeArray <UnityEngine.Experimental.AI.NavMeshLocation>(PathfindingNavMeshProcessor.MAX_PATH_SIZE, Unity.Collections.Allocator.TempJob);
                var pathResults = new Unity.Collections.NativeArray <int>(2, Unity.Collections.Allocator.TempJob);
                var job         = new BuildPathJob()
                {
                    query       = query,
                    fromPoint   = fromPoint,
                    toPoint     = toPoint,
                    agentTypeId = navMeshGraph.agentTypeId,
                    areas       = areas,
                    pathResults = pathResults,
                    results     = results,
                };
                job.Schedule().Complete();
                var pathStatus  = (UnityEngine.Experimental.AI.PathQueryStatus)pathResults[0];
                var cornerCount = pathResults[1];
                pathResults.Dispose();

                if ((pathStatus & UnityEngine.Experimental.AI.PathQueryStatus.Success) != 0)
                {
                    if (cornerCount >= 2)
                    {
                        path.navMeshPoints = PoolListCopyable <Vector3> .Spawn(cornerCount);

                        for (var i = 0; i < cornerCount; ++i)
                        {
                            path.navMeshPoints.Add(results[i].position);
                        }

                        if ((pathfindingLogLevel & LogLevel.Path) != 0)
                        {
                            var hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.x * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash X: " + hash);

                            hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.y * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash Y: " + hash);

                            hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.z * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash Z: " + hash);
                        }

                        if ((pathStatus & UnityEngine.Experimental.AI.PathQueryStatus.PartialResult) != 0)
                        {
                            path.result = PathCompleteState.CompletePartial;
                        }
                        else
                        {
                            path.result = PathCompleteState.Complete;
                        }
                    }
                    else
                    {
                        path.result = PathCompleteState.NotExist;
                    }
                }
                results.Dispose();
                query.Dispose();
                return(path);
            }

            UnityEngine.AI.NavMesh.SamplePosition(fromPoint, out var hitFrom, 1000f, new UnityEngine.AI.NavMeshQueryFilter()
            {
                agentTypeID = navMeshGraph.agentTypeId,
                areaMask    = areas,
            });
            fromPoint = hitFrom.position;
            var from = query.MapLocation(fromPoint, Vector3.one * 10f, navMeshGraph.agentTypeId, areas);

            if (from.polygon.IsNull() == true)
            {
                return(path);
            }

            UnityEngine.AI.NavMesh.SamplePosition(toPoint, out var hitTo, 1000f, new UnityEngine.AI.NavMeshQueryFilter()
            {
                agentTypeID = navMeshGraph.agentTypeId,
                areaMask    = areas,
            });
            toPoint = hitTo.position;
            var to = query.MapLocation(toPoint, Vector3.one * 10f, navMeshGraph.agentTypeId, areas);

            if (to.polygon.IsNull() == true)
            {
                return(path);
            }

            var marker = new Unity.Profiling.ProfilerMarker("PathfindingNavMeshProcessor::Query::BuildPath");

            marker.Begin();
            query.BeginFindPath(from, to, areas);
            query.UpdateFindPath(PathfindingNavMeshProcessor.MAX_ITERATIONS, out var performed);
            marker.End();
            statVisited = performed;

            var result = query.EndFindPath(out var pathSize);

            if ((result & UnityEngine.Experimental.AI.PathQueryStatus.Success) != 0)
            {
                var pathInternal = new Unity.Collections.NativeArray <UnityEngine.Experimental.AI.PolygonId>(pathSize, Unity.Collections.Allocator.Persistent);
                query.GetPathResult(pathInternal);

                var markerFindStraight = new Unity.Profiling.ProfilerMarker("PathfindingNavMeshProcessor::Query::FindStraightPath");
                markerFindStraight.Begin();

                var straightPathFlags = new Unity.Collections.NativeArray <StraightPathFlags>(PathfindingNavMeshProcessor.MAX_PATH_SIZE, Unity.Collections.Allocator.Persistent);
                var vertexSide        = new Unity.Collections.NativeArray <float>(PathfindingNavMeshProcessor.MAX_PATH_SIZE, Unity.Collections.Allocator.Persistent);
                var results           = new Unity.Collections.NativeArray <UnityEngine.Experimental.AI.NavMeshLocation>(PathfindingNavMeshProcessor.MAX_PATH_SIZE, Unity.Collections.Allocator.Persistent);
                var resultStatus      = new Unity.Collections.NativeArray <int>(2, Unity.Collections.Allocator.TempJob);
                var job = new FindStraightPathJob()
                {
                    query             = query,
                    from              = from,
                    to                = to,
                    pathInternal      = pathInternal,
                    pathSize          = pathSize,
                    results           = results,
                    straightPathFlags = straightPathFlags,
                    vertexSide        = vertexSide,
                    resultStatus      = resultStatus,
                };
                job.Schedule().Complete();

                var pathStatus  = (UnityEngine.Experimental.AI.PathQueryStatus)job.resultStatus[0];
                var cornerCount = job.resultStatus[1];
                resultStatus.Dispose();

                statLength = cornerCount;

                markerFindStraight.End();

                if (pathStatus == UnityEngine.Experimental.AI.PathQueryStatus.Success)
                {
                    /*for (int i = 1; i < cornerCount; ++i) {
                     *
                     *  Gizmos.color = Color.green;
                     *  Gizmos.DrawLine(results[i].position, results[i - 1].position);
                     *
                     * }*/
                    pathResult.pathStatus = pathStatus;
                    pathResult.results    = results;
                    pathResult.corners    = cornerCount;

                    if (cornerCount >= 2)
                    {
                        path.navMeshPoints = PoolListCopyable <Vector3> .Spawn(cornerCount);

                        for (var i = 0; i < cornerCount; ++i)
                        {
                            path.navMeshPoints.Add(results[i].position);
                        }

                        if ((pathfindingLogLevel & LogLevel.Path) != 0)
                        {
                            var hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.x * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash X: " + hash);

                            hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.y * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash Y: " + hash);

                            hash = 0;
                            for (var i = 0; i < cornerCount; ++i)
                            {
                                hash ^= (int)(results[i].position.z * 1000000f);
                            }

                            UnityEngine.Debug.Log("Path hash Z: " + hash);
                        }

                        path.result = PathCompleteState.Complete;
                    }
                    else
                    {
                        path.result = PathCompleteState.NotExist;
                    }

                    pathResult.Dispose();
                }
                else
                {
                    path.result = PathCompleteState.NotExist;
                    results.Dispose();
                }

                vertexSide.Dispose();
                straightPathFlags.Dispose();
                pathInternal.Dispose();
            }
            else
            {
                path.result = PathCompleteState.NotExist;
                //Debug.LogWarning("Path result: " + result + ", performed: " + performed);
            }

            System.Diagnostics.Stopwatch swModifier = null;
            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                swModifier = System.Diagnostics.Stopwatch.StartNew();
            }

            if ((path.result & PathCompleteState.Complete) != 0)
            {
                path = pathModifier.Run(path, constraint);
            }

            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                Logger.Log(
                    $"Path result {path.result}, built in {(swPath.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond).ToString("0.##")}ms. Path length: {statLength} (Visited: {statVisited})\nThread Index: {threadIndex}");
            }

            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                Logger.Log($"Path Mods: {swModifier.ElapsedMilliseconds}ms");
            }

            query.Dispose();

            return(path);
        }
Exemple #15
0
        public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0) where TMod : IPathModifier
        {
            if (threadIndex < 0)
            {
                threadIndex = 0;
            }
            threadIndex = threadIndex % Pathfinding.THREADS_COUNT;

            var constraintStart = constraint;

            constraintStart.checkWalkability = true;
            constraintStart.walkable         = true;
            var startNode = graph.GetNearest(from, constraintStart);

            if (startNode == null)
            {
                return(new Path());
            }

            var constraintEnd = constraintStart;

            constraintEnd.checkArea = true;
            constraintEnd.areaMask  = (1 << startNode.area);

            var endNode = graph.GetNearest(to, constraintEnd);

            if (endNode == null)
            {
                return(new Path());
            }

            var visited = PoolListCopyable <Node> .Spawn(10);

            System.Diagnostics.Stopwatch swPath = null;
            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                swPath = System.Diagnostics.Stopwatch.StartNew();
            }
            var nodesPath = this.AstarSearch(graph, visited, startNode, endNode, constraint, threadIndex);

            var statVisited = visited.Count;
            var statLength  = 0;

            var path = new Path();

            path.graph  = graph;
            path.result = PathCompleteState.NotCalculated;

            if (nodesPath == null)
            {
                path.result = PathCompleteState.NotExist;
            }
            else
            {
                statLength = nodesPath.Count;

                path.result = PathCompleteState.Complete;
                path.nodes  = nodesPath;
            }

            for (int i = 0; i < visited.Count; ++i)
            {
                visited[i].Reset(threadIndex);
            }

            PoolListCopyable <Node> .Recycle(ref visited);

            System.Diagnostics.Stopwatch swModifier = null;
            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                swModifier = System.Diagnostics.Stopwatch.StartNew();
            }
            if (path.result == PathCompleteState.Complete)
            {
                path = pathModifier.Run(path, constraint);
            }

            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: {2} (visited: {3})\nThread Index: {4}", path.result, swPath.ElapsedMilliseconds, statLength, statVisited, threadIndex));
            }

            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                Logger.Log(string.Format("Path Mods: {0}ms", swModifier.ElapsedMilliseconds));
            }

            return(path);
        }
        public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0, bool burstEnabled = true, bool cacheEnabled = false) where TMod : struct, IPathModifier
        {
            if (threadIndex < 0)
            {
                threadIndex = 0;
            }
            threadIndex = threadIndex % Pathfinding.THREADS_COUNT;

            var constraintStart = constraint;

            constraintStart.checkWalkability = true;
            constraintStart.walkable         = true;
            var startNode = graph.GetNearest(from, constraintStart);

            if (startNode.node == null)
            {
                return(new Path());
            }

            var constraintEnd = constraintStart;

            constraintEnd.checkArea = true;
            constraintEnd.areaMask  = (1 << startNode.node.area);

            var endNode = graph.GetNearest(to, constraintEnd);

            if (endNode.node == null)
            {
                return(new Path());
            }

            System.Diagnostics.Stopwatch swPath = null;
            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                swPath = System.Diagnostics.Stopwatch.StartNew();
            }
            var statVisited = 0;
            var nodesPath   = this.AstarSearch(ref statVisited, graph as GridGraph, startNode.node, endNode.node, constraint, threadIndex);

            var statLength = 0;

            var path = new Path();

            path.graph  = graph;
            path.result = PathCompleteState.NotCalculated;

            if (nodesPath.Length == 0)
            {
                path.result = PathCompleteState.NotExist;
            }
            else
            {
                statLength = nodesPath.Length;

                path.result = PathCompleteState.Complete;
                var list = PoolListCopyable <Node> .Spawn(nodesPath.Length);

                for (int i = 0; i < nodesPath.Length; ++i)
                {
                    list.Add(graph.nodes[nodesPath[i].index]);
                }
                path.nodes = list;
            }

            nodesPath.Dispose();

            System.Diagnostics.Stopwatch swModifier = null;
            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                swModifier = System.Diagnostics.Stopwatch.StartNew();
            }
            if (path.result == PathCompleteState.Complete)
            {
                path = pathModifier.Run(path, constraint);
            }

            if ((pathfindingLogLevel & LogLevel.Path) != 0)
            {
                Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: {2} (visited: {3})\nThread Index: {4}", path.result, (swPath.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond).ToString("0.##"), statLength, statVisited, threadIndex));
            }

            if ((pathfindingLogLevel & LogLevel.PathMods) != 0)
            {
                Logger.Log(string.Format("Path Mods: {0}ms", swModifier.ElapsedMilliseconds));
            }

            return(path);
        }
Exemple #17
0
 public DataList(int capacity)
 {
     this.dataObject = new DataObject <ListCopyable <T>, DataListProvider <T> >(PoolListCopyable <T> .Spawn(capacity));
 }
Exemple #18
0
        public void Clone(ListCopyable <T> from, ref ListCopyable <T> to)
        {
            to = PoolListCopyable <T> .Spawn(from.Capacity);

            to.CopyFrom(from);
        }
Exemple #19
0
        public override void Update(BufferArray <Views> list, float deltaTime, bool hasChanged)
        {
            if (this.world.settings.useJobsForViews == false || this.world.settings.viewsSettings.unityGameObjectProviderDisableJobs == true)
            {
                return;
            }

            if (list.isCreated == true)
            {
                if (hasChanged == true)
                {
                    if (this.tempList == null)
                    {
                        this.tempList = PoolListCopyable <MonoBehaviourView> .Spawn(list.Length);
                    }

                    var changed = false; //ArrayUtils.Resize(list.Length - 1, ref this.currentTransforms);

                    var k = 0;
                    for (int i = 0, length = list.Length; i < length; ++i)
                    {
                        var item = list.arr[i];
                        if (item.isNotEmpty == false)
                        {
                            continue;
                        }

                        for (int j = 0, count = item.Length; j < count; ++j)
                        {
                            var view = item[j] as MonoBehaviourView;
                            if (view == null)
                            {
                                continue;
                            }
                            if (view.applyStateJob == true && view.entity.IsAlive() == true)
                            {
                                changed |= ArrayUtils.Resize(k, ref this.currentTransforms);
                                var isNew = false;
                                if (k >= this.tempList.Count)
                                {
                                    this.tempList.Add(view);
                                    this.currentTransforms.arr[k] = view.transform;
                                    isNew = true;
                                }

                                var tempItem = this.tempList[k];
                                if (isNew == true ||
                                    tempItem.prefabSourceId != view.prefabSourceId ||
                                    tempItem.creationTick != view.creationTick ||
                                    tempItem.entity != view.entity)
                                {
                                    this.tempList[k] = view;
                                    this.currentTransforms.arr[k] = view.transform;
                                    changed = true;
                                }

                                ++k;
                            }
                        }
                    }

                    if (this.currentTransformArray.isCreated == false)
                    {
                        this.currentTransformArray = new TransformAccessArray(k);
                    }

                    if (changed == true)
                    {
                        this.currentTransformArray.SetTransforms(this.currentTransforms.arr);
                        //if (UnityGameObjectProvider.resultList != null) PoolList<MonoBehaviourView>.Recycle(ref UnityGameObjectProvider.resultList);
                        //var result = PoolList<MonoBehaviourView>.Spawn(this.tempList.Count);
                        //result.AddRange(this.tempList);
                        UnityGameObjectProvider.resultList  = this.tempList;
                        UnityGameObjectProvider.resultCount = k;
                    }
                }

                if (UnityGameObjectProvider.resultCount > 0 && this.currentTransformArray.isCreated == true)
                {
                    var job = new Job()
                    {
                        deltaTime = deltaTime,
                        length    = UnityGameObjectProvider.resultCount
                    };

                    var handle = job.Schedule(this.currentTransformArray);
                    handle.Complete();
                }
            }
        }