Exemplo n.º 1
0
 /// <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);
 }
Exemplo n.º 2
0
        /// <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);
            }
        }