protected override void OnCreate()
        {
            var pointerArray = new NavMeshQueryPointer[JobsUtility.MaxJobThreadCount];

            for (int i = 0; i < JobsUtility.MaxJobThreadCount; ++i)
            {
                pointerArray[i] = new NavMeshQueryPointer
                {
                    Value = UnsafeUtility.Malloc(
                        UnsafeUtility.SizeOf <NavMeshQuery>(),
                        UnsafeUtility.AlignOf <NavMeshQuery>(),
                        Allocator.Persistent
                        )
                };

                var query = new NavMeshQuery(
                    NavMeshWorld.GetDefaultWorld(),
                    Allocator.Persistent,
                    NavConstants.PATH_NODE_MAX
                    );

                queryList.Add(query);

                UnsafeUtility.CopyStructureToPtr(ref query, pointerArray[i].Value);
            }

            PointerArray = new NativeArray <NavMeshQueryPointer>(pointerArray, Allocator.Persistent);
        }
Exemple #2
0
    public void TryFindPath(Vector3 start, Vector3 end)
    {
        using (var polygonIds = new NativeArray <PolygonId>(100, Allocator.Persistent))
            using (var query = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent, 100))
            {
                int maxIterations = 1024;
                var from          = query.MapLocation(start, Vector3.one * 10, 0);
                var to            = query.MapLocation(end, Vector3.one * 10, 0);

                var status = query.BeginFindPath(from, to);

                status = query.UpdateFindPath(maxIterations, out int currentIterations);

                var finalStatus = query.EndFindPath(out int pathLength);
                var pathResult  = query.GetPathResult(polygonIds);

                var straightPath = new NativeArray <NavMeshLocation>(pathLength, Allocator.Temp);
                paths = new Vector3[pathResult];

                for (int i = 0; i < pathResult; i++)
                {
                    var polyId           = polygonIds[i];
                    var polyWorldToLocal = query.PolygonWorldToLocalMatrix(polyId);

                    var b = query.CreateLocation(paths[i], polyId);
                    paths[i] = b.position;
                    //Debug.Log(b.position);
                }

                //Debug.Log(pathResult);
                Debug.DrawLine(from.position, to.position);
            }
    }
        IEnumerator StartQuery()
        {
            NavMeshWorld world = NavMeshWorld.GetDefaultWorld();
            NavMeshQuery query = new NavMeshQuery(world, Allocator.Persistent, maxPath);

            NavMeshLocation startLocation = query.MapLocation(start.position, Vector3.up * extents, 0);
            NavMeshLocation endLocation   = query.MapLocation(end.position, Vector3.up * extents, 0);
            PathQueryStatus status        = query.BeginFindPath(startLocation, endLocation);

            yield return(new WaitWhile(() => {
                status = query.UpdateFindPath(8, out int iterationsPerformed);
                return status == PathQueryStatus.InProgress;
            }));

            status = query.EndFindPath(out int pathsize);

            NativeArray <PolygonId> path = new NativeArray <PolygonId>(pathsize, Allocator.Temp);
            int pathResult = query.GetPathResult(path);

            //NativeArray<NavMeshLocation> pathStraight = new NativeArray<NavMeshLocation>(maxPath, Allocator.Temp);
            ////NativeArray<StraightPathFlag> pathStreaigthFlag = new NativeArray<StraightPathFlags>(maxPath, Allocator.Temp);
            //NativeArray<float> vertexSize = new NativeArray<float>(maxPath, Allocator.Temp);
            //
            //int straghtPathCount = 0;

            for (var i = 0; i < pathResult; i++)
            {
                var p = path[i];

                var loc    = query.CreateLocation(start.position, p);
                var target = loc.position;
            }

            query.Dispose();
        }
Exemple #4
0
        protected override void OnCreate()
        {
            var settings     = pathSystem.Settings;
            var pointerArray = new PathMeshQueryPointer[JobsUtility.MaxJobThreadCount];

            for (var i = 0; i < JobsUtility.MaxJobThreadCount; ++i)
            {
                pointerArray[i] = new PathMeshQueryPointer
                {
                    Value = UnsafeUtility.Malloc(
                        UnsafeUtility.SizeOf <NavMeshQuery>(),
                        UnsafeUtility.AlignOf <NavMeshQuery>(),
                        Allocator.Persistent
                        )
                };

                var query = new NavMeshQuery(
                    NavMeshWorld.GetDefaultWorld(),
                    Allocator.Persistent,
                    settings.PathMeshQueryNodeMax
                    );

                queryList.Add(query);

                UnsafeUtility.CopyStructureToPtr(ref query, pointerArray[i].Value);
            }

            PointerArray = new NativeArray <PathMeshQueryPointer>(pointerArray, Allocator.Persistent);
        }
Exemple #5
0
    protected override void OnCreateManager(int capacity)
    {
        var world = NavMeshWorld.GetDefaultWorld();

        query     = new NavMeshQuery(world, Allocator.Persistent);
        agentType = NavMesh.GetSettingsByIndex(1).agentTypeID;
    }
Exemple #6
0
    public PathQueryQueueEcs(int nodePoolSize, int maxRequestCount)
    {
        var world = NavMeshWorld.GetDefaultWorld();

        m_Query        = new NavMeshQuery(world, Allocator.Persistent, nodePoolSize);
        m_Requests     = new NativeArray <RequestEcs>(maxRequestCount, Allocator.Persistent);
        m_ResultNodes  = new NativeArray <PolygonId>(2 * nodePoolSize, Allocator.Persistent);
        m_ResultRanges = new NativeArray <PathInfo>(maxRequestCount + 1, Allocator.Persistent);
        m_AgentIndices = new NativeArray <int>(maxRequestCount + 1, Allocator.Persistent);
        m_Costs        = new NativeArray <float>(32, Allocator.Persistent);
        for (var i = 0; i < m_Costs.Length; ++i)
        {
            m_Costs[i] = 1.0f;
        }

        m_State    = new NativeArray <QueryQueueState>(1, Allocator.Persistent);
        m_State[0] = new QueryQueueState()
        {
            requestCount       = 0,
            requestIndex       = 0,
            resultNodesCount   = 0,
            resultPathsCount   = 0,
            currentAgentIndex  = -1,
            currentPathRequest = new PathInfo()
        };
    }
    public void Awake()
    {
        Instance      = this;    // worst singleton ever but it works
        entityManager = World.Active.GetExistingManager <EntityManager>();
        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        mapLocationQuery = new NavMeshQuery(navMeshWorld, Allocator.Persistent);
    }
    protected override void OnCreate()
    {
        AgentsGroup = GetEntityQuery(typeof(NavAgent), ComponentType.ReadWrite <Translation>(),
                                     ComponentType.ReadWrite <Rotation>(), ComponentType.ReadWrite <LocalToWorld>());
        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        NavMeshQuery = new NavMeshQuery(navMeshWorld, Allocator.Persistent, 100);
    }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var lookup        = GetBufferFromEntity <PathBufferElement>();
            var commandBuffer = commandBufferSystem.CreateCommandBuffer().ToConcurrent();
            var world         = NavMeshWorld.GetDefaultWorld();

            var pathfindingDatas = requests.ToComponentDataArray <NavMeshPathfindingRequestData>(Allocator.TempJob);
            var entities         = requests.ToEntityArray(Allocator.TempJob);

            var jobs = new NativeArray <JobHandle>(pathfindingDatas.Length, Allocator.TempJob);

            JobHandle jobHandle = inputDeps;

            for (var i = 0; i < entities.Length; ++i)
            {
                var entity = entities[i];

                //Destroy finished requests
                if (pathfindingDatas[i].Status == PathSearchStatus.Finished)
                {
                    navMeshQueries[entity].Dispose();
                    navMeshQueries.Remove(entity);
                    EntityManager.DestroyEntity(entity);
                    continue;
                }

                //Process requests in progress
                if (!navMeshQueries.TryGetValue(entity, out var query))
                {
                    query = navMeshQueries[entity] =
                        new NavMeshQuery(world, Allocator.Persistent, MAXIMUM_POOL_SIZE);
                }
                var navMeshPathfindingJob = new NavMeshPathfindingJob
                {
                    BuffersLookup   = lookup,
                    CommandBuffer   = commandBuffer,
                    JobIndex        = i,
                    Request         = pathfindingDatas[i],
                    Query           = query,
                    MaximumPoolSize = MAXIMUM_POOL_SIZE,
                    EntityRequestId = entity
                };

                jobs[i] = navMeshPathfindingJob.Schedule(inputDeps);
            }

            jobHandle = JobHandle.CombineDependencies(jobs);

            pathfindingDatas.Dispose();
            entities.Dispose();

            jobs.Dispose();

            commandBufferSystem.AddJobHandleForProducer(jobHandle);
            return(jobHandle);
        }
Exemple #10
0
    protected override void OnCreate()
    {
        base.OnCreate();
        var navWorld = NavMeshWorld.GetDefaultWorld();

        agentQuery = GetEntityQuery(new EntityQueryDesc
        {
            All = new ComponentType[] { ComponentType.ReadWrite <AgentComponent>(), ComponentType.ReadWrite <LocalToWorld>() },
        });
    }
        private void Reconfigure()
        {
            foreach (var query in idleQueries)
            {
                query.Dispose();
            }

            idleQueries = new Queue <NavMeshQuery>(
                Enumerable.Range(0, maxNumParallelQueries)
                .Select(x => new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent, PathNodePoolSizeDefault)));
        }
        protected override void OnCreate()
        {
            var agentQueryDesc = new EntityQueryDesc
            {
                All = new ComponentType[] { typeof(NavAgent), typeof(NavAgentAvoidance) }
            };

            _agentQuery     = GetEntityQuery(agentQueryDesc);
            _navMeshQuery   = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent, 128);
            IndexMap        = new NativeMultiHashMap <int, int>(100 * 1024, Allocator.Persistent);
            NextPositionMap = new NativeMultiHashMap <int, float3>(100 * 1024, Allocator.Persistent);
            _querySystem    = World.GetOrCreateSystem <NavMeshQuerySystem>();
        }
Exemple #13
0
        public RequestBatch(int nodePoolSize = 2000)
        {
            var world = NavMeshWorld.GetDefaultWorld();

            query        = new NavMeshQuery(world, Allocator.Persistent, nodePoolSize);
            entities     = new NativeArray <Entity>(MAX_COUNT, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            requests     = new NativeArray <PathRequestData>(MAX_COUNT, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            pathBuffer   = new NativeArray <PathPoint>(MAX_COUNT * MAX_PATHSIZE, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            pathStart    = new NativeArray <int>(MAX_COUNT, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            state        = new NativeArray <State>(1, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            resultBuffer = new NativeArray <PolygonId>(MAX_COUNT * 5, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);

            var s = new State();

            s.entityInUse = State.NONE;
            s.entitySize  = 0;
            s.pathSize    = 0;
            state[0]      = s;
        }
    void Initialize(int capacity)
    {
        var world      = NavMeshWorld.GetDefaultWorld();
        var queryCount = world.IsValid() ? k_QueryCount : 0;

        var agentCount = world.IsValid() ? capacity : 0;

        m_PlanPathForAgent      = new NativeList <bool1>(agentCount, Allocator.Persistent);
        m_EmptyPlanPathForAgent = new NativeList <bool1>(0, Allocator.Persistent);
        m_PathRequestIdForAgent = new NativeList <uint>(agentCount, Allocator.Persistent);
        m_PathRequests          = new NativeList <PathQueryQueueEcs.RequestEcs>(k_PathRequestsPerTick, Allocator.Persistent);
        m_PathRequests.ResizeUninitialized(k_PathRequestsPerTick);
        for (var i = 0; i < m_PathRequests.Length; i++)
        {
            m_PathRequests[i] = new PathQueryQueueEcs.RequestEcs {
                uid = PathQueryQueueEcs.RequestEcs.invalidId
            };
        }
        m_PathRequestsRange          = new NativeArray <int>(k_DataSize, Allocator.Persistent);
        m_PathRequestsRange[k_Start] = 0;
        m_PathRequestsRange[k_Count] = 0;
        m_UniqueIdStore        = new NativeArray <uint>(1, Allocator.Persistent);
        m_CurrentAgentIndex    = new NativeArray <int>(1, Allocator.Persistent);
        m_CurrentAgentIndex[0] = 0;

        m_NavMeshQuery                = new NavMeshQuery(world, Allocator.Persistent);
        m_QueryQueues                 = new PathQueryQueueEcs[queryCount];
        m_QueryJobs                   = new UpdateQueriesJob[queryCount];
        m_AfterQueriesProcessed       = new NativeArray <JobHandle>(queryCount, Allocator.Persistent);
        m_AfterQueriesCleanup         = new JobHandle();
        m_AfterMovedRequestsForgotten = new JobHandle();
        m_IsEmptyQueryQueue           = new bool[queryCount];
        for (var i = 0; i < m_QueryQueues.Length; i++)
        {
            m_QueryQueues[i] = new PathQueryQueueEcs(k_MaxQueryNodes, k_MaxRequestsPerQuery);
            m_QueryJobs[i]   = new UpdateQueriesJob()
            {
                maxIterations = k_MaxQueryIterationsPerTick, queryQueue = m_QueryQueues[i]
            };
            m_AfterQueriesProcessed[i] = new JobHandle();
            m_IsEmptyQueryQueue[i]     = true;
        }
    }
    protected override void OnCreate()
    {
        extents        = new float3(10, 10, 10);
        allPaths       = new Dictionary <int, float3[]>();
        statusOutputs  = new List <NativeArray <int> >();
        results        = new List <NativeArray <float3> >();
        routedEntities = new List <Entity>();
        queries        = new List <NavMeshQuery>();
        jobHandles     = new List <JobHandle>();

        for (int n = 0; n <= 32; n++)
        {
            NativeArray <float3> result       = new NativeArray <float3>(1024, Allocator.Persistent);
            NativeArray <int>    statusOutput = new NativeArray <int>(3, Allocator.Persistent);
            statusOutputs.Add(statusOutput);
            results.Add(result);
        }
        navMeshWorld = NavMeshWorld.GetDefaultWorld();
    }
Exemple #16
0
    //---------------------- Collision Avoidance ---------------------------

    protected override void OnCreate()
    {
        Dictionary <string, string> configValues = Utils.GetConfigValues();

        probabilityOfInfectionWithMaskWait = float.Parse(configValues["PROBABILITY_OF_INFECTION_WITH_MASK_WAIT"]) * 100;
        probabilityOfInfectionWait         = float.Parse(configValues["PROBABILITY_OF_INFECTION_WAIT"]) * 100;
        probabilityOfInfectionWithMask     = float.Parse(configValues["PROBABILITY_OF_INFECTION_WITH_MASK"]) * 100;
        probabilityOfInfection             = float.Parse(configValues["PROBABILITY_OF_INFECTION"]) * 100;
        infectionDistance     = float.Parse(configValues["INFECTION_DISTANCE"]);
        infectionDistanceWait = float.Parse(configValues["INFECTION_DISTANCE_WAIT"]);

        bi_ECB = World.GetOrCreateSystem <BeginInitializationEntityCommandBufferSystem>();

        extents        = new float3(100, 100, 100);
        allPaths       = new Dictionary <string, float3[]>();
        statusOutputs  = new List <NativeArray <int> >();
        results        = new List <NativeArray <float3> >();
        routedEntities = new List <Entity>();
        queries        = new List <NavMeshQuery>();
        jobHandles     = new List <JobHandle>();
        keys           = new List <string>();

        totalNumberOfCovidExit    = 0;
        totalNumberOfStudentsExit = 0;
        frameCounter = 0;

        for (int n = 0; n <= 4000; n++) //limit number equals to Max Entities routed per frame of UnitManager game object
        {
            NativeArray <float3> result       = new NativeArray <float3>(1024, Allocator.Persistent);
            NativeArray <int>    statusOutput = new NativeArray <int>(2, Allocator.Persistent);
            statusOutputs.Add(statusOutput);
            results.Add(result);
            keys.Add("");
        }
        navMeshWorld = NavMeshWorld.GetDefaultWorld();

        //---------------------- Collision Avoidance ---------------------------

        cellVsEntityPositions = new NativeMultiHashMap <int, CovidPos>(0, Allocator.Persistent);

        //---------------------- Collision Avoidance ---------------------------
    }
    protected override void OnCreateManager(int capacity)
    {
        base.OnCreateManager(capacity);

        //costs = new NativeArray<float>(32, Allocator.Persistent);
        //for (int i = 0; i < 32; i++) costs[i] = 1;

        newPathQueries      = new NativeQueue <Entity>(Allocator.Persistent);
        completePathQueries = new NativeQueue <Entity>(Allocator.Persistent);

        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        queries        = new NavMeshQuery[MaxNavMeshQueries];
        queryIndexUsed = new NativeList <int>(MaxNavMeshQueries, Allocator.Persistent);
        queryIndexFree = new NativeList <int>(MaxNavMeshQueries, Allocator.Persistent);
        for (var i = 0; i < MaxNavMeshQueries; ++i)
        {
            queries[i] = new NavMeshQuery(navMeshWorld, Allocator.Persistent, MaxNavMeshNodes);
            queryIndexFree.Add(i);
        }
        findingEntities = new NativeList <Entity>(MaxNavMeshQueries, Allocator.Persistent);
    }
Exemple #18
0
        protected override void OnCreate()
        {
            world         = NavMeshWorld.GetDefaultWorld();
            locationQuery = new NavMeshQuery(world, Allocator.Persistent);

            availableSlots = new ConcurrentQueue <int>();
            ProgressQueue  = new NativeList <PathQueryData>(MaxQueries, Allocator.Persistent);
            handles        = new List <JobHandle>(MaxQueries);
            takenSlots     = new List <int>(MaxQueries);
            statuses       = new List <NativeArray <int> >(MaxQueries);
            results        = new List <NativeArray <NavMeshLocation> >(MaxQueries);
            jobs           = new Dictionary <int, UpdateQueryStatusJob>(MaxQueries);
            queries        = new NavMeshQuery[MaxQueries];
            queryDatas     = new PathQueryData[MaxQueries];
            for (int i = 0; i < MaxQueries; i++)
            {
                handles.Add(new JobHandle());
                statuses.Add(new NativeArray <int>(3, Allocator.Persistent));
                results.Add(new NativeArray <NavMeshLocation>(MaxPathSize, Allocator.Persistent));
                availableSlots.Enqueue(i);
            }

            QueryQueue = new ConcurrentQueue <PathQueryData>();
        }
        protected override void OnUpdate()
        {
            var allQueriesIdle = activeJobs.Length == 0;

            if (reconfigurationPending && allQueriesIdle)
            {
                Reconfigure();
                reconfigurationPending = false;
            }

            var newActiveJobs = new List <UpdateNavMeshQueryJob>();

            Entities.ForEach((Entity entity, ref QueryPathRequestData request) =>
            {
                if (idleQueries.Any())
                {
                    newActiveJobs.Add(new UpdateNavMeshQueryJob()
                    {
                        navMeshQuery           = idleQueries.Dequeue(),
                        queryPathRequest       = request,
                        queryingEntity         = entity,
                        isFirstUpdate          = true,
                        numIterationsPerUpdate = MaxIterationsPerUpdateDefault,
                        areaCosts    = MakeAreaCosts(request.areaCostIndex),
                        updateResult = new NativeArray <UpdateNavMeshQueryJob.UpdateResult>(1, Allocator.Persistent),
                        pathResult   = new NativeArray <float3>(MaxPathLength, Allocator.Persistent)
                    });

                    PostUpdateCommands.RemoveComponent <QueryPathRequestData>(entity);
                }
            });

            activeJobs = activeJobs.Concat(newActiveJobs).ToArray();
            var activeJobHandles = activeJobs.Select(x => x.Schedule()).ToArray();

            // wait for the jobs to finish
            using (var handles = new NativeArray <JobHandle>(activeJobHandles, Allocator.Temp))
            {
                var combinedJobs = JobHandle.CombineDependencies(handles);
                NavMeshWorld.GetDefaultWorld().AddDependency(combinedJobs);
                combinedJobs.Complete();
            }

            var jobsToContinue = new List <int>();

            for (var activeJobIdx = 0; activeJobIdx < activeJobs.Length; ++activeJobIdx)
            {
                var updateResult = activeJobs[activeJobIdx].updateResult[0];

                if (updateResult.queryStatus != PathQueryStatus.InProgress)
                {
                    if ((updateResult.queryStatus == PathQueryStatus.Success) || (updateResult.queryStatus == PathQueryStatus.PartialResult))
                    {
                        var buffer = PostUpdateCommands.AddBuffer <PathVertexResultData>(activeJobs[activeJobIdx].queryingEntity);

                        buffer.ResizeUninitialized(updateResult.pathResultLength);

                        for (int resultVertexIndex = 0; resultVertexIndex < updateResult.pathResultLength; resultVertexIndex++)
                        {
                            buffer[resultVertexIndex] = activeJobs[activeJobIdx].pathResult[resultVertexIndex];
                        }
                    }

                    if (activeJobs[activeJobIdx].areaCosts.IsCreated)
                    {
                        activeJobs[activeJobIdx].areaCosts.Dispose();
                    }

                    if (activeJobs[activeJobIdx].pathResult.IsCreated)
                    {
                        activeJobs[activeJobIdx].pathResult.Dispose();
                    }

                    if (activeJobs[activeJobIdx].updateResult.IsCreated)
                    {
                        activeJobs[activeJobIdx].updateResult.Dispose();
                    }

                    idleQueries.Enqueue(activeJobs[activeJobIdx].navMeshQuery);
                }
                else
                {
                    activeJobs[activeJobIdx].isFirstUpdate = false;
                    jobsToContinue.Add(activeJobIdx);
                }
            }

            activeJobs = jobsToContinue.Select(x => activeJobs[x]).ToArray();
        }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (formations.Length == 0)
        {
            return(inputDeps);
        }

        var assign = new AssignFormationSpeed
        {
            navigators    = formations.navigators,
            integrityData = formations.integrityData,
            formations    = formations.data
        };

        Profiler.BeginSample("Alloc");
        var pathFollow = new MinionFollowPath
        {
            entities        = minions.entities,
            newPathQueries  = newPathQueries,
            pathsInfo       = minions.pathsInfo,
            minionPaths     = minions.paths,
            minionTargets   = minions.targets,
            navMeshLocation = minions.navMeshLocation,
            maxPathSize     = SimulationState.MaxPathSize
        };
        Entity rmEnt;

        while (completePathQueries.TryDequeue(out rmEnt))
        {
            // TODO: avoid linear search
            for (int i = 0; i < findingEntities.Length; ++i)
            {
                if (findingEntities[i] == rmEnt)
                {
                    findingEntities.RemoveAtSwapBack(i);
                    queryIndexFree.Add(queryIndexUsed[i]);
                    queryIndexUsed.RemoveAtSwapBack(i);
                    break;
                }
            }
        }
        for (int i = 0; i < findingEntities.Length; ++i)
        {
            if (!entityManager.Exists(findingEntities[i]))
            {
                findingEntities.RemoveAtSwapBack(i);
                queryIndexFree.Add(queryIndexUsed[i]);
                queryIndexUsed.RemoveAtSwapBack(i);
                --i;
            }
        }
        // Refill with new path queries
        while (findingEntities.Length < MaxNavMeshQueries && newPathQueries.Count > 0)
        {
            // TODO: should use some kind of round robin to make sure all minions get a chance to path find
            findingEntities.Add(newPathQueries.Dequeue());
            queryIndexUsed.Add(queryIndexFree[queryIndexFree.Length - 1]);
            queryIndexFree.RemoveAtSwapBack(queryIndexFree.Length - 1);
        }

        //Debug.Assert(queryIndexFree.Length + queryIndexUsed.Length == MaxNavMeshQueries);

        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        newPathQueries.Clear();
        var findHandle = inputDeps;

        for (int i = 0; i < findingEntities.Length; ++i)
        {
            var pathFind = new MinionPathFind
            {
                query  = queries[queryIndexUsed[i]],
                entity = findingEntities[i],
                completePathQueries = completePathQueries,

                pathsInfo       = minionPathsInfo,
                minionPaths     = minionPaths,
                navMeshLocation = minionNavMeshLocation,
                maxPathSize     = SimulationState.MaxPathSize,
                //costs = costs,
                polygons          = new NativeArray <PolygonId>(100, Allocator.TempJob),
                straightPath      = new NativeArray <NavMeshLocation>(SimulationState.MaxPathSize, Allocator.TempJob),
                straightPathFlags = new NativeArray <StraightPathFlags>(SimulationState.MaxPathSize, Allocator.TempJob),
                vertexSide        = new NativeArray <float>(SimulationState.MaxPathSize, Allocator.TempJob)
            };
            // TODO: figure out how to run these in parallel, they write to different parts of the same array
            findHandle = pathFind.Schedule(findHandle);
            navMeshWorld.AddDependency(findHandle);
        }
        if (findingEntities.Length > 0)
        {
            navMeshWorld.AddDependency(findHandle);
        }
        Profiler.EndSample();

        var pathFindFence = pathFollow.Schedule(minions.Length, SimulationState.BigBatchSize, findHandle); // prepare targets fence?
        var assignFence   = assign.Schedule(formations.Length, SimulationState.BigBatchSize, inputDeps);

        navMeshWorld.AddDependency(pathFindFence);

        return(JobHandle.CombineDependencies(assignFence, pathFindFence));
    }
Exemple #21
0
    protected override void OnCreateManager(int capacity)
    {
        var world = NavMeshWorld.GetDefaultWorld();

        query = new NavMeshQuery(world, Allocator.Persistent);
    }
 protected override void OnCreateManager(int capacity)
 {
     navMeshQuery    = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent, 128);
     indexMap        = new NativeMultiHashMap <int, int>(100 * 1024, Allocator.Persistent);
     nextPositionMap = new NativeMultiHashMap <int, float3>(100 * 1024, Allocator.Persistent);
 }
Exemple #23
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (!Application.isPlaying)
        {
            return(inputDeps);
        }

        if (minions.Length == 0)
        {
            return(inputDeps);                             // I still hate this initialization issues
        }
        // TODO maybe fix native array
        var forwardsBuffer  = new NativeArray <Vector3>(minions.Length, Allocator.TempJob);
        var positionsBuffer = new NativeArray <Vector3>(minions.Length, Allocator.TempJob);
        var locationsBuffer = new NativeArray <NavMeshLocation>(minions.Length, Allocator.TempJob);


        // ============ JOB CREATION ===============
        var minionBehaviorJob = new MinionBehaviourJob
        {
            rigidbodyData    = minions.velocities,
            targetPositions  = minions.targets,
            transforms       = minions.transforms,
            minionAttackData = minions.attackData,
            minionData       = minions.minions,
            animatorData     = minions.animationData,
            navMeshLocations = minions.navMeshLocations,
            forwardsBuffer   = forwardsBuffer,
            positionsBuffer  = positionsBuffer,
            locationsBuffer  = locationsBuffer,
            archerAttackTime = SimulationSettings.Instance.ArcherAttackTime,
            dt         = Time.deltaTime,
            randomizer = Time.frameCount,
        };

        var minionBehaviorMoveJob = new MinionBehaviourMoveJob
        {
            positionsBuffer = positionsBuffer,
            locationsBuffer = locationsBuffer,
            query           = moveLocationQuery
        };

        var minionBehaviorSyncbackJob = new MinionBehaviourSyncbackJob
        {
            transforms       = minions.transforms,
            navMeshLocations = minions.navMeshLocations,
            forwardsBuffer   = forwardsBuffer,
            positionsBuffer  = positionsBuffer,
            locationsBuffer  = locationsBuffer
        };


        var minionBehaviorJobFence = minionBehaviorJob.ScheduleBatch(minions.Length, SimulationState.BigBatchSize,
                                                                     inputDeps);

        minionBehaviorJobFence = minionBehaviorMoveJob.ScheduleBatch(minions.Length, SimulationState.BigBatchSize, minionBehaviorJobFence);
        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        navMeshWorld.AddDependency(minionBehaviorJobFence);
        minionBehaviorJobFence = minionBehaviorSyncbackJob.ScheduleBatch(minions.Length, SimulationState.BigBatchSize, minionBehaviorJobFence);

        return(minionBehaviorJobFence);
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        //
        // Prepare data on the main thread
        //
        m_AfterQueriesCleanup.Complete();
        m_AfterMovedRequestsForgotten.Complete();

        if (m_QueryQueues.Length < k_QueryCount)
        {
            var world = NavMeshWorld.GetDefaultWorld();
            if (world.IsValid())
            {
                DisposeEverything();
                Initialize(m_InitialCapacity);
            }
        }

        if (m_Crowd.agentNavigators.Length == 0)
        {
            return(inputDeps);
        }

        var missingAgents = m_Crowd.agentNavigators.Length - m_PlanPathForAgent.Length;

        if (missingAgents > 0)
        {
            AddAgents(missingAgents);
        }

#if DEBUG_CROWDSYSTEM_ASSERTS
        Debug.Assert(m_Crowd.agents.Length <= m_PathRequestIdForAgent.Length && m_Crowd.agents.Length <= m_PlanPathForAgent.Length,
                     "" + m_Crowd.agents.Length + " agents, " + m_PathRequestIdForAgent.Length + " path request IDs, " + m_PlanPathForAgent.Length + " slots for WantsPath");

        if (dbgCheckRequests)
        {
            var rangeEnd = m_PathRequestsRange[k_Start] + m_PathRequestsRange[k_Count];
            for (var i = m_PathRequestsRange[k_Start]; i < rangeEnd; i++)
            {
                Debug.Assert(m_PathRequests[i].uid != PathQueryQueueEcs.RequestEcs.invalidId, "Path request " + i + " should have a valid unique ID");
            }
        }
#endif

#if DEBUG_CROWDSYSTEM
        if (drawDebug)
        {
            DrawDebug();
            DrawRequestsDebug();
        }
#endif

        var requestsPerQueue = int.MaxValue;
        if (m_QueryQueues.Length > 0)
        {
            var existingRequests = m_QueryQueues.Sum(queue => queue.GetRequestCount());
            var requestCount     = existingRequests + m_PathRequestsRange[k_Count];
            requestsPerQueue = requestCount / m_QueryQueues.Length;
            if (requestCount % m_QueryQueues.Length != 0 || requestsPerQueue == 0)
            {
                requestsPerQueue += 1;
            }
        }

        for (var i = 0; i < m_QueryQueues.Length; i++)
        {
            m_IsEmptyQueryQueue[i] = m_QueryQueues[i].IsEmpty();
        }

#if DEBUG_CROWDSYSTEM_ASSERTS
        if (dbgCheckRequests)
        {
            for (var i = 0; i < m_PathRequestIdForAgent.Length; i++)
            {
                var requestIdForThisAgent = m_PathRequestIdForAgent[i];
                if (requestIdForThisAgent == PathQueryQueueEcs.RequestEcs.invalidId)
                {
                    continue;
                }

                var existsInQ = false;
                var rangeEnd  = m_PathRequestsRange[k_Start] + m_PathRequestsRange[k_Count];
                for (var r = m_PathRequestsRange[k_Start]; r < rangeEnd; r++)
                {
                    var reqInQ = m_PathRequests[r];
                    existsInQ = reqInQ.uid == requestIdForThisAgent;
                    if (existsInQ)
                    {
                        break;
                    }
                }
                if (!existsInQ)
                {
                    foreach (var query in m_QueryQueues)
                    {
                        existsInQ = query.DbgRequestExistsInQueue(requestIdForThisAgent);
                        if (existsInQ)
                        {
                            break;
                        }
                    }
                }
                Debug.Assert(existsInQ, "The request for agent " + i + " doesn't exist in any query queue anymore. UID=" + requestIdForThisAgent);
            }
        }
#endif


        //
        // Begin scheduling jobs
        //

        //var pathNeededJob = new CheckPathNeededJob
        //{
        //    agentNavigators = m_Crowd.agentNavigators,
        //    planPathForAgent = m_PlanPathForAgent,
        //    pathRequestIdForAgent = m_PathRequestIdForAgent,
        //    paths = m_AgentPaths.GetReadOnlyData()
        //};
        //var afterPathNeedChecked = pathNeededJob.Schedule(m_Crowd.agents.Length, k_AgentsBatchSize, inputDeps);

        var makeRequestsJob = new MakePathRequestsJob
        {
            query                 = m_NavMeshQuery,
            agents                = m_Crowd.agents,
            agentNavigators       = m_Crowd.agentNavigators,
            planPathForAgent      = m_EmptyPlanPathForAgent,
            pathRequestIdForAgent = m_PathRequestIdForAgent,
            pathRequests          = m_PathRequests,
            pathRequestsRange     = m_PathRequestsRange,
            currentAgentIndex     = m_CurrentAgentIndex,
            uniqueIdStore         = m_UniqueIdStore
        };
        var afterRequestsCreated = makeRequestsJob.Schedule(inputDeps);

        var afterRequestsMovedToQueries = afterRequestsCreated;
        if (m_QueryQueues.Length > 0)
        {
            foreach (var queue in m_QueryQueues)
            {
                var enqueuingJob = new EnqueueRequestsInQueriesJob
                {
                    pathRequests       = m_PathRequests,
                    pathRequestsRange  = m_PathRequestsRange,
                    maxRequestsInQueue = requestsPerQueue,
                    queryQueue         = queue
                };
                afterRequestsMovedToQueries = enqueuingJob.Schedule(afterRequestsMovedToQueries);
            }
        }

        var forgetMovedRequestsJob = new ForgetMovedRequestsJob
        {
            pathRequests      = m_PathRequests,
            pathRequestsRange = m_PathRequestsRange
        };
        m_AfterMovedRequestsForgotten = forgetMovedRequestsJob.Schedule(afterRequestsMovedToQueries);

        var queriesScheduled = 0;
        for (var i = 0; i < m_QueryJobs.Length; ++i)
        {
            if (m_IsEmptyQueryQueue[i])
            {
                continue;
            }

            m_AfterQueriesProcessed[i] = m_QueryJobs[i].Schedule(afterRequestsMovedToQueries);
            queriesScheduled++;
        }
        var afterQueriesProcessed = queriesScheduled > 0 ? JobHandle.CombineDependencies(m_AfterQueriesProcessed) : afterRequestsMovedToQueries;

        var afterPathsAdded = afterQueriesProcessed;
        foreach (var queue in m_QueryQueues)
        {
            var resultsJob = new ApplyQueryResultsJob {
                queryQueue = queue, paths = m_Crowd.paths, agentNavigators = m_Crowd.agentNavigators
            };
            afterPathsAdded = resultsJob.Schedule(afterPathsAdded);
        }

        var advance = new AdvancePathJob {
            agents = m_Crowd.agents, agentNavigators = m_Crowd.agentNavigators, paths = m_Crowd.paths
        };
        var afterPathsTrimmed = advance.Schedule(m_Crowd.agents.Length, k_AgentsBatchSize, afterPathsAdded);

        const int maxCornersPerAgent = 2;
        var       totalCornersBuffer = m_Crowd.agents.Length * maxCornersPerAgent;
        var       vel = new UpdateVelocityJob
        {
            query             = m_NavMeshQuery,
            agents            = m_Crowd.agents,
            agentNavigators   = m_Crowd.agentNavigators,
            paths             = m_Crowd.paths,
            straightPath      = new NativeArray <NavMeshLocation>(totalCornersBuffer, Allocator.TempJob),
            straightPathFlags = new NativeArray <StraightPathFlags>(totalCornersBuffer, Allocator.TempJob),
            vertexSide        = new NativeArray <float>(totalCornersBuffer, Allocator.TempJob)
        };
        var afterVelocitiesUpdated = vel.Schedule(m_Crowd.agents.Length, k_AgentsBatchSize, afterPathsTrimmed);

        var move = new MoveLocationsJob {
            query = m_NavMeshQuery, agents = m_Crowd.agents, dt = Time.deltaTime
        };
        var afterAgentsMoved = move.Schedule(m_Crowd.agents.Length, k_AgentsBatchSize, afterVelocitiesUpdated);

#if DEBUG_CROWDSYSTEM_LOGS
        if (dbgPrintRequests)
        {
            afterPathsAdded.Complete();
            PrintRequestsDebug();
        }
#endif

        var cleanupFence = afterPathsAdded;
        foreach (var queue in m_QueryQueues)
        {
            var queryCleanupJob = new QueryCleanupJob
            {
                queryQueue            = queue,
                pathRequestIdForAgent = m_PathRequestIdForAgent
            };
            cleanupFence          = queryCleanupJob.Schedule(cleanupFence);
            m_AfterQueriesCleanup = cleanupFence;
        }

        //NavMeshWorld.GetDefaultWorld().AddDependency(afterAgentsMoved);

        return(afterAgentsMoved);
    }
        protected override void OnUpdate()
        {
            var commandBuffer            = barrier.CreateCommandBuffer().AsParallelWriter();
            var localToWorldFromEntity   = GetComponentDataFromEntity <LocalToWorld>(true);
            var translationFromEntity    = GetComponentDataFromEntity <Translation>(true);
            var jumpingFromEntity        = GetComponentDataFromEntity <NavJumping>(true);
            var pathBufferFromEntity     = GetBufferFromEntity <NavPathBufferElement>();
            var jumpBufferFromEntity     = GetBufferFromEntity <NavJumpBufferElement>();
            var navMeshQueryPointerArray = World.GetExistingSystem <NavMeshQuerySystem>().PointerArray;

            Entities
            .WithNone <NavHasProblem>()
            .WithAll <NavPlanning, LocalToParent>()
            .WithReadOnly(localToWorldFromEntity)
            .WithReadOnly(jumpingFromEntity)
            .WithNativeDisableParallelForRestriction(pathBufferFromEntity)
            .WithNativeDisableParallelForRestriction(jumpBufferFromEntity)
            .WithNativeDisableParallelForRestriction(navMeshQueryPointerArray)
            .ForEach((Entity entity, int entityInQueryIndex, int nativeThreadIndex, ref NavAgent agent, in Parent surface) =>
            {
                if (
                    surface.Value.Equals(Entity.Null) ||
                    agent.DestinationSurface.Equals(Entity.Null) ||
                    !localToWorldFromEntity.HasComponent(surface.Value) ||
                    !localToWorldFromEntity.HasComponent(agent.DestinationSurface)
                    )
                {
                    return;
                }

                var agentPosition    = localToWorldFromEntity[entity].Position;
                var worldPosition    = agentPosition;
                var worldDestination = NavUtil.MultiplyPoint3x4(
                    localToWorldFromEntity[agent.DestinationSurface].Value,
                    agent.LocalDestination
                    );

                var jumping = jumpingFromEntity.HasComponent(entity);

                if (jumping)
                {
                    worldPosition    = worldDestination;
                    worldDestination = agentPosition;
                }

                var navMeshQueryPointer = navMeshQueryPointerArray[nativeThreadIndex];
                UnsafeUtility.CopyPtrToStructure(navMeshQueryPointer.Value, out NavMeshQuery navMeshQuery);

                var status = navMeshQuery.BeginFindPath(
                    navMeshQuery.MapLocation(worldPosition, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID),
                    navMeshQuery.MapLocation(worldDestination, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID),
                    NavMesh.AllAreas
                    );

                while (NavUtil.HasStatus(status, PathQueryStatus.InProgress))
                {
                    status = navMeshQuery.UpdateFindPath(
                        NavConstants.ITERATION_MAX,
                        out int iterationsPerformed
                        );
                }

                if (!NavUtil.HasStatus(status, PathQueryStatus.Success))
                {
                    commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity);
                    commandBuffer.RemoveComponent <NavNeedsDestination>(entityInQueryIndex, entity);
                    commandBuffer.AddComponent <NavHasProblem>(entityInQueryIndex, entity, new NavHasProblem
                    {
                        Value = status
                    });

                    return;
                }

                navMeshQuery.EndFindPath(out int pathLength);

                var polygonIdArray = new NativeArray <PolygonId>(
                    NavConstants.PATH_NODE_MAX,
                    Allocator.Temp
                    );

                navMeshQuery.GetPathResult(polygonIdArray);

                var len               = pathLength + 1;
                var straightPath      = new NativeArray <NavMeshLocation>(len, Allocator.Temp);
                var straightPathFlags = new NativeArray <StraightPathFlags>(len, Allocator.Temp);
                var vertexSide        = new NativeArray <float>(len, Allocator.Temp);
                var straightPathCount = 0;

                status = PathUtils.FindStraightPath(
                    navMeshQuery,
                    worldPosition,
                    worldDestination,
                    polygonIdArray,
                    pathLength,
                    ref straightPath,
                    ref straightPathFlags,
                    ref vertexSide,
                    ref straightPathCount,
                    NavConstants.PATH_NODE_MAX
                    );

                var jumpBuffer = !jumpBufferFromEntity.HasComponent(entity) ? commandBuffer.AddBuffer <NavJumpBufferElement>(entityInQueryIndex, entity) : jumpBufferFromEntity[entity];
                var pathBuffer = !pathBufferFromEntity.HasComponent(entity) ? commandBuffer.AddBuffer <NavPathBufferElement>(entityInQueryIndex, entity) : pathBufferFromEntity[entity];

                if (jumping)
                {
                    var lastValidPoint = float3.zero;
                    for (int i = 0; i < straightPath.Length; ++i)
                    {
                        if (navMeshQuery.IsValid(straightPath[i].polygon))
                        {
                            lastValidPoint = straightPath[i].position;
                        }
                        else
                        {
                            break;
                        }
                    }

                    jumpBuffer.Add(
                        NavUtil.MultiplyPoint3x4(
                            math.inverse(localToWorldFromEntity[agent.DestinationSurface].Value),
                            (float3)lastValidPoint + agent.Offset
                            )
                        );

                    if (jumpBuffer.Length > 0)
                    {
                        commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity);
                        commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity);
                    }
                }
                else if (status == PathQueryStatus.Success)
                {
                    pathBuffer.Clear();
                    agent.PathBufferIndex = 0;

                    for (int i = 0; i < straightPathCount; ++i)
                    {
                        pathBuffer.Add(
                            NavUtil.MultiplyPoint3x4(
                                math.inverse(localToWorldFromEntity[surface.Value].Value),
                                (float3)straightPath[i].position + agent.Offset
                                )
                            );
                    }

                    if (pathBuffer.Length > 0)
                    {
                        commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity);
                        commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity);
                    }
                }

                polygonIdArray.Dispose();
                straightPath.Dispose();
                straightPathFlags.Dispose();
                vertexSide.Dispose();
            })
            .WithName("NavPlanJob")
            .ScheduleParallel();

            NavMeshWorld.GetDefaultWorld().AddDependency(Dependency);
            barrier.AddJobHandleForProducer(Dependency);
        }