/// <summary> /// Function that will be executed in parallel to calculate steerings /// </summary> /// <param name="item"></param> private void ParallelSteering(KeyValuePair <int, List <Boid> > item) { List <Boid> list = item.Value; if (list == null || list.Count <= 0) { return; } int numBoidsInCell = list.Count; Vector3 cellAlignment = Vector3.zero; Vector3 cellSeparation = Vector3.zero; for (int i = 0; i < numBoidsInCell; i++) { Boid b = list[i]; cellAlignment += b.Fwd; cellSeparation += b.Pos; } Vector3 avgCellPos = cellSeparation / numBoidsInCell; FindNearest(obstacles, avgCellPos, out BoidInterestPos nearestObstacle, out float nearestObstacleDist); FindNearest(targets, avgCellPos, out BoidInterestPos nearestTarget, out float nearestTargetDist); for (int i = numBoidsInCell - 1; i >= 0; i--) { Boid b = list[i]; Vector3 fwd = b.Fwd; Vector3 pos = b.Pos; Vector3 obstacleSteering = pos - nearestObstacle.Pos; Vector3 avoidObstacleHeading = (nearestObstacle.Pos + Vector3.Normalize(obstacleSteering) * obstacleAversionDistance) - pos; Vector3 targetHeading = targetWeight * Vector3.Normalize(nearestTarget.Pos - pos); float nearestObstacleDistanceFromRadius = nearestObstacleDist - obstacleAversionDistance; Vector3 alignmentResult = alignmentWeight * Vector3.Normalize((cellAlignment / numBoidsInCell) - fwd); Vector3 separationResult = separationWeight * Vector3.Normalize((pos * numBoidsInCell) - cellSeparation); Vector3 normalHeading = Vector3.Normalize(alignmentResult + separationResult + targetHeading); Vector3 targetForward = nearestObstacleDistanceFromRadius < 0.0 ? avoidObstacleHeading : normalHeading; Vector3 nextHeading = Vector3.Normalize(fwd + dt * (targetForward - fwd)); Vector3 nextPos = pos + (nextHeading * (moveSpeed * dt)); b.Fwd = nextHeading; b.Pos = nextPos; Quaternion rot = Quaternion.LookRotation(nextHeading, Vector3.up); matrices[b.OuterBatchesIndex][b.InnerBatchesIndex].SetTRS(nextPos, rot, Vector3.one); list.RemoveAt(i); } boidsDictConcurrent.PushList(list); }