예제 #1
0
        public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
        {
            var boidChunk         = batchInChunk.GetNativeArray(boidTypeHandle);
            var translationsChunk = batchInChunk.GetNativeArray(translationTypeHandle);
            var rotationsChunk    = batchInChunk.GetNativeArray(rotationTypeHandle);


            for (int i = 0; i < batchInChunk.Count; i++)
            {
                Translation p = translationsChunk[i];
                Rotation    r = rotationsChunk[i];
                Boid        b = boidChunk[i];
                int         neighbourStartIndex = maxNeighbours * b.boidId;
                int         neighbourCount      = 0;


                if (usePartitioning)
                {
                    int surroundingCellCount = (int)Mathf.Ceil(neighbourDistance / cellSize);

                    // Are we looking above and below?
                    int sliceSurrounding = threedcells ? surroundingCellCount : 0;
                    for (int slice = -sliceSurrounding; slice <= sliceSurrounding; slice++)
                    {
                        for (int row = -surroundingCellCount; row <= surroundingCellCount; row++)
                        {
                            for (int col = -surroundingCellCount; col <= surroundingCellCount; col++)
                            {
                                Vector3 pos  = positions[b.boidId] + new Vector3(col * cellSize, slice * cellSize, row * cellSize);
                                int     cell = PartitionSpaceJob.PositionToCell(pos, cellSize, gridSize);

                                NativeMultiHashMapIterator <int> iterator;
                                int boidId;
                                if (cells.TryGetFirstValue(cell, out boidId, out iterator))
                                {
                                    do
                                    {
                                        if (boidId != b.boidId)
                                        {
                                            if (Vector3.Distance(positions[b.boidId], positions[boidId]) < neighbourDistance)
                                            {
                                                neighbours[neighbourStartIndex + neighbourCount] = boidId;
                                                neighbourCount++;
                                                if (neighbourCount == maxNeighbours)
                                                {
                                                    b.taggedCount = neighbourCount;
                                                    return;
                                                }
                                            }
                                        }
                                    } while (cells.TryGetNextValue(out boidId, ref iterator));
                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < positions.Length; j++)
                    {
                        if (j != b.boidId)
                        {
                            if (Vector3.Distance(positions[b.boidId], positions[j]) < neighbourDistance)
                            {
                                neighbours[neighbourStartIndex + neighbourCount] = j;
                                neighbourCount++;
                                if (neighbourCount == maxNeighbours)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                b.taggedCount = neighbourCount;
                boidChunk[i]  = b;
            }
        }
예제 #2
0
        protected override void OnUpdate()
        {
            physicsWorld = World.GetExistingSystem <Unity.Physics.Systems.BuildPhysicsWorld>();

            BoidBootstrap bootstrap = this.bootstrap;

            ComponentTypeHandle <Wander>            wTHandle   = GetComponentTypeHandle <Wander>();
            ComponentTypeHandle <Boid>              bTHandle   = GetComponentTypeHandle <Boid>();
            ComponentTypeHandle <Translation>       ttTHandle  = GetComponentTypeHandle <Translation>();
            ComponentTypeHandle <Rotation>          rTHandle   = GetComponentTypeHandle <Rotation>();
            ComponentTypeHandle <Seperation>        sTHandle   = GetComponentTypeHandle <Seperation>();
            ComponentTypeHandle <Cohesion>          cTHandle   = GetComponentTypeHandle <Cohesion>();
            ComponentTypeHandle <Alignment>         aTHandle   = GetComponentTypeHandle <Alignment>();
            ComponentTypeHandle <Constrain>         conTHandle = GetComponentTypeHandle <Constrain>();
            ComponentTypeHandle <LocalToWorld>      ltwTHandle = GetComponentTypeHandle <LocalToWorld>();
            ComponentTypeHandle <ObstacleAvoidance> oaTHandle  = GetComponentTypeHandle <ObstacleAvoidance>();

            float deltaTime = Time.DeltaTime * bootstrap.speed;

            Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000));

            CamPosition = positions[0];
            CamRotation = rotations[0];

            //DrawGizmos();

            // Copy entities to the native arrays
            var copyToNativeJob = new CopyTransformsToNativeJob()
            {
                positions             = this.positions,
                rotations             = this.rotations,
                boidTypeHandle        = bTHandle,
                translationTypeHandle = ttTHandle,
                rotationTypeHandle    = rTHandle
            };

            var copyToNativeHandle = copyToNativeJob.ScheduleParallel(translationsRotationsQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, copyToNativeHandle);

            var oaJob = new ObstacleAvoidanceJob()
            {
                boidTypeHandle              = bTHandle,
                translationTypeHandle       = ttTHandle,
                ltwTypeHandle               = ltwTHandle,
                obstacleAvoidanceTypeHandle = oaTHandle,
                rotationTypeHandle          = rTHandle,
                collisionWorld              = physicsWorld.PhysicsWorld.CollisionWorld
            };

            var oaJobHandle = oaJob.ScheduleParallel(obstacleQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, oaJobHandle);

            if (bootstrap.usePartitioning)
            {
                cells.Clear();
                var partitionJob = new PartitionSpaceJob()
                {
                    positions   = this.positions,
                    cells       = this.cells.AsParallelWriter(),
                    threedcells = bootstrap.threedcells,
                    cellSize    = bootstrap.cellSize,
                    gridSize    = bootstrap.gridSize
                };

                var partitionHandle = partitionJob.Schedule(bootstrap.numBoids, 50, Dependency);
                Dependency = JobHandle.CombineDependencies(Dependency, partitionHandle);
            }
            var countNeighbourJob = new CountNeighboursJob()
            {
                positions             = this.positions,
                rotations             = this.rotations,
                neighbours            = this.neighbours,
                maxNeighbours         = bootstrap.totalNeighbours,
                cells                 = this.cells,
                cellSize              = bootstrap.cellSize,
                gridSize              = bootstrap.gridSize,
                usePartitioning       = bootstrap.usePartitioning,
                neighbourDistance     = bootstrap.neighbourDistance,
                boidTypeHandle        = bTHandle,
                translationTypeHandle = ttTHandle,
                rotationTypeHandle    = rTHandle
            };
            var cnjHandle = countNeighbourJob.ScheduleParallel(translationsRotationsQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, cnjHandle);

            var constrainJob = new ConstrainJob()
            {
                positions           = this.positions,
                boidTypeHandle      = bTHandle,
                constrainTypeHandle = conTHandle,
                weight = bootstrap.constrainWeight,
                centre = bootstrap.transform.position,
                radius = bootstrap.radius
            };

            var conjHandle = constrainJob.ScheduleParallel(constrainQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, conjHandle);


            var seperationJob = new SeperationJob()
            {
                positions             = this.positions,
                maxNeighbours         = this.maxNeighbours,
                random                = random,
                neighbours            = this.neighbours,
                weight                = bootstrap.seperationWeight,
                seperationTypeHandle  = sTHandle,
                translationTypeHandle = ttTHandle,
                boidTypeHandle        = bTHandle,
            };

            var sjHandle = seperationJob.ScheduleParallel(seperationQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, sjHandle);

            var cohesionJob = new CohesionJob()
            {
                positions          = this.positions,
                maxNeighbours      = this.maxNeighbours,
                neighbours         = this.neighbours,
                weight             = bootstrap.cohesionWeight,
                cohesionTypeHandle = cTHandle,
                boidTypeHandle     = bTHandle,
            };

            var cjHandle = cohesionJob.ScheduleParallel(cohesionQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, cjHandle);

            var alignmentJob = new AlignmentJob()
            {
                rotations           = this.rotations,
                maxNeighbours       = this.maxNeighbours,
                neighbours          = this.neighbours,
                weight              = bootstrap.alignmentWeight,
                alignmentTypeHandle = aTHandle,
                boidTypeHandle      = bTHandle,
            };

            var ajHandle = alignmentJob.ScheduleParallel(alignmentQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, ajHandle);

            var wanderJob = new WanderJob()
            {
                wanderTypeHandle      = wTHandle,
                translationTypeHandle = ttTHandle,
                rotationTypeHandle    = rTHandle,
                boidTypeHandle        = bTHandle,
                dT     = deltaTime,
                ran    = random,
                weight = bootstrap.wanderWeight
            };

            var wanderJobHandle = wanderJob.ScheduleParallel(wanderQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, wanderJobHandle);

            var boidJob = new BoidJob()
            {
                positions             = this.positions,
                rotations             = this.rotations,
                speeds                = this.speeds,
                dT                    = deltaTime,
                limitUpAndDown        = bootstrap.limitUpAndDown,
                banking               = 0.01f,
                damping               = 0.01f,
                wanderTypeHandle      = wTHandle,
                boidTypeHandle        = bTHandle,
                translationTypeHandle = ttTHandle,
                seperationTypeHandle  = sTHandle,
                rotationTypeHandle    = rTHandle,
                cohesionTypeHandle    = cTHandle,
                alignmentTypeHandle   = aTHandle,
                constrainTypeHandle   = conTHandle,
                obstacleTypeHandle    = oaTHandle
            };

            var boidJobHandle = boidJob.ScheduleParallel(boidQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, boidJobHandle);

            var copyFromNativeJob = new CopyTransformsFromNativeJob()
            {
                positions             = this.positions,
                rotations             = this.rotations,
                boidTypeHandle        = bTHandle,
                translationTypeHandle = ttTHandle,
                rotationTypeHandle    = rTHandle
            };

            var copyFromNativeHandle = copyFromNativeJob.ScheduleParallel(translationsRotationsQuery, 1, Dependency);

            Dependency = JobHandle.CombineDependencies(Dependency, copyFromNativeHandle);

            return;
        }