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; } }
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; }