void ComputeWeightAndAccelerations(BoidR currentBoid, BoidR otherBoid, Vector3 collision, Vector3 velocityMatch, Vector3 centering) { float visualFieldWeight = ComputeVisualFieldWeight(currentBoid, otherBoid); Vector3 distance = GetDistanceBetweenBoids(currentBoid, otherBoid); float distanceWeight = ComputeDistanceWeight(distance); collision = AddCollisionForce(collision, visualFieldWeight, distanceWeight, distance); velocityMatch = AddVelocityForce(velocityMatch, visualFieldWeight, distanceWeight, currentBoid, otherBoid); centering = AddCenteringForce(centering, visualFieldWeight, distanceWeight, distance); }
void ComputePosition(Vector3 acceleration, BoidR boid, int i, int j, int k) { Vector3 tempPosition = boid.transform.position; float deltaTimeSquared = (Time.fixedDeltaTime * Time.fixedDeltaTime); //Euler's integration Vector3 newPosition = (2.0f * boid.transform.position) - boid.LastPosition + (deltaTimeSquared * acceleration); boid.transform.position = newPosition; boid.LastPosition = tempPosition; }
float ComputeVisualFieldWeight(BoidR thisBoid, BoidR thatBoid) { float binocularAngleOverTwo = thisBoid.BinocularAreaRangeAngle / 2; float fullVisionAngleOverTwo = thisBoid.FullVisionAngle / 2; float visualAngleMagnitude = Vector3.Angle(thisBoid.Velocity, thatBoid.transform.position); if (visualAngleMagnitude > fullVisionAngleOverTwo) { return(0); } if ((binocularAngleOverTwo <= visualAngleMagnitude) && (visualAngleMagnitude < fullVisionAngleOverTwo)) { return((fullVisionAngleOverTwo - visualAngleMagnitude) / (fullVisionAngleOverTwo - binocularAngleOverTwo)); } if ((binocularAngleOverTwo < visualAngleMagnitude) && (visualAngleMagnitude < binocularAngleOverTwo)) { return(1.0f); } return(-1); }
Vector3 GetDistanceBetweenBoids(BoidR currentBoid, BoidR otherBoid) { return(otherBoid.gameObject.transform.position - currentBoid.gameObject.transform.position); }
Vector3 AddVelocityForce(Vector3 velocityMatch, float fieldWeight, float distanceWeight, BoidR currBoid, BoidR otherBoid) { velocityMatch += fieldWeight * distanceWeight * (kVelocityScale * (otherBoid.Velocity - currBoid.Velocity)); return(velocityMatch); }
Vector3 ComputeVelocity(Vector3 acceleration, BoidR boid) { return(acceleration * Time.fixedDeltaTime + boid.Velocity); }
void UpdateBoidPositions() { BoidR currentBoid; Vector3 currentBoidPosition; List <GameObject> boidNeighbours = new List <GameObject>(); for (int i = 0; i < flySpace; i++) { for (int j = 0; j < flySpace; j++) { for (int k = 0; k < flySpace; k++) { if (VoxelEmpty(i, j, k)) { continue; } int boidCountAtVoxel = VoxelCount(i, j, k); int neighbourCount; //init forces Vector3 collision = Vector3.zero; Vector3 velocityMatch = Vector3.zero; Vector3 centering = Vector3.zero; for (int boidVoxelIndex = 0; boidVoxelIndex < boidCountAtVoxel; boidVoxelIndex++) { currentBoid = GetBoid(i, j, k, boidVoxelIndex); currentBoidPosition = GetBoidPosition(i, j, k, boidVoxelIndex); boidNeighbours = GetBoidNeighbours(i, j, k); neighbourCount = boidNeighbours.Count; for (int neighbourIndex = 0; neighbourIndex < neighbourCount; neighbourIndex++) { int currentBoidID = currentBoid.GetInstanceID(); int boidNeighbourID = boidNeighbours[boidVoxelIndex].GetInstanceID(); if (currentBoidID == boidNeighbourID) { continue; } BoidR otherBoid = boidNeighbours[neighbourIndex].GetComponent <BoidR>(); ComputeWeightAndAccelerations(currentBoid, otherBoid, collision, velocityMatch, centering); } Vector3 acceleration = GetAccelerationPrioritization(collision, velocityMatch, centering); currentBoid.Velocity = ComputeVelocity(acceleration, currentBoid); ComputePosition(acceleration, currentBoid, i, j, k); //Vector3 temp = currentBoidPosition; //spatialGrid[i, j, k][boidVoxelIndex].transform.position = // (2.0f * currentBoidPosition) - currentBoid.LastPosition + ((Time.deltaTime * Time.deltaTime) * (acceleration)); //currentBoid.LastPosition = temp; boidNeighbours.Clear(); } } } } foreach (var list in spatialGrid) { list.Clear(); } //int gridTotalLength = spatialGrid.GetLength(0) * spatialGrid.GetLength(1) * spatialGrid.GetLength(2); //System.Array.Clear(spatialGrid, 0, gridTotalLength); }