/// <summary> /// Function that will be executed in parallel to add the boids to the dictionary /// </summary> /// <param name="b"></param> private void ParallelAddToDict(Boid b) { boidsDictConcurrent.Add(b); }
/// <summary> /// Do the boids steering /// </summary> private void DoSteeringSingleThread() { foreach (KeyValuePair <int, List <Boid> > item in boidsDict.DictLists) { List <Boid> list = item.Value; if (list == null || list.Count <= 0) { continue; } int numBoidsInCell = list.Count; Vector3 cellAlignment = Vector3.zero; Vector3 cellSeparation = Vector3.zero; // each list has the boids that are within the same cell Unity is using a different // approach from what I previously did in my first test avoiding to compute local // avoidance between boids themselves is probably boosting performance significantly // they probable went for that to have a more "impressive" numbers on their demo... for (int i = 0; i < numBoidsInCell; i++) { Boid b = list[i]; cellAlignment += b.Fwd; cellSeparation += b.Pos; } // it seems Unity does this just finding the nearest to the first element found in a // cell, if I understood correctly I guess i can take the average 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.Pos = nextPos; b.Fwd = nextHeading; Quaternion rot = Quaternion.LookRotation(nextHeading, Vector3.up); matrices[b.OuterBatchesIndex][b.InnerBatchesIndex].SetTRS(nextPos, rot, Vector3.one); list.RemoveAt(i); } boidsDict.PushList(list); } }