/// <summary>
 /// Set the Scene.
 /// The Scene contains all "application-specific" content that is to added to
 /// the "stage".
 /// LoadScene() is called at the end of Stage's LoadContent().
 /// </summary>
 private void LoadScene()
 {
     terrain = new Terrain(this, "terrain", "heightTexture", "colorTexture");
     Components.Add(terrain);
     // Load Avatar mesh objects, Avatar meshes do not have textures
     player = new Player(this, "Chaser",
        new Vector3(510 * spacing, terrain.surfaceHeight(510, 507), 507 * spacing),
        new Vector3(0, 1, 0), 0.80f, "redAvatarV3");  // face looking diagonally across stage
     player.IsCollidable = true;
     Components.Add(player);
     npAgent = new NPAgent(this, "Evader",
        new Vector3(400 * spacing, terrain.surfaceHeight(400, 400), 400 * spacing),
        new Vector3(0, 1, 0), 0.0f, "magentaAvatarV3");  // facing +Z
     npAgent.IsCollidable = true;
     Components.Add(npAgent);
 }
        /// <summary>
        /// Set GraphicDevice display and rendering BasicEffect effect.  
        /// Create SpriteBatch, font, and font positions.
        /// Creates the traceViewport to display information and the sceneViewport
        /// to render the environment.
        /// Create and add all DrawableGameComponents and Cameras.
        /// First, add all required contest:  Inspector, Cameras, Terrain, Agents
        /// Second, add all optional (scene specific) content
        /// </summary>
        protected override void LoadContent()
        {
            display = graphics.GraphicsDevice;
            effect = new BasicEffect(display);
            // Set up Inspector display
            spriteBatch = new SpriteBatch(display);      // Create a new SpriteBatch
            inspectorFont = Content.Load<SpriteFont>("CourierNew");    // Windows XNA || MonoGames
            // inspectorFont = Content.Load<SpriteFont>("Consolas");       // Ubuntu MonoGames
            // viewports
            defaultViewport = GraphicsDevice.Viewport;
            inspectorViewport = defaultViewport;
            sceneViewport = defaultViewport;
            inspectorViewport.Height = InfoPaneSize * inspectorFont.LineSpacing;
            inspectorProjection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4.0f,
               inspectorViewport.Width / inspectorViewport.Height, 1.0f, 200.0f);
            sceneViewport.Height = defaultViewport.Height - inspectorViewport.Height;
            sceneViewport.Y = inspectorViewport.Height;
            sceneProjection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4.0f,
               sceneViewport.Width / sceneViewport.Height, 1.0f, 1000.0f);
            // create Inspector display
            Texture2D inspectorBackground = Content.Load<Texture2D>("inspectorBackground");
            inspector = new Inspector(display, inspectorViewport, inspectorFont, Color.Black, inspectorBackground);
            // create information display strings
            // help strings
            inspector.setInfo(0, "AGMGSKv5 -- Academic Graphics MonoGames/XNA Starter Kit for CSUN Comp 565 assignments.");
            inspector.setInfo(1, "Press keyboard for input (not case sensitive 'H'  'h')");
            inspector.setInfo(2, "Inspector toggles:  'H' help or info   'M'  matrix or info   'I'  displays next info pane.");
            inspector.setInfo(3, "Arrow keys move the player in, out, left, or right.  'R' resets player to initial orientation.");
            inspector.setInfo(4, "Stage toggles:  'B' bounding spheres, 'C' cameras, 'F' fog, 'T' updates, 'Y' yon");
            inspector.setInfo(5, "Press 'P' to change packing level of flock");
            // initialize empty info strings
            for (int i = 5; i < 20; i++) inspector.setInfo(i, "  ");
            inspector.setInfo(5, "matrics info pane, initially empty");
            inspector.setInfo(10, "first info pane, initially empty");
            inspector.setInfo(15, "second info pane, initially empty");
            // set blending for bounding sphere drawing
            blending = new BlendState();
            blending.ColorSourceBlend = Blend.SourceAlpha;
            blending.ColorDestinationBlend = Blend.InverseSourceAlpha;
            blending.ColorBlendFunction = BlendFunction.Add;
            notBlending = new BlendState();
            notBlending = display.BlendState;
            // Create and add stage components
            // You must have a TopDownCamera, BoundingSphere3D, Terrain, and Agents (player, npAgent) in your stage!
            // Place objects at a position, provide rotation axis and rotation radians.
            // All location vectors are specified relative to the center of the stage.
            // Create a top-down "Whole stage" camera view, make it first camera in collection.
            topDownCamera = new Camera(this, Camera.CameraEnum.TopDownCamera);
            camera.Add(topDownCamera);
            boundingSphere3D = Content.Load<Model>("boundingSphereV3");
            wayPoint3D = Content.Load<Model>("100x50x100Marker");
            // Create required entities:
            collidable = new List<Object3D>();
            terrain = new Terrain(this, "terrain", "heightTexture", "colorTexture");
            Components.Add(terrain);
            // Load Agent mesh objects, meshes do not have textures
            player = new Player(this, "Chaser",
               new Vector3(510 * spacing, terrain.surfaceHeight(510, 507), 507 * spacing),
               new Vector3(0, 1, 0), 0.78f, "redAvatarV3");  // face looking diagonally across stage
            player.IsCollidable = true; // test collisions for player
            Components.Add(player);
            npAgent = new NPAgent(this, "Evader",
               new Vector3(490 * spacing, terrain.surfaceHeight(490, 475), 475 * spacing),
               new Vector3(0, 1, 0), 0.0f, "magentaAvatarV3");  // facing +Z
            npAgent.IsCollidable = false;
            // npAgent does not test for collisions
            Components.Add(npAgent);
            // ----------- CREATE OPTIONAL CONTENT HERE -----------------------
            // Load all optional content.  Content not requried by AGXNASK
            // create a temple
            Model3D m3d = new Model3D(this, "temple", "templeV3");
            m3d.IsCollidable = true;  // must be set before addObject(...) and Model3D doesn't set it
            m3d.addObject(new Vector3(200 * spacing, terrain.surfaceHeight(200, 200), 200 * spacing),
               new Vector3(0, 1, 0), 0.79f);
            Components.Add(m3d);

            // Add Treasures To Map
            Treasure tr = new Treasure(this, "t1", "hash");
            tr.addObject(new Vector3(477 * spacing, terrain.surfaceHeight(477, 290) + 110, 290 * spacing),
                new Vector3(0, 1, 0), 0.79f);
            Components.Add(tr);
            treasures.Add(tr);

            // inside the wall, rotated to fit
            tr = new Treasure(this, "t2", "hash");
            tr.addObject(new Vector3(446 * spacing, terrain.surfaceHeight(446, 450) + 110, 450 * spacing),
                new Vector3(0, 1, 0), 1.45f);
               Components.Add(tr);
               treasures.Add(tr);

               // Before Gibson
               tr = new Treasure(this, "t5", "hash");
               tr.addObject(new Vector3(470 * spacing, terrain.surfaceHeight(470, 144) + 210, 144 * spacing),
               new Vector3(0, 1, 0), 0.79f);
               Components.Add(tr);
               treasures.Add(tr);

            // Inside Gibson
            tr = new Treasure(this, "t3", "hash");
            tr.addObject(new Vector3(507 * spacing, terrain.surfaceHeight(507, 425) + 110, 425 * spacing),
                new Vector3(0, 1, 0), 0.79f);
            Components.Add(tr);
            treasures.Add(tr);

            // On Hill
            tr = new Treasure(this, "t4", "hash");
            tr.addObject(new Vector3(470 * spacing, terrain.surfaceHeight(470, 144) + 210, 144 * spacing),
                new Vector3(0, 1, 0), 0.79f);
            Components.Add(tr);
            treasures.Add(tr);

            /* Add a grid of pillars */
            /* Not collidable for now because it has a HUGE bounding sphere */
            Model3D pillar;
            int offset = 12;
            for (int i = 1; i < 12; i++)
            {
                for (int j = 1; j < 12; j++)
                {
                   /* Set Coordinators */
                    int x = (353 + (offset * i)) * spacing;
                    int z = (269 + (offset * j)) * spacing;
                    float y = terrain.surfaceHeight(x, z);

                    /* Add Small pillar inside big pillar to deal with collisions for now */
                    pillar = new Model3D(this, "p_sm" + i, "pillar_sm");
                    pillar.IsCollidable = true;
                    pillar.addObject(new Vector3(x + 570, y + 50, z-80), new Vector3(0, 1, 0), 0.79f);
                    Components.Add(pillar);

                    /* Gibson Pillar */
                    pillar = new Model3D(this, "p" + i, "pillar");
                    pillar.addObject(new Vector3(x, y + 300, z),  new Vector3(0, 1, 0), 0.79f);
                    Components.Add(pillar);
                }
            }

            // create walls for obstacle avoidance or path finding algorithms
            Wall wall = new Wall(this, "wall", "100x100x100Brick");
            Components.Add(wall);

            graph = new Graph(this);
            //Components.Add( graph.GetAStarPath(new Vector3(510 * spacing, terrain.surfaceHeight(510, 507), 507 * spacing), new Vector3(410 * spacing, terrain.surfaceHeight(410, 414) + 110, 414 * spacing)));

            Random random = new Random();  // used for pack and cloud
            // create a Pack of dogs with Player as the leader
            pack = new Pack(this, "dog", "dogV3", player.AgentObject);
            Components.Add(pack);
            for (int x = -9; x < 10; x += 6)
                for (int z = -3; z < 4; z += 6)
                {
                    float scale = (float)(0.5 + random.NextDouble());
                    float xPos = (480 + x) * spacing;  // position of pack
                    float zPos = (480 + z) * spacing;
                    pack.addObject(
                       new Vector3(xPos, terrain.surfaceHeight((int)xPos / spacing, (int)zPos / spacing), zPos),
                       new Vector3(0, 1, 0), 0.0f,
                       new Vector3(scale, scale, scale));
                }
            // create some clouds
            Cloud cloud = new Cloud(this, "cloud", "cloudV3");
            Components.Add(cloud);
            // add 9 cloud instances
            for (int x = range / 4; x < range; x += (range / 4))
                for (int z = range / 4; z < range; z += (range / 4))
                    cloud.addObject(
                       new Vector3(x * spacing, terrain.surfaceHeight(x, z) + 2000, z * spacing),
                       new Vector3(0, 1, 0), 0.0f,
                       new Vector3(random.Next(3) + 1, random.Next(3) + 1, random.Next(3) + 1));
            // ----------- end of optional content
            // Set initial camera and projection matrix
            nextCamera();  // select the first camera
        }