/// <summary> /// Align our bird within the flock. /// For every nearby bird in the system, calculate the average velocity /// and move us towards that - this keeps us moving with the flock. /// </summary> /// <param name='birds'> /// Birds. all the birds in the scene - we only really care about those in the neighbourdist /// </param> Vector3 Align (List<Bird> birds) { Vector3 steer = new Vector3 (0, 0, 0); int count = 0; foreach (Bird other in birds) { float d = Vector3.Distance (m_loc, other.Location); if ((d > 0) && (d < m_model.NeighbourDistance)) { steer += other.Velocity; count++; } } if (count > 0) { steer /= (float)count; } // As long as the vector is greater than 0 if (steer.Length () > 0) { // Implement Reynolds: Steering = Desired - Velocity steer.Normalize (); steer *= m_model.MaxSpeed; steer -= m_vel; //steer.limit(maxforce); steer = BirdsUtil.Limit (steer, m_model.MaxForce); } return steer; }
/// A method that calculates a steering vector towards a target /// Takes a second argument, if true, it slows down as it approaches the target Vector3 Steer (Vector3 target, bool slowdown) { Vector3 steer; // The steering vector Vector3 desired = Vector3.Subtract(target, m_loc); // A vector pointing from the location to the target float d = desired.Length (); // Distance from the target is the magnitude of the vector // If the distance is greater than 0, calc steering (otherwise return zero vector) if (d > 0) { // Normalize desired desired.Normalize (); // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed) if ((slowdown) && (d < 100.0f)) { desired *= (m_model.MaxSpeed * (d / 100.0f)); // This damping is somewhat arbitrary } else { desired *= m_model.MaxSpeed; } // Steering = Desired minus Velocity //steer = target.sub(desired,m_vel); steer = Vector3.Subtract (desired, m_vel); //steer.limit(maxforce); // Limit to maximum steering force steer = BirdsUtil.Limit (steer, m_model.MaxForce); } else { steer = Vector3.Zero; } return steer; }
/// <summary> /// Separate ourselves from the specified birds. /// keeps us a respectable distance from our closest neighbours whilst still /// being part of our local flock /// </summary> /// <param name='birds'> /// Birds. all the birds in the scene /// </param> Vector3 Separate (List<Bird> birds) { Vector3 steer = new Vector3 (0, 0, 0); int count = 0; // For every bird in the system, check if it's too close foreach (Bird other in birds) { float d = Vector3.Distance (m_loc, other.Location); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < m_model.DesiredSeparation)) { // Calculate vector pointing away from neighbor Vector3 diff = Vector3.Subtract (m_loc, other.Location); diff.Normalize (); diff = Vector3.Divide (diff, d); steer = Vector3.Add (steer, diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { steer /= (float)count; } // As long as the vector is greater than 0 if (steer.Length () > 0) { // Implement Reynolds: Steering = Desired - Velocity steer.Normalize (); steer *= m_model.MaxSpeed; steer -= m_vel; //steer.limit(maxforce); steer = BirdsUtil.Limit (steer, m_model.MaxForce); } return steer; }
/// <summary> /// Method to update our location within the scene. /// update our location in the world based on our /// current location, velocity and acceleration /// taking into account our max speed /// /// </summary> void UpdatePositionInScene () { // Update velocity //vel.add(acc); m_vel += m_acc; // Limit speed //m_vel.limit(maxspeed); m_vel = BirdsUtil.Limit (m_vel, m_model.MaxSpeed); m_loc += m_vel; // Reset accelertion to 0 each cycle m_acc *= 0.0f; }