public void setSurfaceHeight(Object3D anObject3D)
 {
     float terrainHeight = terrain.surfaceHeight((anObject3D.Translation.X / spacing),
                                                  (anObject3D.Translation.Z / spacing));
     anObject3D.Translation = new Vector3(anObject3D.Translation.X,
                                           terrainHeight, anObject3D.Translation.Z);
 }
 public Camera(Stage aScene, Object3D anAgentObject, CameraEnum cameraType)
 {
     scene = aScene;
     agent = anAgentObject;
     cameraCase = cameraType;
 }
 /// <summary>
 /// Construct a leaderless pack.
 /// </summary>
 /// <param name="theStage"> the scene</param>
 /// <param name="label"> name of pack</param>
 /// <param name="meshFile"> model of pack instance</param>
 public Pack(Stage theStage, string label, string meshFile)
     : base(theStage, label, meshFile)
 {
     isCollidable = true;
     leader = null;
     random = new Random();
 }
 // Methods
 public bool isCollidable(Object3D obj3d)
 {
     if (collidable.Contains(obj3d)) return true;
     else return false;
 }
        // Apply separation rules
        public Vector3 getSeparation(Object3D current)
        {
            Vector3 separation = Vector3.Zero;
            float distanceRadius = 700;
            foreach (Object3D obj in instance)
            {
                if (current != obj)
                {
                    Vector3 header = current.Translation - obj.Translation;
                    // If distance between current boid and another object is less than distanceRadius
                    // add to the separation force
                    if (header.Length() < distanceRadius)
                    {
                        separation += 5 * Vector3.Normalize(header) / (header.Length() / distanceRadius);
                    }
                }
            }

            // Add separation between leader and other boids
            if (Vector3.Distance(leader.Translation, current.Translation) < distanceRadius)
            {
                Vector3 header = current.Translation - leader.Translation;
                separation += 5 * Vector3.Normalize(header) / (header.Length() / distanceRadius);

            }
            return 2 * separation;
        }
 public bool isFlockMember(Object3D current)
 {
     return flockMembers[instance.IndexOf(current)];
 }
        // Apply cohesion rules
        public Vector3 getCohesion(Object3D current)
        {
            Vector3 cohesion = Vector3.Zero;
            // Get vector toward leader's position
            cohesion = leader.Translation - current.Translation;
            cohesion.Normalize();

            // Multiply by random cohesion force between 0 and 15
            return cohesion * 15 * (float)random.NextDouble();
        }
        // Apply alignment rules
        public Vector3 getAlignment(Object3D current)
        {
            Vector3 alignment = leader.Forward;
            Vector3 averageDelta = Vector3.Zero;
            int N = 0;

            // Get the average difference between the current boid's forward vector and leader's
            foreach (Object3D obj in instance)
            {
                if (obj != current)
                {
                    averageDelta += alignment - current.Forward;
                    N++;
                }
            }

            if (N > 0)
            {
                averageDelta /= N;
                averageDelta.Normalize();
            }
            return 0.45f * averageDelta;
        }
 /// <summary>
 /// Construct a pack with an Object3D leader
 /// </summary>
 /// <param name="theStage"> the scene </param>
 /// <param name="label"> name of pack</param>
 /// <param name="meshFile"> model of a pack instance</param>
 /// <param name="aLeader"> Object3D alignment and pack center </param>
 public Pack(Stage theStage, string label, string meshFile, Object3D aLeader)
     : base(theStage, label, meshFile)
 {
     isCollidable = true;
     leader = aLeader;
     random = new Random();
     flockMembers = new List<Boolean>();
 }
 /// <summary>
 /// Create a new Object3D, place it on the stage, add to Model3D's instance collection, 
 /// and if collidable add to collision collection. 
 /// </summary>
 /// <param name="position"> location of new Object3D</param>
 /// <param name="orientAxis"> axis of rotation</param>
 /// <param name="radians"> rotation on orientAxis</param>
 /// <returns> the new Object3D</returns>
 public virtual Object3D addObject(Vector3 position, Vector3 orientAxis, float radians)
 {
     Object3D obj3d = new Object3D(stage, this, String.Format("{0}.{1}", name, instance.Count),
        position, orientAxis, radians, Vector3.One);
     obj3d.updateBoundingSphere();  // need to do only once for Model3D
     instance.Add(obj3d);
     if (IsCollidable) stage.Collidable.Add(obj3d);
     this.position = position;
     return obj3d;
 }
 /// <summary>
 /// Create an Agent.
 /// All Agents are collidable and have a single instance Object3D named agentObject.
 /// Set StepSize, create first, follow and above cameras.
 /// Set first as agentCamera
 /// <param name="stage"></param>
 /// <param name="label"></param>
 /// <param name="position"></param>
 /// <param name="orientAxis"></param>
 /// <param name="radians"></param>
 /// <param name="meshFile"></param>
 /// </summary>
 public Agent(Stage stage, string label, Vector3 position, Vector3 orientAxis,
    float radians, string meshFile)
     : base(stage, label, meshFile)
 {
     // create an Object3D for this agent
     agentObject = addObject(position, orientAxis, radians);
     first = new Camera(stage, agentObject, Camera.CameraEnum.FirstCamera);
     follow = new Camera(stage, agentObject, Camera.CameraEnum.FollowCamera);
     above = new Camera(stage, agentObject, Camera.CameraEnum.AboveCamera);
     stage.addCamera(first);
     stage.addCamera(follow);
     stage.addCamera(above);
     agentCamera = first;
 }