/// <summary>
        /// Create a path from XZ nodes defined in a pathFile.
        /// The file must be accessible from the executable environment.
        /// </summary>
        /// <param name="theStage"> "world's stage" </param>
        /// <param name="aPathType"> SINGLE, REVERSE, or LOOP path traversal</param>
        /// <param name="pathFile"> text file, each line a node of X Z values, separated by a single space </x></param>
        public Path(Stage theStage, PathType aPathType, string pathFile)
            : base(theStage)
        {
            node = new List<NavNode>();
            stage = theStage;
            nextNode = 0;
            pathType = aPathType;
            done = false;

            // read file
            using (StreamReader fileIn = File.OpenText(pathFile)) {
                int x, z;
                string line;
                string[] tokens;
                line = fileIn.ReadLine();

                do {
                    // use default separators
                    tokens = line.Split(new char[] { });
                    x = Int32.Parse(tokens[0]);
                    z = Int32.Parse(tokens[1]);
                    node.Add(new NavNode(new Vector3(x, 0, z), NavNode.NavNodeEnum.WAYPOINT));
                    line = fileIn.ReadLine();
                }
                while (line != null);
            }
        }
 public Camera(Stage aScene, CameraEnum whichCameraType)
 {
     Name = "Whole stage";
     scene = aScene;
     whichCamera = whichCameraType;
     terrainCenter = scene.TerrainSize / 2;
     UpdateViewMatrix();
 }
 /// <summary>
 /// Create a path
 /// </summary>
 /// <param name="theStage"> "world's stage" </param>
 /// <param name="apath"> collection of nodes in path</param>
 /// <param name="aPathType"> SINGLE, REVERSE, or LOOP path traversal</param>
 public Path(Stage theStage, List<NavNode> aPath, PathType aPathType, bool flag)
     : base(theStage)
 {
     node = aPath;
     nextNode = 0;
     pathType = aPathType;
     stage = theStage;
     done = false;
     drawFlag = flag;
 }
        public Treasure(Stage theStage, string label, string fileOfModel, Vector3 position, Vector3 up, float scale)
            : base(theStage, label, fileOfModel)
        {
            AddObject(position, up, scale);
            treasureObject = instance.First<Object3D>();
            isOpen = false;

            closeStateModel = stage.Content.Load<Model>(HIDDEN_TREASURE_FILENAME);
            openStateModel = stage.Content.Load<Model>(FOUND_TREASURE_FILENAME);
        }
        public Player(Stage theStage, string label, Vector3 pos,  
                      Vector3 orientAxis, float radians, string meshFile)
            : base(theStage, label, pos, orientAxis, radians, meshFile)
        {
            // change names for on-screen display of current camera

            first.Name = "First";
            follow.Name = "Follow";
            above.Name = "Above";

            IsCollidable = true;  // Player test collisions
            rotate = 0;
            angle = 0.01f;
            initialOrientation = agentObject.Orientation;
        }
        public Model3D(Stage theStage, string label, string fileOfModel)
            : base(theStage)
        {
            name = label;
            stage = theStage;
            instance = new List<Object3D>();
            model = stage.Content.Load<Model>(fileOfModel);

            // compute the translation to the model's bounding sphere
            // center and radius;
            float minX, minY, minZ, maxX, maxY, maxZ;
            minX = minY = minZ = Int32.MaxValue;
            maxX = maxY = maxZ = Int32.MinValue;

            for (int i = 0; i < model.Meshes.Count; i++) {
                // See if this mesh extends the bounding sphere.
                BoundingSphere aBoundingSphere = model.Meshes[i].BoundingSphere;
                if ((aBoundingSphere.Center.X - aBoundingSphere.Radius) < minX)
                    minX = aBoundingSphere.Center.X - aBoundingSphere.Radius;
                if ((aBoundingSphere.Center.Y - aBoundingSphere.Radius) < minY)
                    minY = aBoundingSphere.Center.Y - aBoundingSphere.Radius;
                if ((aBoundingSphere.Center.Z - aBoundingSphere.Radius) < minZ)
                    minZ = aBoundingSphere.Center.Z - aBoundingSphere.Radius;
                if ((aBoundingSphere.Center.X + aBoundingSphere.Radius) > maxX)
                    maxX = aBoundingSphere.Center.X + aBoundingSphere.Radius;
                if ((aBoundingSphere.Center.Y + aBoundingSphere.Radius) > maxY)
                    maxY = aBoundingSphere.Center.Y + aBoundingSphere.Radius;
                if ((aBoundingSphere.Center.Z + aBoundingSphere.Radius) > maxZ)
                    maxZ = aBoundingSphere.Center.Z + aBoundingSphere.Radius;
            }

            // get the diameter of model's bounding sphere
            // radius temporarily holds the largest diameter
            if ((maxX - minX) > boundingSphereRadius)
                boundingSphereRadius = maxX - minX;
            if ((maxY - minY) > boundingSphereRadius)
                boundingSphereRadius = maxY - minY;
            if ((maxZ - minZ) > boundingSphereRadius)
                boundingSphereRadius = maxZ - minZ;

            // set boundingSphereRadius
            boundingSphereRadius = boundingSphereRadius * 1.1f / 2.0f;  // set the radius from largest diameter

            // set the center of model's bounding sphere
            boundingSphereCenter =
              new Vector3(minX + boundingSphereRadius, minY + boundingSphereRadius, minZ + boundingSphereRadius);
            // need to scale boundingSphereRadius for each object instances in Object3D
        }
        /// <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
        /// 
        /// </summary>
        public Agent(Stage stage, string label, Vector3 position, Vector3 orientAxis, float radians, string meshFile)
            : base(stage, label, meshFile)
        {
            AddObject(position, orientAxis, radians);
            agentObject = instance.First<Object3D>();

            // create 3 cameras
            first = new Camera(stage, agentObject, Camera.CameraEnum.FirstCamera);
            follow = new Camera(stage, agentObject, Camera.CameraEnum.FollowCamera);
            above = new Camera(stage, agentObject, Camera.CameraEnum.AboveCamera);

            // add 3 cameras to Stage
            stage.AddCamera(first);
            stage.AddCamera(follow);
            stage.AddCamera(above);

            // initialize the first camera
            agentCamera = first;
            taggedTreasures = 0;
        }
        /// <summary>
        /// Object that places, orients, and scales itself.
        /// </summary>
        /// <param name="theStage"> the stage containing object </param> 
        /// <param name="aModel">how the object looks</param> 
        /// <param name="label"> name of object </param> 
        /// <param name="position"> position in stage </param> 
        /// <param name="orientAxis"> axis to orient on </param> 
        /// <param name="radians"> orientation rotation </param> 
        /// <param name="objectScales">re-scale Model3D </param>  
        public Object3D(Stage theStage, Model3D aModel, string label, Vector3 position, Vector3 orientAxis, float radians, Vector3 objectScales)
        {
            stage = theStage;
            name = label;
            scales = objectScales;
            model = aModel;
            step = 1;
            stepSize = 10;
            pitch = yaw = roll = 0.0f;

            // set object orientation
            /*
             *  ---------------------
             *  | Rx | Ry | Rz | Rw |  right
             *  ---------------------
             *  | Ux | Uy | Uz | Uw |  up
             *  ---------------------
             *  | Bx | By | Bz | Bw |  backward = -forward
             *  ---------------------
             *  | Tx | Ty | Yz | Tw |  translation
             *  ---------------------
             */
            orientation = Matrix.Identity;
            orientation *= Matrix.CreateScale(scales);
            orientation *= Matrix.CreateFromAxisAngle(orientAxis, radians);
            orientation *= Matrix.CreateTranslation(position);

            // scale it's bounding sphere
            ScaleObjectBoundingSphere();
        }
 // Constructor
 public Cloud(Stage stage, string label, string meshFile)
     : base(stage, label, meshFile)
 {
     random = new Random();
 }
        public Wall(Stage theStage, string label, string meshFile)
            : base(theStage, label, meshFile)
        {
            isCollidable = true;

            // "just another brick in the wall", Pink Floyd
            int spacing = stage.Terrain.Spacing;
            Terrain terrain = stage.Terrain;
            int wallBaseX = 300;
            int wallBaseZ = 448;
            int xPos, zPos;

            // a brick for testing npAgent !collision
            // AddObject(new Vector3(495 * spacing, terrain.surfaceHeight(495, 500), 500 * spacing), Vector3.Up, 0.0f);

            // 8 right
            for (int i = 0; i < 7; i++) {
                xPos = i + wallBaseX;
                zPos = wallBaseZ;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            // up 7 then down 18
            for (int i = 0; i < 18; i++) {
                xPos = wallBaseX + 7;
                zPos = i - 7 + wallBaseZ;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            // 4 up, after skipping 3 left
            for (int i = 0; i < 4; i++) {
                xPos = wallBaseX + 1;
                zPos = wallBaseZ + 10 - i;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            //  up 1 left 8
            for (int i = 0; i < 8; i++) {
                xPos = -i + wallBaseX + 1;
                zPos = wallBaseZ + 6;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            // up 12
            for (int i = 0; i < 12; i++) {
                xPos = wallBaseX - 6;
                zPos = -i + wallBaseZ + 5;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            // 8 right
            for (int i = 0; i < 8; i++) {
                xPos = i + wallBaseX - 6;
                zPos = wallBaseZ - 6;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }

            // up 2
            for (int i = 0; i < 2; i++) {
                xPos = wallBaseX + 1;
                zPos = wallBaseZ - 6 - i;
                AddObject(new Vector3(xPos * spacing, terrain.SurfaceHeight(xPos, zPos), zPos * spacing), Vector3.Up, 0.0f);
            }
        }
 public IndexVertexBuffers(Stage theStage, string label)
     : base(theStage)
 {
     stage = theStage;
     name = label;
 }
 public Camera(Stage aScene, Object3D anAgentObject, CameraEnum whichCameraType)
 {
     scene = aScene;
     agent = anAgentObject;
     whichCamera = whichCameraType;
 }
 //   public MovableModel3D(Stage theStage, string label, Vector3 position,
 //   Vector3 orientAxis, float radians, string meshFile)
 //      : base(theStage, label, position, orientAxis, radians, meshFile)
 public MovableModel3D(Stage theStage, string label, string meshFile)
     : base(theStage, label, meshFile)
 {
 }
        public Terrain(Stage theStage, string label, string heightFile, string colorFile)
            : base(theStage, label)
        {
            range = stage.Range;
            width = height = range;
            nVertices = width * height;

            terrainHeight = new int[width, height];

            vertex = new VertexPositionColor[nVertices];
            nIndices = (width - 1) * (height - 1) * 6;
            indices = new int[nIndices];  // there are 6 indices 2 faces / 4 vertices
            spacing = stage.Spacing;

            // set display information
            display = stage.Display;
            effect = stage.SceneEffect;
            heightTexture = stage.Content.Load<Texture2D>(heightFile);
            heightMap = new Microsoft.Xna.Framework.Color[width * height];
            heightTexture.GetData<Microsoft.Xna.Framework.Color>(heightMap);

            // create colorMap values from colorTexture
            colorTexture = stage.Content.Load<Texture2D>(colorFile);
            colorMap = new Microsoft.Xna.Framework.Color[width * height];
            colorTexture.GetData<Microsoft.Xna.Framework.Color>(colorMap);

            // create  vertices for terrain
            Vector4 vector4;
            int vertexHeight;

            int i = 0;
            for (int z = 0; z < height; z++) {
                for (int x = 0; x < width; x++) {
                    vector4 = heightMap[i].ToVector4();        // convert packed Rgba32 values to floats
                    vertexHeight = (int) (vector4.X * 255);    // scale vertexHeight 0..255
                    vertexHeight = (int) (vector4.X * 255);    // scale vertexHeight 0..255
                    vertexHeight *= multiplier;                // multiply height
                    terrainHeight[x, z] = vertexHeight;        // save height for navigation

                    vertex[i] = new VertexPositionColor(
                       new Vector3(x * spacing, vertexHeight, z * spacing),
                       new Color(colorMap[i].ToVector4()));
                    i++;
                }
            }

            // free up unneeded maps
            colorMap = null;
            heightMap = null;
            // set indices clockwise from point of view
            i = 0;
            for (int z = 0; z < height - 1; z++) {
                for (int x = 0; x < width - 1; x++) {
                    indices[i++] = z * width + x;
                    indices[i++] = z * width + x + 1;
                    indices[i++] = (z + 1) * width + x;
                    indices[i++] = (z + 1) * width + x;
                    indices[i++] = z * width + x + 1;
                    indices[i++] = (z + 1) * width + x + 1;
                }
            }

            // create VertexBuffer and store on GPU
            vb = new VertexBuffer(display, typeof(VertexPositionColor), vertex.Length, BufferUsage.WriteOnly);
            vb.SetData<VertexPositionColor>(vertex); // , 0, vertex.Length);
            // create IndexBuffer and store on GPU
            ib = new IndexBuffer(display, typeof(int), indices.Length, BufferUsage.WriteOnly);
            IB.SetData<int>(indices);
        }
        // constructors
        /// <summary>
        /// Object that places and orients itself.
        /// </summary>
        /// <param name="theStage"> the stage containing object </param> 
        /// <param name="aModel">how the object looks</param> 
        /// <param name="label"> name of object </param> 
        /// <param name="position"> position in stage </param> 
        /// <param name="orientAxis"> axis to orient on </param> 
        /// <param name="radians"> orientation rotation </param> 
        public Object3D(Stage theStage, Model3D aModel, string label, Vector3 position, Vector3 orientAxis, float radians)
        {
            scales = Vector3.One;
            stage = theStage;
            model = aModel;
            name = label;

            step = 1;
            stepSize = 10;
            pitch = yaw = roll = 0.0f;

            orientation = Matrix.Identity;
            orientation *= Matrix.CreateFromAxisAngle(orientAxis, radians);
            orientation *= Matrix.CreateTranslation(position);

            ScaleObjectBoundingSphere();
        }
        /// <summary>
        /// Create a NPC. 
        /// AGXNASK distribution has npAgent move following a Path.
        /// </summary>
        /// <param name="theStage"> the world</param>
        /// <param name="label"> name of </param>
        /// <param name="pos"> initial position </param>
        /// <param name="orientAxis"> initial rotation axis</param>
        /// <param name="radians"> initial rotation</param>
        /// <param name="meshFile"> Direct X *.x Model in Contents directory </param>
        public NPAgent(Stage theStage, string label, Vector3 pos, Vector3 orientAxis, float radians, string meshFile)
            : base(theStage, label, pos, orientAxis, radians, meshFile)
        {
            IsCollidable = true;

            first.Name = "npFirst";
            follow.Name = "npFollow";
            above.Name = "npAbove";

            // initialize all treasures
            InitializeMarkTreasures();

            // initialize treasure path queue
            treasurePathQueue = new Queue<Path>();
            // initialize exploring path queue
            explorePathQueue = new Queue<Path>();

            // add all predefined path to explore path queue
            // AddPathToExploreQueue();

            Path initialPath = new Path(stage, MakeExploringPaths(), Path.PathType.SINGLE, true);

             // set it to current path
            currentPath = initialPath;

            // set the mode
            mode = ModeEnum.EXPLORING;
            npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;

            stage.Components.Add(currentPath);
            nextGoal = currentPath.NextNode;
            agentObject.TurnToFace(nextGoal.Translation);
        }
        /// <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)
        {
            random = new Random();
            isCollidable = true;
            leader = null;
            flockMode = FlockEnum.FLOCK_0_PERCENT;

            InitializeFlocing();
        }