コード例 #1
0
        public static JobHandle GetChangedChunks <T>(
            this EntityQuery query,
            ComponentSystemBase system,
            Allocator allocator,
            ref NativeQueue <VTuple <int, int> > .ParallelWriter changedEntitySlices,
            JobHandle inputDeps,
            bool changeAll = false)
            where T : struct, IComponentData
        {
            var chunks = query.CreateArchetypeChunkArrayAsync(allocator, out var createChunksHandle);

            inputDeps = JobHandle.CombineDependencies(inputDeps, createChunksHandle);
            var indicesState = new NativeArray <int>(chunks.Length, Allocator.TempJob);

            inputDeps = new MemsetNativeArray <int> {
                Source = indicesState,
                Value  = -1
            }.Schedule(indicesState.Length, 64, inputDeps);
            inputDeps = new GatherChunkChanged <T> {
                ChunkType         = system.GetArchetypeChunkComponentType <T>(true),
                ChangedIndices    = indicesState,
                LastSystemVersion = system.LastSystemVersion,
                ForceChange       = changeAll
            }.Schedule(query, inputDeps);

            inputDeps = new ExtractChangedSlicesFromChunks {
                Source = indicesState,
                Chunks = chunks,
                Slices = changedEntitySlices
            }.Schedule(indicesState.Length, 64, inputDeps);
            inputDeps = indicesState.Dispose(inputDeps);
            return(inputDeps);
        }
コード例 #2
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (m_BoardQuery.CalculateEntityCount() <= 0)
        {
            return(inputDeps);
        }

        var boardEntity  = m_BoardQuery.GetSingletonEntity();
        var board        = m_BoardQuery.GetSingleton <LbBoard>();
        var bufferLookup = GetBufferFromEntity <LbCatMap>();

        var buffer      = bufferLookup[boardEntity];
        var bufferArray = buffer.AsNativeArray();

        var handle = new MemsetNativeArray <LbCatMap>()
        {
            Source = bufferArray,
            Value  = new LbCatMap()
        }.Schedule(bufferArray.Length, 32, inputDeps);

        handle = new CatMapJob
        {
            Size         = board.SizeY,
            Buffer       = bufferArray,
            Translations = m_CatQuery.ToComponentDataArray <Translation>(Allocator.TempJob)
        }.Schedule(handle);

        handle = new CollisionJob
        {
            Size = board.SizeY,
            CatLocationBuffer = bufferArray,
            Queue             = m_Queue.AsParallelWriter(),
        }.Schedule(this, handle);

        handle = new CollisionCleanJob
        {
            Queue         = m_Queue,
            CommandBuffer = m_Barrier.CreateCommandBuffer(),
        }.Schedule(handle);

        m_Barrier.AddJobHandleForProducer(handle);

        return(handle);
    }
コード例 #3
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var board            = m_BoardQuery.GetSingleton <LbBoard>();
        var entitiesSpawners = m_ArrowSpawerQuery.ToEntityArray(Allocator.TempJob);
        var entitiesArrows   = m_ArrowsQuery.ToEntityArray(Allocator.TempJob);
        var arrowSpawners    = m_ArrowSpawerQuery.ToComponentDataArray <LbArrowSpawner>(Allocator.TempJob);
        var boardEntity      = m_BoardQuery.GetSingletonEntity();
        var arrowsQuery      = m_ArrowsQuery.ToComponentDataArray <LbArrow>(Allocator.TempJob);
        var bufferLookup     = GetBufferFromEntity <LbArrowDirectionMap>();
        var buffer           = bufferLookup[boardEntity];
        var bufferArray      = buffer.AsNativeArray();
        var commandBuffer    = m_EntityCommandBufferSystem.CreateCommandBuffer();

        var handle = new MemsetNativeArray <LbArrowDirectionMap>()
        {
            Source = bufferArray,
            Value  = new LbArrowDirectionMap()
        }.Schedule(bufferArray.Length, bufferArray.Length, inputDeps);

        handle = new SpawnArrow
        {
            Entities      = entitiesSpawners,
            ArrowSpawners = arrowSpawners,
            CommandBuffer = commandBuffer
        }.Schedule(handle);


        handle = new WriteArroMap
        {
            Size              = board.SizeY,
            Entities          = entitiesArrows,
            LbArrows          = arrowsQuery,
            ArrowDirectionMap = bufferArray,
        }.Schedule(handle);

        m_EntityCommandBufferSystem.AddJobHandleForProducer(handle);

        return(handle);
    }
コード例 #4
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var boardEntity  = m_Query.GetSingletonEntity();
        var board        = m_Query.GetSingleton <LbBoard>();
        var bufferLookup = GetBufferFromEntity <LbCatMap>();

        var buffer      = bufferLookup[boardEntity];
        var bufferArray = buffer.AsNativeArray();

        var cleanJobHandle = new MemsetNativeArray <LbCatMap>()
        {
            Source = bufferArray,
            Value  = new LbCatMap()
        }.Schedule(bufferArray.Length, 32, inputDeps);

        var jobHandle = new CatMapJob
        {
            Size         = board.SizeY,
            Buffer       = bufferArray,
            Translations = m_CatQuery.ToComponentDataArray <Translation>(Allocator.TempJob)
        }.Schedule(cleanJobHandle);

        return(jobHandle);
    }
コード例 #5
0
        private void InitJobData()
        {
            float deltaTime = 0f;

            #region JobDataSetup
            //
            //Init all job data here. Declare roughly inline. Optional brackets for things that can be parallel
            //

            #region ResetBeginningOfSimFrame

            _jobDataResetBlobAccelerations = new MemsetNativeArray <float2> {
                Source = _blobAccelerations, Value = float2.zero
            };

            _jobDataResetCursorAccelerations = new MemsetNativeArray <float2> {
                Source = _cursorAccelerations, Value = float2.zero
            };

            _jobDataResetGooGroups = new MemsetNativeArray <int> {
                Source = _blobGroupIDs, Value = -1
            };
            //   _jobDataCopyBlobRadii = new MemsetNativeArray<float> {Source = _blobRadii, Value = GooPhysics.MaxSpringDistance};

            _jobDataCopyBlobInfoToFloat3 = new JobCopyBlobInfoToFloat3
            {
                BlobPos       = _blobPositions,
                BlobTeams     = _blobTeamIDs,
                BlobPosFloat3 = _blobPositionsV3
            };


            _jobBuildKnnTree = new KnnRebuildJob(_knnContainer);

            // Initialize all the range query results
            _blobKNNNearestNeighbourQueryResults = new NativeArray <RangeQueryResult>(_blobPositions.Length, Allocator.Persistent);

            _uniqueBlobEdges        = new NativeMultiHashMap <int, int>(_blobPositions.Length * 40, Allocator.Persistent);
            _uniqueBlobEdgesHashSet = new NativeHashSet <long>(_blobPositions.Length * 40, Allocator.Persistent);
            // Each range query result object needs to declare upfront what the maximum number of points in range is


            for (int i = 0; i < _blobKNNNearestNeighbourQueryResults.Length; ++i)
            {
                _blobKNNNearestNeighbourQueryResults[i] = new RangeQueryResult(GooPhysics.MaxNearestNeighbours, Allocator.Persistent);
            }


            _jobDataQueryNearestNeighboursKNN = new QueryRangesBatchJob {
                m_container      = _knnContainer,
                m_queryPositions = _blobPositionsV3,
                m_SearchRadius   = GooPhysics.MaxSpringDistance,

                Results = _blobKNNNearestNeighbourQueryResults
            };
            #endregion //ResetBeginningOfSimFrame

            #region Updates
            //build edges with existing positions


            _jobDataFloodFillGroupIDsKnn = new JobFloodFillIDsKnn()
            {
                BlobNearestNeighbours = _blobKNNNearestNeighbourQueryResults,
                GroupIDs   = _blobGroupIDs,
                FloodQueue = _floodQueue,
                NumGroups  = _numGroups //for safety.don't want divide by zero
            };

            _jobDataFloodFillGroupIDsMultiHashMap = new JobFloodFillIDsUniqueEdges()
            {
                Springs    = _uniqueBlobEdges,
                GroupIDs   = _blobGroupIDs,
                FloodQueue = _floodQueue,
                NumGroups  = _numGroups //for safety.don't want divide by zero
            };

            _jobDataSpringForcesUsingKnn = new JobSpringForceUsingKNNResults
            {
                AccelerationAccumulator = _blobAccelerations,
                BlobNearestNeighbours   = _blobKNNNearestNeighbourQueryResults,
                MaxEdgeDistanceRaw      = GooPhysics.MaxSpringDistance * 2.0f,
                SpringConstant          = GooPhysics.SpringForce,
                DampeningConstant       = GooPhysics.DampeningConstant,
                Positions = _blobPositions,
                Velocity  = _blobVelocities,
            };

            _jobCompileDataUniqueEdges = new JobCompileUniqueEdges
            {
                BlobNearestNeighbours = _blobKNNNearestNeighbourQueryResults,
                Edges       = _uniqueBlobEdges.AsParallelWriter(),
                UniqueEdges = _uniqueBlobEdgesHashSet.AsParallelWriter()
            };

            _jobDataSpringForcesUniqueEdges = new JobUniqueSpringForce
            {
                AccelerationAccumulator = _blobAccelerations,
                Springs            = _uniqueBlobEdges,
                MaxEdgeDistanceRaw = GooPhysics.MaxSpringDistance * 2.0f,
                SpringConstant     = GooPhysics.SpringForce,
                DampeningConstant  = GooPhysics.DampeningConstant,
                Positions          = _blobPositions,
                Velocity           = _blobVelocities,
            };

            _jobDataFluidInfluence = new JobVelocityInfluenceFalloff
            {
                BlobPositions         = _blobPositions,
                BlobVelocities        = _blobVelocities,
                BlobNearestNeighbours = _blobKNNNearestNeighbourQueryResults,
                InfluenceRadius       = _blobRadii,
                InfluenceModulator    = GooPhysics.FluidInfluenceModulator,
                BlobAccelAccumulator  = _blobAccelerations
            };

            //update cursor accel based on inputs
            //todo: could be CopyTo?

            //_cursorInputDeltas.CopyTo(_cursorAccelerations);
            _jobDataSetCursorAcceleration = new JobSetAcceleration
            {
                ValueToSet = _cursorInputDeltas,
                AccumulatedAcceleration = _cursorAccelerations
            };

            //update cursor friction
            _jobDataApplyCursorFriction = new JobApplyLinearAndConstantFriction
            {
                DeltaTime               = deltaTime,
                LinearFriction          = CursorLinearFriction,
                ConstantFriction        = CursorConstantFriction,
                AccumulatedAcceleration = _cursorAccelerations,
                Velocity = _cursorVelocities
            };


            _jobDataUpdateCursorPositions = new JobApplyAcceelrationAndVelocity
            {
                DeltaTime = deltaTime,
                AccumulatedAcceleration = _cursorAccelerations,
                VelocityInAndOut        = _cursorVelocities,
                PositionInAndOut        = _cursorPositions
            };

            //Now we can update the blobs with the new state of the cursors
            _jobDataCursorsInfluenceBlobs = new JobCursorsInfluenceBlobs
            {
                CursorPositions      = _cursorPositions,
                CursorVelocities     = _cursorVelocities,
                CursorRadius         = _cursorRadii,
                BlobPositions        = _blobPositions,
                BlobAccelAccumulator = _blobAccelerations
            };

            _jobDataApplyFrictionToBlobs = new JobApplyLinearAndConstantFriction
            {
                DeltaTime = deltaTime,
                //TODO: maybe I want friction based on acceleration (t*t) since that's the freshest part of this.
                //So, constant + linear(t) + accelerative (t*t)
                LinearFriction          = GooPhysics.LinearFriction,
                ConstantFriction        = GooPhysics.ConstantFriction,
                AccumulatedAcceleration = _blobAccelerations,
                Velocity = _blobVelocities
            };

            //Blob sim gets updated
            _jobDataUpdateBlobPositions = new JobApplyAcceelrationAndVelocity
            {
                DeltaTime = deltaTime,
                AccumulatedAcceleration = _blobAccelerations,
                VelocityInAndOut        = _blobVelocities,
                PositionInAndOut        = _blobPositions
            };

            //Output

            _jobDataDebugColorisationInt = new JobDebugColorisationInt()
            {
                minVal = 0,
                maxVal = 10,
                values = _blobGroupIDs,
                colors = _blobColors,
            };

            _jobDataDebugColorisationKNNLength = new JobDebugColorisationKNNRangeQuery()
            {
                minVal = 0,
                maxVal = 10,
                values = _blobKNNNearestNeighbourQueryResults,
                colors = _blobColors,
            };

            /*  _jobDataDebugColorisationFloat = new JobDebugColorisationFloat
             * {
             *   minVal = 0,
             *   maxVal = 10,
             *   values = _blobEdgeCount,
             *   colors =_blobColors,
             * }*/

            _jobDataDebugColorisationFloat2Magnitude = new JobDebugColorisationFloat2XY
            {
                maxVal = 10,
                values = _blobVelocities,
                colors = _blobColors
            };

            _jobDataCopyBlobsToParticleSystem = new JopCopyBlobsToParticleSystem
            {
                colors     = _blobColors,
                positions  = _blobPositions,
                velocities = _blobVelocities
            };

            _jobDataCopyCursorsToTransforms = new JobCopyBlobsToTransforms
            {
                BlobPos = _cursorPositions
            };


            #region BoundsForCamera
            _jobDataCalculateAABB = new JobCalculateAABB()
            {
                Positions = _blobPositions,
                Bounds    = _overallGooBounds
            };
            #endregion // BoundsForCamera
            #endregion // Updates
            #endregion // JobDataSetup
        }
コード例 #6
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            EntityManager.GetAllUniqueSharedComponentData(m_UniqueTypes);

            var obstacleCount = m_ObstacleGroup.CalculateLength();
            var targetCount   = m_TargetGroup.CalculateLength();

            // Ignore typeIndex 0, can't use the default for anything meaningful.
            for (int typeIndex = 1; typeIndex < m_UniqueTypes.Count; typeIndex++)
            {
                var settings = m_UniqueTypes[typeIndex];
                m_BoidGroup.SetFilter(settings);

                var boidCount = m_BoidGroup.CalculateLength();

                var cacheIndex                = typeIndex - 1;
                var cellIndices               = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var hashMap                   = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);
                var cellObstacleDistance      = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellObstaclePositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellTargetPositionIndex   = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellCount                 = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);


                var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                             NativeArrayOptions.UninitializedMemory);
                var cellSeparation = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                              NativeArrayOptions.UninitializedMemory);
                var copyTargetPositions = new NativeArray <float3>(targetCount, Allocator.TempJob,
                                                                   NativeArrayOptions.UninitializedMemory);
                var copyObstaclePositions = new NativeArray <float3>(obstacleCount, Allocator.TempJob,
                                                                     NativeArrayOptions.UninitializedMemory);

                var initialCellAlignmentJob = new CopyHeadings
                {
                    headings = cellAlignment
                };
                var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(m_BoidGroup, inputDeps);

                var initialCellSeparationJob = new CopyPositions
                {
                    positions = cellSeparation
                };
                var initialCellSeparationJobHandle = initialCellSeparationJob.Schedule(m_BoidGroup, inputDeps);

                var copyTargetPositionsJob = new CopyPositions
                {
                    positions = copyTargetPositions
                };
                var copyTargetPositionsJobHandle = copyTargetPositionsJob.Schedule(m_TargetGroup, inputDeps);

                var copyObstaclePositionsJob = new CopyPositions
                {
                    positions = copyObstaclePositions
                };
                var copyObstaclePositionsJobHandle = copyObstaclePositionsJob.Schedule(m_ObstacleGroup, inputDeps);

                var nextCells = new PrevCells
                {
                    cellIndices               = cellIndices,
                    hashMap                   = hashMap,
                    copyObstaclePositions     = copyObstaclePositions,
                    copyTargetPositions       = copyTargetPositions,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount                 = cellCount
                };

                if (cacheIndex > (m_PrevCells.Count - 1))
                {
                    m_PrevCells.Add(nextCells);
                }
                else
                {
                    m_PrevCells[cacheIndex].hashMap.Dispose();
                    m_PrevCells[cacheIndex].cellIndices.Dispose();
                    m_PrevCells[cacheIndex].cellObstaclePositionIndex.Dispose();
                    m_PrevCells[cacheIndex].cellTargetPositionIndex.Dispose();
                    m_PrevCells[cacheIndex].copyTargetPositions.Dispose();
                    m_PrevCells[cacheIndex].copyObstaclePositions.Dispose();
                    m_PrevCells[cacheIndex].cellAlignment.Dispose();
                    m_PrevCells[cacheIndex].cellSeparation.Dispose();
                    m_PrevCells[cacheIndex].cellObstacleDistance.Dispose();
                    m_PrevCells[cacheIndex].cellCount.Dispose();
                }
                m_PrevCells[cacheIndex] = nextCells;

                var hashPositionsJob = new HashPositions
                {
                    hashMap    = hashMap.ToConcurrent(),
                    cellRadius = settings.CellRadius
                };
                var hashPositionsJobHandle = hashPositionsJob.Schedule(m_BoidGroup, inputDeps);

                var initialCellCountJob = new MemsetNativeArray <int>
                {
                    Source = cellCount,
                    Value  = 1
                };
                var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps);

                var initialCellBarrierJobHandle        = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
                var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);
                var mergeCellsBarrierJobHandle         = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle);

                var mergeCellsJob = new MergeCells
                {
                    cellIndices               = cellIndices,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount         = cellCount,
                    targetPositions   = copyTargetPositions,
                    obstaclePositions = copyObstaclePositions
                };
                var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

                var steerJob = new Steer
                {
                    cellIndices               = nextCells.cellIndices,
                    settings                  = settings,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount                 = cellCount,
                    targetPositions           = copyTargetPositions,
                    obstaclePositions         = copyObstaclePositions,
                    dt = Time.deltaTime,
                };
                var steerJobHandle = steerJob.Schedule(m_BoidGroup, mergeCellsJobHandle);

                inputDeps = steerJobHandle;
                m_BoidGroup.AddDependency(inputDeps);
            }
            m_UniqueTypes.Clear();

            return(inputDeps);
        }
コード例 #7
0
        protected override void OnUpdate()
        {
            var obstacleCount = m_ObstacleQuery.CalculateEntityCount();
            var targetCount   = m_TargetQuery.CalculateEntityCount();

            EntityManager.GetAllUniqueSharedComponentData(m_UniqueTypes);

            // Each variant of the Boid represents a different value of the SharedComponentData and is self-contained,
            // meaning Boids of the same variant only interact with one another. Thus, this loop processes each
            // variant type individually.
            for (int boidVariantIndex = 0; boidVariantIndex < m_UniqueTypes.Count; boidVariantIndex++)
            {
                var settings = m_UniqueTypes[boidVariantIndex];
                m_BoidQuery.AddSharedComponentFilter(settings);

                var boidCount = m_BoidQuery.CalculateEntityCount();

                if (boidCount == 0)
                {
                    // Early out. If the given variant includes no Boids, move on to the next loop.
                    // For example, variant 0 will always exit early bc it's it represents a default, uninitialized
                    // Boid struct, which does not appear in this sample.
                    m_BoidQuery.ResetFilter();
                    continue;
                }

                // The following calculates spatial cells of neighboring Boids
                // note: working with a sparse grid and not a dense bounded grid so there
                // are no predefined borders of the space.

                var hashMap     = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);
                var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellObstaclePositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellTargetPositionIndex   = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellCount            = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellObstacleDistance = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellAlignment        = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellSeparation       = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                var copyTargetPositions   = new NativeArray <float3>(targetCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyObstaclePositions = new NativeArray <float3>(obstacleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                // The following jobs all run in parallel because the same JobHandle is passed for their
                // input dependencies when the jobs are scheduled; thus, they can run in any order (or concurrently).
                // The concurrency is property of how they're scheduled, not of the job structs themselves.

                // These jobs extract the relevant position, heading component
                // to NativeArrays so that they can be randomly accessed by the `MergeCells` and `Steer` jobs.
                // These jobs are defined inline using the Entities.ForEach lambda syntax.
                var initialCellAlignmentJobHandle = Entities
                                                    .WithSharedComponentFilter(settings)
                                                    .WithName("InitialCellAlignmentJob")
                                                    .ForEach((int entityInQueryIndex, in LocalToWorld localToWorld) =>
                {
                    cellAlignment[entityInQueryIndex] = localToWorld.Forward;
                })
                                                    .ScheduleParallel(Dependency);

                var initialCellSeparationJobHandle = Entities
                                                     .WithSharedComponentFilter(settings)
                                                     .WithName("InitialCellSeparationJob")
                                                     .ForEach((int entityInQueryIndex, in LocalToWorld localToWorld) =>
                {
                    cellSeparation[entityInQueryIndex] = localToWorld.Position;
                })
                                                     .ScheduleParallel(Dependency);

                var copyTargetPositionsJobHandle = Entities
                                                   .WithName("CopyTargetPositionsJob")
                                                   .WithAll <BoidTarget>()
                                                   .WithStoreEntityQueryInField(ref m_TargetQuery)
                                                   .ForEach((int entityInQueryIndex, in LocalToWorld localToWorld) =>
                {
                    copyTargetPositions[entityInQueryIndex] = localToWorld.Position;
                })
                                                   .ScheduleParallel(Dependency);

                var copyObstaclePositionsJobHandle = Entities
                                                     .WithName("CopyObstaclePositionsJob")
                                                     .WithAll <BoidObstacle>()
                                                     .WithStoreEntityQueryInField(ref m_ObstacleQuery)
                                                     .ForEach((int entityInQueryIndex, in LocalToWorld localToWorld) =>
                {
                    copyObstaclePositions[entityInQueryIndex] = localToWorld.Position;
                })
                                                     .ScheduleParallel(Dependency);

                // Populates a hash map, where each bucket contains the indices of all Boids whose positions quantize
                // to the same value for a given cell radius so that the information can be randomly accessed by
                // the `MergeCells` and `Steer` jobs.
                // This is useful in terms of the algorithm because it limits the number of comparisons that will
                // actually occur between the different boids. Instead of for each boid, searching through all
                // boids for those within a certain radius, this limits those by the hash-to-bucket simplification.
                var parallelHashMap        = hashMap.AsParallelWriter();
                var hashPositionsJobHandle = Entities
                                             .WithName("HashPositionsJob")
                                             .WithAll <Boid>()
                                             .ForEach((int entityInQueryIndex, in LocalToWorld localToWorld) =>
                {
                    var hash = (int)math.hash(new int3(math.floor(localToWorld.Position / settings.CellRadius)));
                    parallelHashMap.Add(hash, entityInQueryIndex);
                })
                                             .ScheduleParallel(Dependency);

                var initialCellCountJob = new MemsetNativeArray <int>
                {
                    Source = cellCount,
                    Value  = 1
                };
                var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, Dependency);

                var initialCellBarrierJobHandle        = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
                var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);
                var mergeCellsBarrierJobHandle         = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle);

                var mergeCellsJob = new MergeCells
                {
                    cellIndices               = cellIndices,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount         = cellCount,
                    targetPositions   = copyTargetPositions,
                    obstaclePositions = copyObstaclePositions
                };
                var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

                // This reads the previously calculated boid information for all the boids of each cell to update
                // the `localToWorld` of each of the boids based on their newly calculated headings using
                // the standard boid flocking algorithm.
                float deltaTime      = math.min(0.05f, Time.DeltaTime);
                var   steerJobHandle = Entities
                                       .WithName("Steer")
                                       .WithSharedComponentFilter(settings) // implies .WithAll<Boid>()
                                       .WithReadOnly(cellIndices)
                                       .WithReadOnly(cellCount)
                                       .WithReadOnly(cellAlignment)
                                       .WithReadOnly(cellSeparation)
                                       .WithReadOnly(cellObstacleDistance)
                                       .WithReadOnly(cellObstaclePositionIndex)
                                       .WithReadOnly(cellTargetPositionIndex)
                                       .WithReadOnly(copyObstaclePositions)
                                       .WithReadOnly(copyTargetPositions)
                                       .ForEach((int entityInQueryIndex, ref LocalToWorld localToWorld) =>
                {
                    // temporarily storing the values for code readability
                    var forward                      = localToWorld.Forward;
                    var currentPosition              = localToWorld.Position;
                    var cellIndex                    = cellIndices[entityInQueryIndex];
                    var neighborCount                = cellCount[cellIndex];
                    var alignment                    = cellAlignment[cellIndex];
                    var separation                   = cellSeparation[cellIndex];
                    var nearestObstacleDistance      = cellObstacleDistance[cellIndex];
                    var nearestObstaclePositionIndex = cellObstaclePositionIndex[cellIndex];
                    var nearestTargetPositionIndex   = cellTargetPositionIndex[cellIndex];
                    var nearestObstaclePosition      = copyObstaclePositions[nearestObstaclePositionIndex];
                    var nearestTargetPosition        = copyTargetPositions[nearestTargetPositionIndex];

                    // Setting up the directions for the three main biocrowds influencing directions adjusted based
                    // on the predefined weights:
                    // 1) alignment - how much should it move in a direction similar to those around it?
                    // note: we use `alignment/neighborCount`, because we need the average alignment in this case; however
                    // alignment is currently the summation of all those of the boids within the cellIndex being considered.
                    var alignmentResult = settings.AlignmentWeight
                                          * math.normalizesafe((alignment / neighborCount) - forward);
                    // 2) separation - how close is it to other boids and are there too many or too few for comfort?
                    // note: here separation represents the summed possible center of the cell. We perform the multiplication
                    // so that both `currentPosition` and `separation` are weighted to represent the cell as a whole and not
                    // the current individual boid.
                    var separationResult = settings.SeparationWeight
                                           * math.normalizesafe((currentPosition * neighborCount) - separation);
                    // 3) target - is it still towards its destination?
                    var targetHeading = settings.TargetWeight
                                        * math.normalizesafe(nearestTargetPosition - currentPosition);

                    // creating the obstacle avoidant vector s.t. it's pointing towards the nearest obstacle
                    // but at the specified 'ObstacleAversionDistance'. If this distance is greater than the
                    // current distance to the obstacle, the direction becomes inverted. This simulates the
                    // idea that if `currentPosition` is too close to an obstacle, the weight of this pushes
                    // the current boid to escape in the fastest direction; however, if the obstacle isn't
                    // too close, the weighting denotes that the boid doesnt need to escape but will move
                    // slower if still moving in that direction (note: we end up not using this move-slower
                    // case, because of `targetForward`'s decision to not use obstacle avoidance if an obstacle
                    // isn't close enough).
                    var obstacleSteering     = currentPosition - nearestObstaclePosition;
                    var avoidObstacleHeading = (nearestObstaclePosition + math.normalizesafe(obstacleSteering)
                                                * settings.ObstacleAversionDistance) - currentPosition;

                    // the updated heading direction. If not needing to be avoidant (ie obstacle is not within
                    // predefined radius) then go with the usual defined heading that uses the amalgamation of
                    // the weighted alignment, separation, and target direction vectors.
                    var nearestObstacleDistanceFromRadius = nearestObstacleDistance - settings.ObstacleAversionDistance;
                    var normalHeading = math.normalizesafe(alignmentResult + separationResult + targetHeading);
                    var targetForward = math.select(normalHeading, avoidObstacleHeading, nearestObstacleDistanceFromRadius < 0);

                    // updates using the newly calculated heading direction
                    var nextHeading = math.normalizesafe(forward + deltaTime * (targetForward - forward));
                    localToWorld    = new LocalToWorld
                    {
                        Value = float4x4.TRS(
                            new float3(localToWorld.Position + (nextHeading * settings.MoveSpeed * deltaTime)),
                            quaternion.LookRotationSafe(nextHeading, math.up()),
                            new float3(1.0f, 1.0f, 1.0f))
                    };
                }).ScheduleParallel(mergeCellsJobHandle);

                // Dispose allocated containers with dispose jobs.
                Dependency = steerJobHandle;
                var disposeJobHandle = hashMap.Dispose(Dependency);
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellIndices.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellObstaclePositionIndex.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellTargetPositionIndex.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellCount.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellObstacleDistance.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellAlignment.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, cellSeparation.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, copyObstaclePositions.Dispose(Dependency));
                disposeJobHandle = JobHandle.CombineDependencies(disposeJobHandle, copyTargetPositions.Dispose(Dependency));
                Dependency       = disposeJobHandle;

                // We pass the job handle and add the dependency so that we keep the proper ordering between the jobs
                // as the looping iterates. For our purposes of execution, this ordering isn't necessary; however, without
                // the add dependency call here, the safety system will throw an error, because we're accessing multiple
                // pieces of boid data and it would think there could possibly be a race condition.

                m_BoidQuery.AddDependency(Dependency);
                m_BoidQuery.ResetFilter();
            }
            m_UniqueTypes.Clear();
        }
コード例 #8
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            EntityManager.GetAllUniqueSharedComponentData(m_UniqueTypes);

            var obstacleCount = m_ObstacleQuery.CalculateEntityCount();
            var targetCount   = m_TargetQuery.CalculateEntityCount();

            // Cannot call [DeallocateOnJobCompletion] on Hashmaps yet, so doing own cleanup here
            // of the hashes created in the previous iteration.
            for (int i = 0; i < m_PrevFrameHashmaps.Count; ++i)
            {
                m_PrevFrameHashmaps[i].Dispose();
            }
            m_PrevFrameHashmaps.Clear();

            // Each variant of the Boid represents a different value of the SharedComponentData and is self-contained,
            // meaning Boids of the same variant only interact with one another. Thus, this loop processes each
            // variant type individually.
            for (int boidVariantIndex = 0; boidVariantIndex < m_UniqueTypes.Count; boidVariantIndex++)
            {
                var settings = m_UniqueTypes[boidVariantIndex];
                m_BoidQuery.SetFilter(settings);
                var boidCount = m_BoidQuery.CalculateEntityCount();

                if (boidCount == 0)
                {
                    // Early out. If the given variant includes no Boids, move on to the next loop.
                    // For example, variant 0 will always exit early bc it's it represents a default, uninitialized
                    // Boid struct, which does not appear in this sample.
                    continue;
                }

                // The following calculates spatial cells of neighboring Boids
                // note: working with a sparse grid and not a dense bounded grid so there
                // are no predefined borders of the space.

                var hashMap = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);

                var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellObstaclePositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellTargetPositionIndex   = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                var cellCount = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                var cellObstacleDistance = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellAlignment        = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var cellSeparation       = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                var copyTargetPositions   = new NativeArray <float3>(targetCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyObstaclePositions = new NativeArray <float3>(obstacleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                // The following jobs all run in parallel because the same JobHandle is passed for their
                // input dependencies when the jobs are scheduled; thus, they can run in any order (or concurrently).
                // The concurrency is property of how they're scheduled, not of the job structs themselves.

                var initialCellAlignmentJob = new CopyHeadings
                {
                    headings = cellAlignment
                };
                var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(m_BoidQuery, inputDeps);

                var initialCellSeparationJob = new CopyPositions
                {
                    positions = cellSeparation
                };
                var initialCellSeparationJobHandle = initialCellSeparationJob.Schedule(m_BoidQuery, inputDeps);

                var copyTargetPositionsJob = new CopyPositions
                {
                    positions = copyTargetPositions
                };
                var copyTargetPositionsJobHandle = copyTargetPositionsJob.Schedule(m_TargetQuery, inputDeps);

                var copyObstaclePositionsJob = new CopyPositions
                {
                    positions = copyObstaclePositions
                };
                var copyObstaclePositionsJobHandle = copyObstaclePositionsJob.Schedule(m_ObstacleQuery, inputDeps);

                // Cannot call [DeallocateOnJobCompletion] on Hashmaps yet, so adding resolved hashes to the list
                // so that theyre usable in the upcoming cell jobs and also have a straight forward cleanup.
                m_PrevFrameHashmaps.Add(hashMap);

                // setting up the jobs for position and cell count

                var hashPositionsJob = new HashPositions
                {
                    hashMap    = hashMap.AsParallelWriter(),
                    cellRadius = settings.CellRadius
                };
                var hashPositionsJobHandle = hashPositionsJob.Schedule(m_BoidQuery, inputDeps);

                var initialCellCountJob = new MemsetNativeArray <int>
                {
                    Source = cellCount,
                    Value  = 1
                };
                var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps);

                var initialCellBarrierJobHandle        = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
                var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);
                var mergeCellsBarrierJobHandle         = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle);

                var mergeCellsJob = new MergeCells
                {
                    cellIndices               = cellIndices,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount         = cellCount,
                    targetPositions   = copyTargetPositions,
                    obstaclePositions = copyObstaclePositions
                };
                var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

                var steerJob = new Steer
                {
                    cellIndices               = cellIndices,
                    settings                  = settings,
                    cellAlignment             = cellAlignment,
                    cellSeparation            = cellSeparation,
                    cellObstacleDistance      = cellObstacleDistance,
                    cellObstaclePositionIndex = cellObstaclePositionIndex,
                    cellTargetPositionIndex   = cellTargetPositionIndex,
                    cellCount                 = cellCount,
                    targetPositions           = copyTargetPositions,
                    obstaclePositions         = copyObstaclePositions,
                    dt = Time.deltaTime,
                };
                var steerJobHandle = steerJob.Schedule(m_BoidQuery, mergeCellsJobHandle);

                inputDeps = steerJobHandle;
                m_BoidQuery.AddDependency(inputDeps);
            }
            m_UniqueTypes.Clear();

            return(inputDeps);
        }
コード例 #9
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (cameraTransform == null)
        {
            cameraTransform = GameObject.Find("Main Camera").transform;
        }

        EntityManager.GetAllUniqueSharedComponentData(uniqueTypes);

        ComponentDataArray <SPHCollider> colliders = SPHColliderGroup.GetComponentDataArray <SPHCollider>();
        int colliderCount = colliders.Length;

        for (int typeIndex = 1; typeIndex < uniqueTypes.Count; typeIndex++)
        {
            // Get the current chunk setting
            SPHParticle settings = uniqueTypes[typeIndex];
            SPHCharacterGroup.SetFilter(settings);

            // Cache the data
            ComponentDataArray <Position>    positions  = SPHCharacterGroup.GetComponentDataArray <Position>();
            ComponentDataArray <SPHVelocity> velocities = SPHCharacterGroup.GetComponentDataArray <SPHVelocity>();

            int cacheIndex    = typeIndex - 1;
            int particleCount = positions.Length;

            NativeMultiHashMap <int, int> hashMap = new NativeMultiHashMap <int, int>(particleCount, Allocator.TempJob);

            NativeArray <Position>    particlesPosition = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SPHVelocity> particlesVelocity = new NativeArray <SPHVelocity>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float3>      particlesForces   = new NativeArray <float3>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>       particlesPressure = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>       particlesDensity  = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <int>         particleIndices   = new NativeArray <int>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            NativeArray <int>         cellOffsetTableNative = new NativeArray <int>(cellOffsetTable, Allocator.TempJob);
            NativeArray <SPHCollider> copyColliders         = new NativeArray <SPHCollider>(colliderCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);



            // Add new or dispose previous particle chunks
            PreviousParticle nextParticles = new PreviousParticle
            {
                hashMap           = hashMap,
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesForces   = particlesForces,
                particlesPressure = particlesPressure,
                particlesDensity  = particlesDensity,
                particleIndices   = particleIndices,
                cellOffsetTable   = cellOffsetTableNative,
                copyColliders     = copyColliders
            };

            if (cacheIndex > previousParticles.Count - 1)
            {
                previousParticles.Add(nextParticles);
            }
            else
            {
                previousParticles[cacheIndex].hashMap.Dispose();
                previousParticles[cacheIndex].particlesPosition.Dispose();
                previousParticles[cacheIndex].particlesVelocity.Dispose();
                previousParticles[cacheIndex].particlesForces.Dispose();
                previousParticles[cacheIndex].particlesPressure.Dispose();
                previousParticles[cacheIndex].particlesDensity.Dispose();
                previousParticles[cacheIndex].particleIndices.Dispose();
                previousParticles[cacheIndex].cellOffsetTable.Dispose();
                previousParticles[cacheIndex].copyColliders.Dispose();
            }
            previousParticles[cacheIndex] = nextParticles;



            // Copy the component data to native arrays
            CopyComponentData <Position> particlesPositionJob = new CopyComponentData <Position> {
                Source = positions, Results = particlesPosition
            };
            JobHandle particlesPositionJobHandle = particlesPositionJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SPHVelocity> particlesVelocityJob = new CopyComponentData <SPHVelocity> {
                Source = velocities, Results = particlesVelocity
            };
            JobHandle particlesVelocityJobHandle = particlesVelocityJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SPHCollider> copyCollidersJob = new CopyComponentData <SPHCollider> {
                Source = colliders, Results = copyColliders
            };
            JobHandle copyCollidersJobHandle = copyCollidersJob.Schedule(colliderCount, 64, inputDeps);

            MemsetNativeArray <float> particlesPressureJob = new MemsetNativeArray <float> {
                Source = particlesPressure, Value = 0.0f
            };
            JobHandle particlesPressureJobHandle = particlesPressureJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float> particlesDensityJob = new MemsetNativeArray <float> {
                Source = particlesDensity, Value = 0.0f
            };
            JobHandle particlesDensityJobHandle = particlesDensityJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <int> particleIndicesJob = new MemsetNativeArray <int> {
                Source = particleIndices, Value = 0
            };
            JobHandle particleIndicesJobHandle = particleIndicesJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float3> particlesForcesJob = new MemsetNativeArray <float3> {
                Source = particlesForces, Value = new float3(0, 0, 0)
            };
            JobHandle particlesForcesJobHandle = particlesForcesJob.Schedule(particleCount, 64, inputDeps);



            // Put positions into a hashMap
            HashPositions hashPositionsJob = new HashPositions
            {
                positions  = particlesPosition,
                hashMap    = hashMap.ToConcurrent(),
                cellRadius = settings.radius
            };
            JobHandle hashPositionsJobHandle = hashPositionsJob.Schedule(particleCount, 64, particlesPositionJobHandle);

            JobHandle mergedPositionIndicesJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, particleIndicesJobHandle);

            MergeParticles mergeParticlesJob = new MergeParticles
            {
                particleIndices = particleIndices
            };
            JobHandle mergeParticlesJobHandle = mergeParticlesJob.Schedule(hashMap, 64, mergedPositionIndicesJobHandle);

            JobHandle mergedMergedParticlesDensityPressure = JobHandle.CombineDependencies(mergeParticlesJobHandle, particlesPressureJobHandle, particlesDensityJobHandle);

            // Compute density pressure
            ComputeDensityPressure computeDensityPressureJob = new ComputeDensityPressure
            {
                particlesPosition = particlesPosition,
                densities         = particlesDensity,
                pressures         = particlesPressure,
                hashMap           = hashMap,
                cellOffsetTable   = cellOffsetTableNative,
                settings          = settings
            };
            JobHandle computeDensityPressureJobHandle = computeDensityPressureJob.Schedule(particleCount, 64, mergedMergedParticlesDensityPressure);

            JobHandle mergeComputeDensityPressureVelocityForces = JobHandle.CombineDependencies(computeDensityPressureJobHandle, particlesForcesJobHandle, particlesVelocityJobHandle);

            // Compute forces
            ComputeForces computeForcesJob = new ComputeForces
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesForces   = particlesForces,
                particlesPressure = particlesPressure,
                particlesDensity  = particlesDensity,
                cellOffsetTable   = cellOffsetTableNative,
                hashMap           = hashMap,
                settings          = settings
            };
            JobHandle computeForcesJobHandle = computeForcesJob.Schedule(particleCount, 64, mergeComputeDensityPressureVelocityForces);

            // Integrate
            Integrate integrateJob = new Integrate
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesDensity  = particlesDensity,
                particlesForces   = particlesForces
            };
            JobHandle integrateJobHandle = integrateJob.Schedule(particleCount, 64, computeForcesJobHandle);

            JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(integrateJobHandle, copyCollidersJobHandle);

            // Compute Colliders
            ComputeColliders computeCollidersJob = new ComputeColliders
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                copyColliders     = copyColliders,
                settings          = settings
            };
            JobHandle computeCollidersJobHandle = computeCollidersJob.Schedule(particleCount, 64, mergedIntegrateCollider);

            // Apply positions
            ApplyPositions applyPositionsJob = new ApplyPositions
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                positions         = positions,
                velocities        = velocities
            };
            JobHandle applyPositionsJobHandle = applyPositionsJob.Schedule(particleCount, 64, computeCollidersJobHandle);

            inputDeps = applyPositionsJobHandle;
        }

        // Done
        uniqueTypes.Clear();
        return(inputDeps);
    }
コード例 #10
0
    protected override JobHandle OnUpdate(JobHandle inputDependencies)
    {
        Settings settings;

        settings.CellRadius        = 16;
        settings.SeparationWeight  = 1;
        settings.AlignmentWeight   = 1;
        settings.TargetWeight      = 2;
        settings.MaxTargetDistance = 10000;
        //settings.ObstacleAversionDistance = 35;
        settings.MoveSpeed  = 25;
        settings.boidRadius = 0.5f;

        EntityManager.GetAllUniqueSharedComponentData(uniqueFactions);

        int healthCount = healthQuery.CalculateEntityCount();

        for (int i = 0; i < prevFrameHashmaps.Count; i++)
        {
            prevFrameHashmaps[i].Dispose();
        }
        prevFrameHashmaps.Clear();

        for (int index = 0; index < uniqueFactions.Count; index++)
        {
            boidQuery.SetFilter(uniqueFactions[index]);

            int boidCount = boidQuery.CalculateEntityCount();

            if (boidCount == 0)
            {
                continue;
            }

            var cellIndices          = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var hashMap              = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);
            var cellObstacleDistance = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellCount            = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var killTrigger          = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                         NativeArrayOptions.UninitializedMemory);
            var cellSeparation = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                          NativeArrayOptions.UninitializedMemory);
            var boidsData = new NativeArray <Boid>(boidCount, Allocator.TempJob,
                                                   NativeArrayOptions.UninitializedMemory);
            var cellTargetPositions = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                               NativeArrayOptions.UninitializedMemory);
            var cellObstaclePositions = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                                 NativeArrayOptions.UninitializedMemory);
            var bulletSpawns = new NativeArray <BulletSpawn>(boidCount, Allocator.TempJob,
                                                             NativeArrayOptions.ClearMemory);

            var damageDict = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);

            var initialCellAlignmentJob = new CopyHeadings {
                headings = cellAlignment
            };
            var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(boidQuery, inputDependencies);

            var initialCellSeparationJob = new CopyPositions {
                positions = cellSeparation
            };
            var initialCellSeparationJobHandle = initialCellSeparationJob.Schedule(boidQuery, inputDependencies);

            var initialBoidData = new CopyBoids {
                boids = boidsData
            };
            var initialBoidDataJobHandle = initialBoidData.Schedule(boidQuery, inputDependencies);

            // Cannot call [DeallocateOnJobCompletion] on Hashmaps yet
            prevFrameHashmaps.Add(hashMap);

            var hashPositionsJob = new HashPositions {
                hashMap    = hashMap.AsParallelWriter(),
                cellRadius = settings.CellRadius
            };
            var hashPositionsJobHandle = hashPositionsJob.Schedule(boidQuery, inputDependencies);

            var initialCellCountJob = new MemsetNativeArray <int> {
                Source = cellCount,
                Value  = 1
            };
            var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDependencies);

            var killTriggerJob = new MemsetNativeArray <int> {
                Source = killTrigger,
                Value  = 0
            };
            var killTriggerJobHandle = killTriggerJob.Schedule(boidCount, 64, inputDependencies);

            var initialCellBarrierJobHandle = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
            var initialBoidBarrierJobHandle = JobHandle.CombineDependencies(initialBoidDataJobHandle, killTriggerJobHandle);
            var mergeCellsBarrierJobHandle  = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, initialBoidBarrierJobHandle);

            ref PhysicsWorld physicsWorld = ref Unity.Entities.World.Active.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;

            var commandBuffer = m_Barrier.CreateCommandBuffer().ToConcurrent();
            prevFrameHashmaps.Add(damageDict);

            var mergeCellsJob = new MergeCells {
                cellIndices           = cellIndices,
                cellObstaclePositions = cellObstaclePositions,
                cellTargetPositions   = cellTargetPositions,
                cellAlignment         = cellAlignment,
                cellSeparation        = cellSeparation,
                cellObstacleDistance  = cellObstacleDistance,
                cellCount             = cellCount,
                boidsData             = boidsData,
                killTrigger           = killTrigger,
                physicsWorld          = physicsWorld,
                damageDict            = damageDict.AsParallelWriter(),
                bulletSpawns          = bulletSpawns,
                commandBuffer         = commandBuffer,
                bulletPrefab          = BulletPrefabAuthoring.Prefab,
                //enemyEntityLook = Setup.enemyEntityLook,
                groupIndex = math.select(4u, 8u, uniqueFactions[index].Value == 0),
                time       = Time.time,
                settings   = settings,
            };
            var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

            m_Barrier.AddJobHandleForProducer(mergeCellsJobHandle);

            var applyBulletSpawnDataJob = new ApplyBulletSpawnData {
                bulletSpawns  = bulletSpawns,
                destroyAtTime = Time.time + 5,
                commandBuffer = commandBuffer,
                bulletPrefab  = BulletPrefabAuthoring.Prefab
            };
            var applyBulletSpawnDataJobHandle = applyBulletSpawnDataJob.Schedule(boidCount, 64, mergeCellsJobHandle);

            m_Barrier.AddJobHandleForProducer(applyBulletSpawnDataJobHandle);

            var updateBoidData = new UpdateBoidData {
                boidsData = boidsData
            };
            var updateBoidDataJobHandle = updateBoidData.Schedule(boidQuery, applyBulletSpawnDataJobHandle);

            var steerJob = new Steer {
                cellIndices          = cellIndices,
                settings             = settings,
                cellAlignment        = cellAlignment,
                cellSeparation       = cellSeparation,
                cellObstacleDistance = cellObstacleDistance,
                cellCount            = cellCount,
                targetPositions      = cellTargetPositions,
                obstaclePositions    = cellObstaclePositions,
                boidsData            = boidsData,
                dt = Time.deltaTime,
            };
            var steerJobHandle = steerJob.Schedule(boidQuery, updateBoidDataJobHandle);

            var killJob = new Kill {
                killTrigger   = killTrigger,
                commandBuffer = commandBuffer,
            };
            var killJobHandle = killJob.Schedule(boidQuery, steerJobHandle);

            m_Barrier.AddJobHandleForProducer(killJobHandle);

            var applyDamageJob = new ApplyDamage {
                damageDict = damageDict
            };
            var applyDamageJobHandle = applyDamageJob.Schedule(healthQuery, mergeCellsJobHandle);

            inputDependencies = JobHandle.CombineDependencies(killJobHandle, applyDamageJobHandle, applyBulletSpawnDataJobHandle);
            boidQuery.AddDependency(inputDependencies);
        }
コード例 #11
0
ファイル: SMBSystem.cs プロジェクト: SrManny/TFG_OPEN
    //La data del sphereParticle es compartiiiida
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (cameraTransform == null)
        {
            cameraTransform = GameObject.Find("Main Camera").transform;
        }
        EntityManager.GetAllUniqueSharedComponentData(uniqueTypes);
        ComponentDataArray <SMBCollider> colliders = SMBColliderGroup.GetComponentDataArray <SMBCollider>();
        int colliderCount = colliders.Length;

        for (int typeIndex = 1; typeIndex < uniqueTypes.Count; typeIndex++)
        {
            // Get the current chunk setting
            SMBProperties settings = uniqueTypes[typeIndex];
            //SMBDestination smbdestination = _destination[typeIndex];
            SMBCharacterGroup.SetFilter(settings);

            // Cache the data
            ComponentDataArray <Position>       positions       = SMBCharacterGroup.GetComponentDataArray <Position>();
            ComponentDataArray <SMBVelocity>    velocities      = SMBCharacterGroup.GetComponentDataArray <SMBVelocity>();
            ComponentDataArray <SMBDestination> SMBdestinations = SMBCharacterGroup.GetComponentDataArray <SMBDestination>();
            ComponentDataArray <SMBSspeed>      SMBSspeeds      = SMBCharacterGroup.GetComponentDataArray <SMBSspeed>();
            ComponentDataArray <SMBPath>        indexPaths      = SMBCharacterGroup.GetComponentDataArray <SMBPath>();

            int cacheIndex    = typeIndex - 1;
            int particleCount = positions.Length;

            NativeMultiHashMap <int, int> hashMap              = new NativeMultiHashMap <int, int>(particleCount, Allocator.TempJob);
            NativeArray <Position>        particlesPosition    = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <Position>        finalposition        = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SMBVelocity>     particlesVelocity    = new NativeArray <SMBVelocity>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SMBDestination>  particlesDestination = new NativeArray <SMBDestination>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SMBSspeed>       particlesSspeed      = new NativeArray <SMBSspeed>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SMBPath>         particlesindexPaths  = new NativeArray <SMBPath>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float3>          particlesForces      = new NativeArray <float3>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>           particlesPressure    = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>           particlesDensity     = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <int>             particleIndices      = new NativeArray <int>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            NativeArray <int>         cellOffsetTableNative = new NativeArray <int>(cellOffsetTable, Allocator.TempJob);
            NativeArray <SMBCollider> copyColliders         = new NativeArray <SMBCollider>(colliderCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);



            // Add new or dispose previous particle chunks
            PreviousParticle nextParticles = new PreviousParticle
            {
                hashMap              = hashMap,
                particlesPosition    = particlesPosition,
                particlesVelocity    = particlesVelocity,
                particlesDestination = particlesDestination,
                particlesSspeed      = particlesSspeed,
                particlesindexPaths  = particlesindexPaths,
                particlesForces      = particlesForces,
                particlesPressure    = particlesPressure,
                particlesDensity     = particlesDensity,
                particleIndices      = particleIndices,
                cellOffsetTable      = cellOffsetTableNative,
                copyColliders        = copyColliders
            };

            if (cacheIndex > previousParticles.Count - 1)
            {
                previousParticles.Add(nextParticles);
            }
            else
            {
                previousParticles[cacheIndex].hashMap.Dispose();
                previousParticles[cacheIndex].particlesPosition.Dispose();
                previousParticles[cacheIndex].particlesVelocity.Dispose();
                previousParticles[cacheIndex].particlesDestination.Dispose();
                previousParticles[cacheIndex].particlesSspeed.Dispose();
                previousParticles[cacheIndex].particlesindexPaths.Dispose();
                previousParticles[cacheIndex].particlesForces.Dispose();
                previousParticles[cacheIndex].particlesPressure.Dispose();
                previousParticles[cacheIndex].particlesDensity.Dispose();
                previousParticles[cacheIndex].particleIndices.Dispose();
                previousParticles[cacheIndex].cellOffsetTable.Dispose();
                previousParticles[cacheIndex].copyColliders.Dispose();
            }
            previousParticles[cacheIndex] = nextParticles;



            // Copy the component data to native arrays
            CopyComponentData <Position> particlesPositionJob = new CopyComponentData <Position> {
                Source = positions, Results = particlesPosition
            };
            JobHandle particlesPositionJobHandle = particlesPositionJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SMBVelocity> particlesVelocityJob = new CopyComponentData <SMBVelocity> {
                Source = velocities, Results = particlesVelocity
            };
            JobHandle particlesVelocityJobHandle = particlesVelocityJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SMBDestination> particlesDestinationJob = new CopyComponentData <SMBDestination> {
                Source = SMBdestinations, Results = particlesDestination
            };
            JobHandle particlesDestinationJobHandle = particlesDestinationJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SMBSspeed> particlesSspeedJob = new CopyComponentData <SMBSspeed> {
                Source = SMBSspeeds, Results = particlesSspeed
            };
            JobHandle particlesSspeedJobHandle = particlesSspeedJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SMBCollider> copyCollidersJob = new CopyComponentData <SMBCollider> {
                Source = colliders, Results = copyColliders
            };
            JobHandle copyCollidersJobHandle = copyCollidersJob.Schedule(colliderCount, 64, inputDeps);

            MemsetNativeArray <float> particlesPressureJob = new MemsetNativeArray <float> {
                Source = particlesPressure, Value = 0.0f
            };
            JobHandle particlesPressureJobHandle = particlesPressureJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float> particlesDensityJob = new MemsetNativeArray <float> {
                Source = particlesDensity, Value = 0.0f
            };
            JobHandle particlesDensityJobHandle = particlesDensityJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <int> particleIndicesJob = new MemsetNativeArray <int> {
                Source = particleIndices, Value = 0
            };
            JobHandle particleIndicesJobHandle = particleIndicesJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float3> particlesForcesJob = new MemsetNativeArray <float3> {
                Source = particlesForces, Value = new float3(0, 0, 0)
            };
            JobHandle particlesForcesJobHandle = particlesForcesJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <Position> finalpositionJob = new MemsetNativeArray <Position> {
                Source = finalposition, Value = new Position {
                    Value = new float3()
                }
            };
            JobHandle finalpositionJobHandle = finalpositionJob.Schedule(particleCount, 64, inputDeps);

            //JobHandle computepathsJobHandle = particlesPositionJobHandle;


            if (first)
            {
                int index = 0, firsTriangle = 1;
                for (int i = 0; i < particleCount; ++i)
                {
                    astar.cleanStructures();
                    astar.setOrigin(positions[i].Value);
                    astar.setDestination(SMBdestinations[i].destination);
                    astar.trianglePath2();
                    //Allpaths.AddRange(astar.trianglePath2());
                    wayPointsPath.AddRange(astar.getWayPoints());

                    int aux = wayPointsPath.Count;
                    if (aux - index == 0)
                    {
                        firsTriangle = -1;
                    }
                    else
                    {
                        firsTriangle = 1;
                    }
                    Unity.Mathematics.Random ola = new Unity.Mathematics.Random(1);
                    indexPaths[i] = new SMBPath {
                        indexIni = index, indexFin = aux, NextPoint = new float3(), Firsttriangle = firsTriangle, recalculate = ola.NextInt(15), fordwarDir = new float3()
                    };
                    index = aux;
                }
                first = false;
            }
            //Una vez llegado al destino ir a otro, funciona pero va muuuuy lento

            /*else
             * {
             *  int index = 0, firsTriangle = 1, aux = 0;
             *  int diff = 0;
             *  for (int i = 0; i < particleCount; ++i)
             *  {
             *      index = indexPaths[i].indexIni + diff;
             *      aux = indexPaths[i].indexFin + diff;
             *      float3 NextPoint = indexPaths[i].NextPoint, fordwarDir = indexPaths[i].fordwarDir;
             *      int recalculate = indexPaths[i].recalculate;
             *      firsTriangle = indexPaths[i].Firsttriangle;
             *      if (SMBdestinations[i].finished == 1)
             *      {
             *          firsTriangle = 1;
             *          astar.cleanStructures();
             *          astar.setOrigin(positions[i].Value);
             *          astar.setDestination(SMBdestinations[i].destinations2);
             *          astar.trianglePath2();
             *          int count = 0;
             *          if (i == 0)
             *          {
             *              wayPointsPath.RemoveRange(0, indexPaths[i].indexFin);
             *              index = 0;
             *              count = indexPaths[i].indexFin;
             *          }
             *          else
             *          {
             *              index = indexPaths[i - 1].indexFin;
             *              count = indexPaths[i].indexFin + diff - indexPaths[i - 1].indexFin;
             *              wayPointsPath.RemoveRange(indexPaths[i - 1].indexFin, count);
             *          }
             *          List<SMBWaypoint> wayaux = astar.getWayPoints();
             *          wayPointsPath.InsertRange(index, wayaux);
             *
             *          aux = wayaux.Count;
             *
             *          indexPaths[i] = new SMBPath { indexIni = index, indexFin = aux + index, NextPoint = new float3(), Firsttriangle = firsTriangle, recalculate = recalculate, fordwarDir = new float3() };
             *          SMBdestinations[i] = new SMBDestination {finished = 2, destinations2 = SMBdestinations[i].destinations2, destination = SMBdestinations[i].destination };
             *          diff += aux - count;
             *      }
             *      else indexPaths[i] = new SMBPath { indexIni = index, indexFin = aux, NextPoint = NextPoint, Firsttriangle = firsTriangle, recalculate = recalculate, fordwarDir = fordwarDir };
             *  }
             * }*/


            NativeArray <SMBWaypoint> NwayPointspaths = new NativeArray <SMBWaypoint>(wayPointsPath.Count, Allocator.TempJob);
            //MemsetNativeArray<SMBWaypoint> waypointsJob = new MemsetNativeArray<SMBWaypoint> { Source = NwayPointspaths, Value = new SMBWaypoint { } };

            //NativeArray<int>.Copy(Allpaths.ToArray(), paths);
            NativeArray <SMBWaypoint> .Copy(wayPointsPath.ToArray(), NwayPointspaths, wayPointsPath.Count);

            //CopyComponentData<SMBDestination> particlesDestinationJob = new CopyComponentData<SMBDestination> { Source = SMBdestinations, Results = particlesDestination };
            //JobHandle particlesDestinationJobHandle = particlesDestinationJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SMBPath> particlesIndexPathJob = new CopyComponentData <SMBPath> {
                Source = indexPaths, Results = particlesindexPaths
            };
            JobHandle particlesIndexPathJobHandle = particlesIndexPathJob.Schedule(particleCount, 64, inputDeps);
            // Put positions into a hashMap
            HashPositions hashPositionsJob = new HashPositions
            {
                positions  = particlesPosition,
                hashMap    = hashMap.ToConcurrent(),
                cellRadius = settings.radius
            };
            JobHandle hashPositionsJobHandle = hashPositionsJob.Schedule(particleCount, 64, particlesPositionJobHandle);

            JobHandle mergedPositionIndicesJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, particleIndicesJobHandle);

            MergeParticles mergeParticlesJob = new MergeParticles
            {
                particleIndices = particleIndices
            };
            JobHandle mergeParticlesJobHandle = mergeParticlesJob.Schedule(hashMap, 64, mergedPositionIndicesJobHandle);

            JobHandle mergedMergedParticlesDensityPressure = JobHandle.CombineDependencies(mergeParticlesJobHandle, particlesPressureJobHandle, particlesDensityJobHandle);

            // Compute density pressure
            ComputeDensityPressure computeDensityPressureJob = new ComputeDensityPressure
            {
                particlesPosition = particlesPosition,
                densities         = particlesDensity,
                pressures         = particlesPressure,
                hashMap           = hashMap,
                cellOffsetTable   = cellOffsetTableNative,
                settings          = settings
            };
            JobHandle computeDensityPressureJobHandle = computeDensityPressureJob.Schedule(particleCount, 64, mergedMergedParticlesDensityPressure);

            JobHandle mergeComputeDensityPressureVelocityForces = JobHandle.CombineDependencies(computeDensityPressureJobHandle, particlesForcesJobHandle, particlesVelocityJobHandle);

            // Compute forces
            ComputeForces computeForcesJob = new ComputeForces
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesForces   = particlesForces,
                particlesPressure = particlesPressure,
                particlesDensity  = particlesDensity,
                cellOffsetTable   = cellOffsetTableNative,
                hashMap           = hashMap,
                settings          = settings
            };
            JobHandle computeForcesJobHandle = computeForcesJob.Schedule(particleCount, 64, mergeComputeDensityPressureVelocityForces);

            // Integrate
            Integrate integrateJob = new Integrate
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesDensity  = particlesDensity,
                particlesForces   = particlesForces
            };
            JobHandle integrateJobHandle = integrateJob.Schedule(particleCount, 64, computeForcesJobHandle);

            JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(integrateJobHandle, copyCollidersJobHandle);
            //JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(particlesPositionJobHandle, particlesVelocityJobHandle, copyCollidersJobHandle);
            // Compute Colliders
            ComputeColliders computeCollidersJob = new ComputeColliders
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                copyColliders     = copyColliders,
                settings          = settings
            };
            JobHandle computeCollidersJobHandle = computeCollidersJob.Schedule(particleCount, 64, mergedIntegrateCollider);
            JobHandle allReady = JobHandle.CombineDependencies(computeCollidersJobHandle, particlesIndexPathJobHandle, particlesDestinationJobHandle);

            ComputeNewPoint computeNewPointJob = new ComputeNewPoint
            {
                particlesPosition    = particlesPosition,
                waypoints            = NwayPointspaths,
                indexPaths           = particlesindexPaths,
                particlesDestination = particlesDestination
            };
            JobHandle computeNewPointJobHandle = computeNewPointJob.Schedule(particleCount, 64, allReady);


            computeNewPointJobHandle = JobHandle.CombineDependencies(computeNewPointJobHandle, finalpositionJobHandle);

            RecomputeNewPoint RecomputeNewPointJob = new RecomputeNewPoint
            {
                particlesPosition = particlesPosition,
                waypoints         = NwayPointspaths,
                indexPaths        = particlesindexPaths
            };
            JobHandle       RecomputeNewPointJobHandle = RecomputeNewPointJob.Schedule(particleCount, 64, computeNewPointJobHandle);
            JobHandle       preparedToComputePositions = JobHandle.CombineDependencies(RecomputeNewPointJobHandle, particlesSspeedJobHandle);
            ComputePosition computePositionJob         = new ComputePosition
            {
                particlesPosition    = particlesPosition,
                particlesDestination = particlesDestination,
                particlesSspeed      = particlesSspeed,
                particlesVelocity    = particlesVelocity,
                indexPaths           = particlesindexPaths,
                hashMap         = hashMap,
                settings        = settings,
                cellOffsetTable = cellOffsetTableNative,
                finalPosition   = finalposition
            };
            JobHandle comptePositionJobHandle = computePositionJob.Schedule(particleCount, 64, preparedToComputePositions);


            // Apply positions
            ApplyPositions applyPositionsJob = new ApplyPositions
            {
                particlesPosition   = finalposition,
                particlesVelocity   = particlesVelocity,
                particlesindexPaths = particlesindexPaths,
                //particlesDestination = particlesDestination,
                particlesSspeed = particlesSspeed,
                positions       = positions,
                velocities      = velocities,
                indexPaths      = indexPaths,
                SMBSspeeds      = SMBSspeeds,
                //SMBdestinations = SMBdestinations,
            };
            JobHandle applyPositionsJobHandle = applyPositionsJob.Schedule(particleCount, 64, comptePositionJobHandle);

            inputDeps = applyPositionsJobHandle;
            inputDeps.Complete();
            NwayPointspaths.Dispose();
            finalposition.Dispose();
        }

        // Done
        uniqueTypes.Clear();

        return(inputDeps);
    }
コード例 #12
0
    protected override JobHandle OnUpdate(JobHandle input_deps)
    {
        float dt           = Time.DeltaTime * SimulationManager.sim.speed_multiplier;
        float current_time = SimulationManager.sim.current_time;
        float day_time     = SimulationManager.sim.day_time;

        var home_bound   = SimulationManager.sim.home_bound;
        var wearing_mask = SimulationManager.sim.wearing_mask;
        var has_started  = SimulationManager.sim.has_started;

        int   person_count             = SimulationManager.sim.person_count;
        Rect  bounds                   = SimulationManager.sim.bounds;
        float interaction_radius       = SimulationManager.sim.interaction_radius;
        float infection_rate_per_virus = SimulationManager.sim.infection_rate_per_virus;
        var   max_hash                 = (int)(bounds.width * bounds.height / interaction_radius / interaction_radius);

        var hash_map = new NativeMultiHashMap <int, int>(person_count, Allocator.TempJob);

        var cell_index    = new NativeArray <int>(person_count, Allocator.TempJob);
        var cell_virus    = new NativeArray <float>(person_count, Allocator.TempJob);
        var cell_count    = new NativeArray <int>(person_count, Allocator.TempJob);
        var cell_position = new NativeArray <float2>(person_count, Allocator.TempJob);

        var room_count          = 13 * 13 * SimulationManager.sim.rooms_per_apartment * 4;
        var occupied_count      = new NativeArray <int>(room_count, Allocator.TempJob);
        var occupied_virus      = new NativeArray <float>(room_count, Allocator.TempJob);
        var occupied_antibodies = new NativeArray <float>(room_count, Allocator.TempJob);

        // Read data into NativeArrays.
        var read_pos_deps = Entities.WithAll <PersonData>().ForEach(
            (int entityInQueryIndex, in Translation R) =>
        {
            cell_position[entityInQueryIndex] = new float2(R.Value.x, R.Value.z);
        }).Schedule(input_deps);

        var read_virus_deps = Entities.ForEach(
            (int entityInQueryIndex, in PersonData p) =>
        {
            cell_virus[entityInQueryIndex] = p.virus;
        }).Schedule(input_deps);

        var initialize_cell_count_deps = new MemsetNativeArray <int>
        {
            Source = cell_count,
            Value  = 1
        }.Schedule(person_count, 64, input_deps);

        var initialize_occupied_count_deps = new MemsetNativeArray <int>
        {
            Source = occupied_count,
            Value  = 1
        }.Schedule(room_count, 64, input_deps);

        // Place people into the hash map.
        var parallel_hash_map = hash_map.AsParallelWriter();
        var read_hash_deps    = Entities.ForEach(
            (int entityInQueryIndex, in Translation R, in PersonData P) =>
        {
            var pos = new float2(R.Value.x, R.Value.z) + new float2(bounds.min.x, bounds.min.y);
            int hash;
            if (P.is_home)
            {
                hash = max_hash + P.home_idx;
            }
            else
            {
                hash = (int)math.hash(new int2(math.floor(pos / interaction_radius)));
            }
            parallel_hash_map.Add(hash, entityInQueryIndex);
        }).Schedule(input_deps);
コード例 #13
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var settings     = ECSController.FlockParams;
            var gameSettings = GlobalSettings.Instance;

            EntityManager.GetAllUniqueSharedComponentData(UniqueTypes);

            int targetsCount   = BoidTargetsGroup.CalculateLength();
            int obstaclesCount = BoidObstaclesGroup.CalculateLength();

            UIControl.Instance.NrOfObstacles = obstaclesCount;

            // Ignore typeIndex 0, can't use the default for anything meaningful.
            for (int typeIndex = 1; typeIndex < UniqueTypes.Count; typeIndex++)
            {
                Boid boid = UniqueTypes[typeIndex];
                BoidGroup.SetFilter(boid);

                var boidCount = BoidGroup.CalculateLength();
                UIControl.Instance.NrOfBoidsAlive = boidCount;

                var cacheIndex = typeIndex - 1;
                // containers that store all the data.
                var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var hashMap     = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);
                var cellCount   = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                             NativeArrayOptions.UninitializedMemory);
                var cellPositions = new NativeArray <float3>(boidCount, Allocator.TempJob,
                                                             NativeArrayOptions.UninitializedMemory);

                var targetsPositions = new NativeArray <float3>(targetsCount, Allocator.TempJob,
                                                                NativeArrayOptions.UninitializedMemory);
                var closestTargetIndices = new NativeArray <int>(boidCount, Allocator.TempJob,
                                                                 NativeArrayOptions.UninitializedMemory);

                var obstaclesPositions = new NativeArray <float3>(obstaclesCount, Allocator.TempJob,
                                                                  NativeArrayOptions.UninitializedMemory);
                var closestObstacleIndices = new NativeArray <int>(boidCount, Allocator.TempJob,
                                                                   NativeArrayOptions.UninitializedMemory);
                var closestObstacleSqDistances = new NativeArray <float>(boidCount, Allocator.TempJob,
                                                                         NativeArrayOptions.UninitializedMemory);

                float3 sumOfAllBoidsPositions = float3.zero;

                // copy values to buffers.
                var initialCellAlignmentJob = new CopyHeadingsInBuffer {
                    headingsResult = cellAlignment
                };
                var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(BoidGroup, inputDeps);

                var initialCopyPositionJob = new CopyPositionsInBuffer {
                    positionsResult = cellPositions
                };
                var initialCopyPositionJobHandle = initialCopyPositionJob.Schedule(BoidGroup, inputDeps);

                var sumPositionsJob = new SumPositions {
                    positionsSum = sumOfAllBoidsPositions
                };
                var sumPositionsJobHandle = sumPositionsJob.Schedule(BoidGroup, inputDeps);

                // copy targets positions
                var copyPositionsOfTargetsJob = new CopyPositionsInBuffer {
                    positionsResult = targetsPositions
                };
                var copyPositionsOfTargetsJobHandle = copyPositionsOfTargetsJob.Schedule(BoidTargetsGroup, inputDeps);

                // copy obstacles positions
                var copyPositionsOfObstaclesJob = new CopyPositionsInBuffer {
                    positionsResult = obstaclesPositions
                };
                var copyPositionsOfObstaclesJobHandle = copyPositionsOfObstaclesJob.Schedule(BoidObstaclesGroup, inputDeps);

                var newCellData = new CellsData {
                    indicesOfCells = cellIndices,
                    hashMapBlockIndexWithBoidsIndex = hashMap,
                    sumOfDirectionsOnCells          = cellAlignment,
                    sumOfPositionsOnCells           = cellPositions,
                    nrOfBoidsOnCells           = cellCount,
                    targetsPositions           = targetsPositions,
                    closestTargetIndices       = closestTargetIndices,
                    closestObstacleIndices     = closestObstacleIndices,
                    closestObstacleSqDistances = closestObstacleSqDistances,
                    obstaclesPositions         = obstaclesPositions,
                };

                if (cacheIndex > (_CellsData.Count - 1))
                {
                    _CellsData.Add(newCellData);
                }
                else
                {
                    DisposeCellData(_CellsData[cacheIndex]);
                }
                _CellsData[cacheIndex] = newCellData;

                // hash the entity position
                var hashPositionsJob = new HashPositionsToHashMap {
                    hashMap            = hashMap.ToConcurrent(),
                    cellRadius         = ECSController.Instance.CellSizeVaried,
                    positionOffsetVary = ECSController.Instance.PositionNeighbourCubeOffset
                };
                var hashPositionsJobHandle = hashPositionsJob.Schedule(BoidGroup, inputDeps);

                // set all cell count to 1.
                var initialCellCountJob = new MemsetNativeArray <int> {
                    Source = cellCount,
                    Value  = 1
                };
                var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps);

                // bariers. from now on we need to use the created buffers.
                // and we need to know that they are finished.
                var initialCellBarrierJobHandle = JobHandle.CombineDependencies(
                    initialCellAlignmentJobHandle, initialCopyPositionJobHandle, initialCellCountJobHandle);
                var mergeCellsBarrierJobHandle = JobHandle.CombineDependencies(
                    hashPositionsJobHandle, initialCellBarrierJobHandle, sumPositionsJobHandle);
                var targetsJobHandle = JobHandle.CombineDependencies(mergeCellsBarrierJobHandle,
                                                                     copyPositionsOfTargetsJobHandle, copyPositionsOfObstaclesJobHandle);

                var mergeCellsJob = new MergeCellsJob {
                    indicesOfCells                   = cellIndices,
                    cellAlignment                    = cellAlignment,
                    cellPositions                    = cellPositions,
                    cellCount                        = cellCount,
                    targetsPositions                 = targetsPositions,
                    closestTargetIndexToCells        = closestTargetIndices,
                    closestObstacleSqDistanceToCells = closestObstacleSqDistances,
                    closestObstacleIndexToCells      = closestObstacleIndices,
                    obstaclesPositions               = obstaclesPositions
                };
                // job now depends on last barrier.
                var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, targetsJobHandle);
                EntityCommandBuffer.Concurrent commandBuffer        = barrierCommand.CreateCommandBuffer().ToConcurrent();
                NativeQueue <float3>           killedPositionsQueue = new NativeQueue <float3>(Allocator.TempJob);

                var steerJob = new MoveBoids {
                    cellIndices          = newCellData.indicesOfCells,
                    alignmentWeight      = gameSettings.AlignmentWeight,
                    separationWeight     = gameSettings.SeparationWeight,
                    cohesionWeight       = gameSettings.CohesionWeight,
                    cellSize             = ECSController.Instance.CellSizeVaried,
                    sphereBoundarySize   = gameSettings.SphereBoundarySize,
                    sphereBoundaryWeight = gameSettings.BoundaryWeight,
                    moveSpeed            = gameSettings.MoveSpeed,
                    cellAlignment        = cellAlignment,
                    cellPositions        = cellPositions,
                    cellCount            = cellCount,
                    dt = Time.deltaTime,
                    walkToFlockCenterWeight = gameSettings.WalkToFlockCenterWeight,
                    sumOfAllPositions       = sumOfAllBoidsPositions,
                    nrOfTotalBoids          = boidCount,
                    maintainYWeight         = gameSettings.maintainYWeight,
                    yLength                         = gameSettings.yLength,
                    perlinNoiseScale                = settings.perlinNoiseScale,
                    targetsPositions                = targetsPositions,
                    cellClosestTargetsIndices       = closestTargetIndices,
                    goToTargetsWeight               = gameSettings.goToTargetsWeight,
                    obstaclesPositions              = obstaclesPositions,
                    cellClosestObstaclesIndices     = closestObstacleIndices,
                    cellClosestObstaclesSqDistances = closestObstacleSqDistances,
                    startAvoidingObstacleAtDistance = gameSettings.avoidDistanceObstacles,
                    avoidObstaclesWeight            = gameSettings.avoidObstaclesWeight,
                    terrainY                        = ECSController.TerrainY,
                    distanceToAvoidTerrain          = settings.distanceToAvoidTerrain,
                    avoidTerrainWeight              = gameSettings.avoidTerrainWeight,
                    avoidXZwhileHeightBiggerThan    = settings.avoidXZwhileHeightBiggerThan,
                    avoidXZwhileHeightBiggerFade    = settings.avoidXZwhileHeightBiggerFade,
                    obstacleKillRadius              = settings.obstacleKillRadius,
                    commandBuffer                   = commandBuffer,
                    diedPositions                   = killedPositionsQueue.ToConcurrent(),
                };
                // job depends on merge cells job
                var steerJobHandle = steerJob.Schedule(BoidGroup, mergeCellsJobHandle);

                barrierCommand.AddJobHandleForProducer(steerJobHandle);
                steerJobHandle.Complete();

                if (killedPositionsQueue.TryDequeue(out float3 pos))
                {
                    GameController.Instance.KilledBoidAt(pos);
                }

                killedPositionsQueue.Dispose();
                inputDeps = steerJobHandle;
                BoidGroup.AddDependency(inputDeps);
            }
            UniqueTypes.Clear();

            return(inputDeps);
        }
コード例 #14
0
    protected override JobHandle OnUpdate(JobHandle inputDependencies)
    {
        EntityManager.GetAllUniqueSharedComponentData(uniqueTypes);

        var obstacleCount = obstacleQuery.CalculateEntityCount();
        var targetCount   = targetQuery.CalculateEntityCount();

        for (int i = 0; i < prevFrameHashmaps.Count; i++)
        {
            prevFrameHashmaps[i].Dispose();
        }
        prevFrameHashmaps.Clear();

        for (int hordeVariantIndex = 0; hordeVariantIndex < uniqueTypes.Count; hordeVariantIndex++)
        {
            var settings = uniqueTypes[hordeVariantIndex];
            hordeQuery.SetFilter(settings);
            var hordeCount = hordeQuery.CalculateEntityCount();

            if (hordeCount == 0)
            {
                continue;
            }
            //Debug.Log(hordeCount);

            #region Initial vars

            var hashMap = new NativeMultiHashMap <int, int>(hordeCount, Allocator.TempJob);

            var cellIndices = new NativeArray <int>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellObstaclePositionIndex = new NativeArray <int>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellTargetPositionIndex   = new NativeArray <int>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            var cellCount = new NativeArray <int>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            var cellObstacleDistance = new NativeArray <float>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellAlignment        = new NativeArray <float3>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellSeparation       = new NativeArray <float3>(hordeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            var copyTargetPositions   = new NativeArray <float3>(targetCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var copyObstaclePositions = new NativeArray <float3>(obstacleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            #endregion

            #region Initial jobs

            var initialCellAlignmentJob = new CopyHeadings {
                headings = cellAlignment
            };
            var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(hordeQuery, inputDependencies);

            var initialCellSeparationJob = new CopyPositions {
                positions = cellSeparation
            };
            var initialCellSeparationJobHandle = initialCellSeparationJob.Schedule(hordeQuery, inputDependencies);

            var copyTargetPositionsJob = new CopyPositions {
                positions = copyTargetPositions
            };
            var copyTargetPositionsJobHandle = copyTargetPositionsJob.Schedule(targetQuery, inputDependencies);

            var copyObstaclePositionsJob = new CopyPositions {
                positions = copyObstaclePositions
            };
            var copyObstaclePositionsJobHandle = copyObstaclePositionsJob.Schedule(obstacleQuery, inputDependencies);

            prevFrameHashmaps.Add(hashMap);

            var hashPositionsJob = new HashPositions
            {
                hashMap    = hashMap.AsParallelWriter(),
                cellRadius = settings.CellRadius
            };
            var hashPositionsJobHandle = hashPositionsJob.Schedule(hordeQuery, inputDependencies);

            var initialCellCountJob = new MemsetNativeArray <int>
            {
                Source = cellCount,
                Value  = 1
            };
            var initialCellCountJobHandle = initialCellCountJob.Schedule(hordeCount, 64, inputDependencies);

            #endregion

            var initialCellBarrierJobHandle        = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
            var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);
            var mergeCellsBarrierJobHandle         = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle);

            var mergeCellsJob = new MergeCells
            {
                cellIndices               = cellIndices,
                cellAlignment             = cellAlignment,
                cellSeparation            = cellSeparation,
                cellObstacleDistance      = cellObstacleDistance,
                cellObstaclePositionIndex = cellObstaclePositionIndex,
                cellTargetPositionIndex   = cellTargetPositionIndex,
                cellCount         = cellCount,
                targetPositions   = copyTargetPositions,
                obstaclePositions = copyObstaclePositions
            };
            var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

            var steerJob = new Steer
            {
                cellIndices               = cellIndices,
                settings                  = settings,
                cellAlignment             = cellAlignment,
                cellSeparation            = cellSeparation,
                cellObstacleDistance      = cellObstacleDistance,
                cellObstaclePositionIndex = cellObstaclePositionIndex,
                cellTargetPositionIndex   = cellTargetPositionIndex,
                cellCount                 = cellCount,
                targetPositions           = copyTargetPositions,
                obstaclePositions         = copyObstaclePositions,
                dt = Time.deltaTime,
            };
            var steerJobHandle = steerJob.Schedule(hordeQuery, mergeCellsJobHandle);

            inputDependencies = steerJobHandle;
            hordeQuery.AddDependency(inputDependencies);
        }
        uniqueTypes.Clear();

        return(inputDependencies);
    }
コード例 #15
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var boidCount = m_Boids.boidTag.Length;

            var cellIndices               = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var hashMap                   = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob);
            var copyTargetPositions       = new NativeArray <Position>(m_Boids.boidTarget.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var copyObstaclePositions     = new NativeArray <Position>(m_Obstacles.obstaclePositions.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellSeparation            = new NativeArray <Position>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellObstacleDistance      = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellObstaclePositionIndex = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var cellCount                 = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);



            var hashPositionsJob = new HashPositions
            {
                positions  = m_Boids.boidPositions,
                hashMap    = hashMap,
                cellRadius = ECSBootstrapper.boidSettings.cellRadius
            };
            var hashPositionsJobHandle = hashPositionsJob.Schedule(boidCount, 64, inputDeps);

            var initialCellSeparationJob = new CopyComponentData <Position>
            {
                Source  = m_Boids.boidPositions,
                Results = cellSeparation
            };
            var initialCellSeparationJobHandle = initialCellSeparationJob.Schedule(boidCount, 64, inputDeps);

            var initialCellCountJob = new MemsetNativeArray <int>
            {
                Source = cellCount,
                Value  = 1
            };
            var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps);

            var initialCellBarrierJobHandle = JobHandle.CombineDependencies(initialCellSeparationJobHandle, initialCellCountJobHandle);

            var copyTargetPositionJob = new CopyTargetPositions
            {
                Source  = m_Boids.boidTarget,
                Results = copyTargetPositions
            };

            var copyTargetPositionsJobHandle = copyTargetPositionJob.Schedule(m_Boids.boidTarget.Length, 2, inputDeps);

            var copyObstaclePositionsJob = new CopyComponentData <Position>
            {
                Source  = m_Obstacles.obstaclePositions,
                Results = copyObstaclePositions
            };
            var copyObstaclePositionsJobHandle = copyObstaclePositionsJob.Schedule(m_Obstacles.obstaclePositions.Length, 2, inputDeps);

            var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);

            var mergeCellsBarrierJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, initialCellBarrierJobHandle, copyTargetObstacleBarrierJobHandle);

            var mergeCellsJob = new MergeCells
            {
                cellIndices               = cellIndices,
                cellSeparation            = cellSeparation,
                cellObstacleDistance      = cellObstacleDistance,
                cellObstaclePositionIndex = cellObstaclePositionIndex,
                cellCount         = cellCount,
                obstaclePositions = copyObstaclePositions
            };
            var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);

            var steerJob = new Steer
            {
                cellIndices               = cellIndices, //D
                settings                  = ECSBootstrapper.boidSettings,
                cellSeparation            = cellSeparation,
                cellObstacleDistance      = cellObstacleDistance,
                cellObstaclePositionIndex = cellObstaclePositionIndex,
                cellCount                 = cellCount,
                targetPositions           = copyTargetPositions,
                obstaclePositions         = copyObstaclePositions,
                dt        = Time.deltaTime,
                positions = m_Boids.boidPositions,
                headings  = m_Boids.boidHeadings,
            };
            var steerJobHandle = steerJob.Schedule(boidCount, 64, mergeCellsJobHandle);

            steerJobHandle.Complete();


            cellIndices.Dispose();
            hashMap.Dispose();
            copyTargetPositions.Dispose();
            copyObstaclePositions.Dispose();
            cellSeparation.Dispose();
            cellObstacleDistance.Dispose();
            cellObstaclePositionIndex.Dispose();
            cellCount.Dispose();


            return(inputDeps);
        }
コード例 #16
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        // reset values to -1
        var clearArrayJob = new MemsetNativeArray <int> // MemsetNativeArray job assigns the same value to the whole array
        {
            Source = gridIndexArray,
            Value  = -1
        };

        var clearArrayJobHandle = clearArrayJob.Schedule(ARRAY_SIZE, 64, inputDeps); // not sure what the 64 innerloop batch count means

        // fill index array job
        var fillJob = new FillDataArrayJob()
        {
            gridIndexData = gridIndexArray
        };

        var fillJobHandle = fillJob.Schedule(this, clearArrayJobHandle); // makes sure the clearArrayJob is complete

        #region legacy slow

        /*
         * entities = MicrobeSpawner.entityArray;
         * centerPos = Object.FindObjectOfType<InputComponent>().transform.position;
         * globalOffset += .2f; // WTF IS THIS
         *
         * // update avoidance data and calculate force
         *
         * // THIS MAKES THE SYSTEM SLOW!!!
         *
         * for (int i = 0; i < MicrobeSpawner.total; i++)
         * {
         *  MovementData indexForcePrevPos = EntityManager.GetComponentData<MovementData>(entities[i]);
         *  Position position = EntityManager.GetComponentData<Position>(entities[i]);
         *  entityPositionsArray[i] = position.Value;
         *
         *  // remove old position from grid
         *  int outerIndex = CoordsToOuterIndex(
         *      (int)indexForcePrevPos.PreviousPosition.x,
         *      (int)indexForcePrevPos.PreviousPosition.y);
         *
         *  if (outerIndex >= 0 && outerIndex < gridIndexArray.Length)
         *  {
         *      for (int innerIndex = outerIndex; innerIndex < outerIndex + COLLISION_FORCES_PER_TILE; innerIndex++)
         *      {
         *          if (gridIndexArray[innerIndex] == indexForcePrevPos.Index)
         *          {
         *              gridIndexArray[innerIndex] = 0;
         *          }
         *      }
         *  }
         *
         *  // add new position to grid
         *  outerIndex = CoordsToOuterIndex((int)position.Value.x, (int)position.Value.z);
         *  if (outerIndex >= 0 && outerIndex < gridIndexArray.Length)
         *  {
         *      for (int innerIndex = outerIndex; innerIndex < outerIndex + COLLISION_FORCES_PER_TILE; innerIndex++)
         *      {
         *          if (gridIndexArray[innerIndex] == 0)
         *          {
         *              gridIndexArray[innerIndex] = indexForcePrevPos.Index;
         *          }
         *      }
         *  }
         * }*/
        #endregion

        // movement job
        var movementJob       = new PositionJob(gridIndexArray, entityPositionsArray);
        var movementJobHandle = movementJob.Schedule(this, fillJobHandle);  // makes sure the fillJob is complete

        return(movementJobHandle);

        //return movementJob.Schedule(this, inputDeps);
    }