public ClothModel(GraphicFactory factory, PhysxPhysicWorld PhysxPhysicWorld, ClothMeshDescription clothMeshDesc,
                          XNA.Vector3[] Points,
                          XNA.Vector2[] TextCoords,
                          int[] Indices,
                          String diffuseTextureName = null)
            : base(factory, "Cloth", false)
        {
            this._diffuseName = diffuseTextureName;

            VerticesNum = Points.Length;
            IndicesNum  = Indices.Length;

            clothMeshDesc.AllocateVertices <Vector3>(VerticesNum);
            clothMeshDesc.AllocateTriangles <int>(IndicesNum / 3);

            clothMeshDesc.VertexCount   = VerticesNum;
            clothMeshDesc.TriangleCount = IndicesNum / 3;

            BatchInformation = new PloobsEngine.Modelo.BatchInformation(0, VerticesNum, IndicesNum / 3, 0, 0,
                                                                        VertexPositionNormalTexture.VertexDeclaration, VertexPositionNormalTexture.VertexDeclaration.VertexStride, PrimitiveType.TriangleList);
            BatchInformation.ModelLocalTransformation = XNA.Matrix.Identity;

            vertexPositionNormalTexture = new VertexPositionNormalTexture[VerticesNum];

            BatchInformation.VertexBuffer = factory.CreateDynamicVertexBuffer(VertexPositionNormalTexture.VertexDeclaration, VerticesNum + (int)(1.2 * VerticesNum), BufferUsage.WriteOnly);
            BatchInformation.IndexBuffer  = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, IndicesNum + (int)(1.2 * IndicesNum), BufferUsage.WriteOnly);

            BatchInformation.IndexBuffer.SetData <int>(Indices);
            clothMeshDesc.VerticesStream.SetData(Points);
            clothMeshDesc.TriangleStream.SetData(Indices);

            for (int i = 0; i < BatchInformation.NumVertices; i++)
            {
                vertexPositionNormalTexture[i].TextureCoordinate = TextCoords[i];
                vertexPositionNormalTexture[i].Position          = Points[i];
            }



            // We are using 32 bit integers for our indices, so make sure the 16 bit flag is removed.
            // 32 bits are the default, so this isn't technically needed, but it's good to show in a sample
            clothMeshDesc.Flags &= ~MeshFlag.Indices16Bit;
            //clothMeshDesc.Flags |= (MeshFlag)((int)clothMeshDesc.Flags | (int)ClothMeshFlag.Tearable);

            // Write the cooked data to memory
            using (var memoryStream = new MemoryStream())
            {
                Cooking.InitializeCooking();
                Cooking.CookClothMesh(clothMeshDesc, memoryStream);
                Cooking.CloseCooking();

                // Need to reset the position of the stream to the beginning
                memoryStream.Position = 0;

                ClothMesh = PhysxPhysicWorld.Core.CreateClothMesh(memoryStream);
            }

            modelRadius = Microsoft.Xna.Framework.BoundingSphere.CreateFromPoints(Points).Radius;
            LoadModel(factory, out BatchInformations, out TextureInformations);
        }
        protected override void  LoadModel(GraphicFactory factory, out BatchInformation[][] BatchInformations, out TextureInformation[][] TextureInformation)

        {
            vertexBufferS = factory.CreateDynamicVertexBuffer(VertexPositionTexture.VertexDeclaration, vertices.Count(), BufferUsage.None);
            vertexBufferS.SetData(vertices);
            int noVertices  = vertices.Count();
            int noTriangles = indices.Count() / 3;

            indexBufferS = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, indices.Count(), BufferUsage.None);
            indexBufferS.SetData(indices);

            BatchInformations = new BatchInformation[1][];
            BatchInformation[] b = new BatchInformation[1];
            b[0] = new BatchInformation(0, noVertices, noTriangles, 0, 0, VertexPositionTexture.VertexDeclaration, VertexPositionTexture.VertexDeclaration.VertexStride, BatchType.INDEXED);
            b[0].VertexBuffer    = vertexBufferS;
            b[0].IndexBuffer     = indexBufferS;
            BatchInformations[0] = b;

            TextureInformation       = new TextureInformation[1][];
            TextureInformation[0]    = new TextureInformation[1];
            TextureInformation[0][0] = new TextureInformation(false, factory);
            TextureInformation[0][0].SetTexture(diffuseName, TextureType.DIFFUSE);
        }
        /// <summary>
        /// Loads the model.
        /// </summary>
        /// <param name="factory">The factory.</param>
        /// <param name="BatchInformations">The batch informations.</param>
        /// <param name="TextureInformations">The texture informations.</param>
        protected override void LoadModel(GraphicFactory factory, out BatchInformation[][] BatchInformations, out TextureInformation[][] TextureInformations)
        {
            int vertCount   = bilboards.Count() * 4;
            int indexCount  = bilboards.Count() * 6;
            int noVertices  = vertCount;
            int noTriangles = indexCount / 3;

            VertexBuffer vertexBufferS = factory.CreateDynamicVertexBuffer(VertexPositionTexture.VertexDeclaration, vertCount, BufferUsage.WriteOnly);
            IndexBuffer  IndexBufferS  = factory.CreateDynamicIndexBuffer(IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly);

            BatchInformations = new BatchInformation[1][];
            BatchInformation[] b = new BatchInformation[1];
            b[0] = new BatchInformation(0, vertCount, noTriangles, 0, 0, VertexPositionTexture.VertexDeclaration, VertexPositionTexture.VertexDeclaration.VertexStride, BatchType.INDEXED);
            b[0].ModelLocalTransformation = Matrix.Identity;
            b[0].VertexBuffer             = vertexBufferS;
            b[0].IndexBuffer     = IndexBufferS;
            BatchInformations[0] = b;

            TextureInformations    = new TextureInformation[1][];
            TextureInformations[0] = new TextureInformation[1];

            TextureInformations[0][0] = new TextureInformation(isInternal, factory, diffuseTextureName, null, null, null);
            TextureInformations[0][0].LoadTexture();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleModel"/> class.
        /// </summary>
        /// <param name="factory">The graphic factory.</param>
        /// <param name="PhysxPhysicWorld">The physx physic world.</param>
        /// <param name="clothMeshDesc">The cloth mesh desc.</param>
        /// <param name="Points">The points.</param>
        /// <param name="TextCoords">The text coords.</param>
        /// <param name="Indices">The indices.</param>
        /// <param name="diffuseTextureName">Name of the diffuse texture.</param>
        public ClothModel(GraphicFactory factory, PhysxPhysicWorld PhysxPhysicWorld, ClothMeshDescription clothMeshDesc,  
            Vector3[] Points ,
            Vector2[] TextCoords ,
            int[] Indices ,
            String diffuseTextureName = null)
            : base(factory, "Cloth", false)
        {
            this._diffuseName = diffuseTextureName;            

            VerticesNum = Points.Length;
            IndicesNum = Indices.Length;
            
            clothMeshDesc.AllocateVertices<Vector3>(VerticesNum);
            clothMeshDesc.AllocateTriangles<int>(IndicesNum / 3);

            clothMeshDesc.VertexCount = VerticesNum;
            clothMeshDesc.TriangleCount = IndicesNum / 3;

            BatchInformation = new PloobsEngine.Modelo.BatchInformation(0, VerticesNum, IndicesNum / 3, 0, 0,
                VertexPositionNormalTexture.VertexDeclaration, VertexPositionNormalTexture.VertexDeclaration.VertexStride, PrimitiveType.TriangleList);
            BatchInformation.ModelLocalTransformation = XNA.Matrix.Identity;

            vertexPositionNormalTexture = new VertexPositionNormalTexture[VerticesNum];

            BatchInformation.VertexBuffer = factory.CreateDynamicVertexBuffer(VertexPositionNormalTexture.VertexDeclaration, VerticesNum + (int)(1.2 * VerticesNum), BufferUsage.WriteOnly);
            BatchInformation.IndexBuffer = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, IndicesNum + (int)(1.2 * IndicesNum), BufferUsage.WriteOnly);

            BatchInformation.IndexBuffer.SetData<int>(Indices);
            clothMeshDesc.VerticesStream.SetData(Points);
            clothMeshDesc.TriangleStream.SetData(Indices);


            XNA.Vector3[] pts = new XNA.Vector3[BatchInformation.NumVertices];
            for (int i = 0; i < BatchInformation.NumVertices; i++)
            {
                vertexPositionNormalTexture[i].TextureCoordinate = TextCoords[i].AsXNA();
                vertexPositionNormalTexture[i].Position = Points[i].AsXNA();
                pts[i] = vertexPositionNormalTexture[i].Position;
            }
                        
            modelRadius = Microsoft.Xna.Framework.BoundingSphere.CreateFromPoints(pts).Radius;
            pts = null;


            // We are using 32 bit integers for our indices, so make sure the 16 bit flag is removed.
            // 32 bits are the default, so this isn't technically needed, but it's good to show in a sample
            clothMeshDesc.Flags &= ~MeshFlag.Indices16Bit;
            //clothMeshDesc.Flags |= (MeshFlag)((int)clothMeshDesc.Flags | (int)ClothMeshFlag.Tearable);

            // Write the cooked data to memory
            using (var memoryStream = new MemoryStream())
            {
                Cooking.InitializeCooking();
                Cooking.CookClothMesh(clothMeshDesc, memoryStream);
                Cooking.CloseCooking();

                // Need to reset the position of the stream to the beginning
                memoryStream.Position = 0;

                ClothMesh = PhysxPhysicWorld.Core.CreateClothMesh(memoryStream);
            }

            
            LoadModel(factory, out BatchInformations, out TextureInformations);
        }
        /// <summary>
        /// Initialises a complete QuadTerrain.
        ///This is the Constructor method. As you might have guessed, it constructs a quad terrain.
        /// Quasar.
        /// </summary>
        /// <param name="factory">The factory.</param>
        /// <param name="heightMap">The Texture2D to use as a heightmap. Must have square dimensions of (2^n)+1, where n is an integer.</param>
        /// <param name="squareSize">The edge size of each individual LOD square. Lower values increase CPU Load, decrease GPU Load, and increase Loading times. Must be (2^n)+1, and larger than 5.</param>
        /// <param name="vertexBufferSize">The size of Vertex buffer to use. Lower Values increase the number of draw calls by splitting the terrain into several Vertex Buffers. Must be (2^n)+1, and larger than squareSize.</param>
        /// <param name="scale">The XZ scale to multiply the terrain by.</param>
        /// <param name="height">The Y scale to multiply the terrain by.</param>
        public QuadTerrain(GraphicFactory factory ,Texture2D heightMap, int squareSize, int vertexBufferSize, float scale, float height)
        {
            this.factory = factory;
            //I'm not entirely sure what this does, but it is used in updateTerrain.
            //I think it is used to prevent the Vertex Buffers being filled during the initialisation UpdateTerrain call.
            first = true;

            LODHeightImpact = 1.0f;                        
             
            

            //Set terrain width and height from heightmap.
            terrainHeight = heightMap.Height;
            terrainWidth = heightMap.Width;

            //Set some obvious public variables
            HeightMap = heightMap;
            SquareSize = squareSize;
            Scale = scale;
            HeightScale = height;
            VBsize = vertexBufferSize;

            //Copy the heightmap from a Texture to an array of colours...
            Color[] heightMapColors = new Color[terrainWidth * terrainHeight];
            heightMap.GetData(heightMapColors);

            //Initialise the HeightStore and 
            heightStore = new float[heightMap.Width, heightMap.Height];
            normStore = new Vector3[heightMap.Width, heightMap.Height];

            //this is the Normal texture for the entire terrain. It is used within the shader to prevent normal popup.
            normalTexture = factory.CreateTexture2D(heightMap.Width, heightMap.Height, true, SurfaceFormat.Color);
            Color[] normalData = new Color[heightMap.Width * heightMap.Height];

            #region depricated
            /*
            int NodeDepth= 0;
            int NodeLevel = (int)Math.Pow(2, (NodeDepth));
            int NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1;
            int stepSize = (NodeScale - 1) / (squareSize - 1);
            */

            ////////////////////////////////////////////////////
            // For:
            // SquareSize = 9
            // Height = 257
            // NodeDepth,   NodeLevel,  NodeScale,  stepSize
            // 0,           1,          257,        64
            // 1,           2,          129,        32
            // 2,           4,          65,         16
            // 3,           8,          33,         8
            // 4,           16,         19,         4
            // 5,           32,         9,          2
            // 6,           64,         5,          1
            ////////////////////////////////////////////////////

            //Get node depth:
            //int NodeScale = stepSize*(squareSize-1)+1;
            //int NodeLevel = (NodeScale - 1) * (heightMap.Height - 1);
            //int maxNodeDepth = (int)Math.Log(NodeLevel, 2);
            //int maxNodeDepth;
            #endregion

            //Determine Maximum Node Depth from Square Size and height of heightmap
            int NodeScale = 1 * (squareSize - 1) + 1;
            int NodeLevel = (heightMap.Height - 1) / (NodeScale - 1);
            maxNodeDepth = (int)Math.Log(NodeLevel, 2);

            //Work out number of vertex arrays needed:
            //Math.Pow(HeightMap.HEIGHT / 512, 2))+1;
            numberOfVBs = (int)Math.Pow((terrainHeight - 1) / (VBsize - 1), 2);
            sqrtNumberOfVBs = (int)Math.Sqrt(numberOfVBs);

            //Initialise the Array of Vertex Arrays, accompanying Array of Vertex Buffers and the Array of Integer Index Arrays.
            allVertices = new VertexPosition[numberOfVBs + 1][];
            allVBs = new VertexBuffer[numberOfVBs + 1];
            allIndices = new int[numberOfVBs + 1][];

            //And as if that wasn't confusing enough...
            //Now I initialise each Array in the Array of Vertex Arrays, each corresponding Buffer in the Array of Vertex Buffers,
            //and each Integer Index Array in the Array of Integer Index Arrays.
            for (int i = 0; i < numberOfVBs + 1; i++)
            {
                allVertices[i] = new VertexPosition[(VBsize + 1) * (VBsize + 1)];
                allVBs[i] = factory.CreateVertexBuffer(VertexPosition.VertexDeclaration, (VBsize + 1) * (VBsize + 1), BufferUsage.WriteOnly);
                allIndices[i] = new int[VBsize * VBsize * 6];
            }
            //Array.

            //This list is used to sort the Quadnodes to be drawn by distance to save on Overdraw.
            qnl = new List<QuadNode>();

            //Create a 2D array of floats from the heightmap colour array.
            for (int y = 0; y < terrainHeight; y++)
            {
                for (int x = 0; x < terrainWidth; x++)
                {
                    //heightstore Array
                    heightStore[x, y] = heightMapColors[x + y * terrainWidth].R;
                }
            }

            //Define the 'renderedIndices' array, which keeps track of the number of indices from each vertex buffer each frame.
            renderedindices = new int[numberOfVBs + 1];


            /////////////////////////////////////////////////////
            //Generate Vertex Positions and normals
            int PlusXVBIndex;
            int PlusYVBIndex;
            int PlusXYVBIndex;
            int PlusVBIndex;
            for (int y = 0; y < terrainHeight; y++)
            {
                for (int x = 0; x < terrainWidth; x++)
                {

                    PlusXYVBIndex = (int)(Math.Floor(((float)(x + 1) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y + 1) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs));
                    PlusXVBIndex = (int)(Math.Floor(((float)(x + 1) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs));
                    PlusYVBIndex = (int)(Math.Floor(((float)(x) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y + 1) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs));
                    PlusVBIndex = (int)(Math.Floor(((float)(x) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs));

                    Vector3 normX = Vector3.Zero;
                    Vector3 normY = Vector3.Zero;
                    Vector3 normalVector = new Vector3();

                    if (x > 0 && y > 0 && x < terrainWidth - 1 && y < terrainHeight - 1)
                    {
                        normX = new Vector3((heightStore[x - 1, y] - heightStore[x + 1, y]) / 2 * height, 0, scale);
                        normY = new Vector3(0, (heightStore[x, y - 1] - heightStore[x, y + 1]) / 2 * height, scale);
                        normalVector = normX + normY;
                        normalVector.Normalize();

                        Vector3 texVector = new Vector3();
                        texVector.X = (normalVector.X + 1) / 2f;
                        texVector.Y = (normalVector.Y + 1) / 2f;
                        texVector.Z = (normalVector.Z + 1) / 2f;
                        normalData[x + y * terrainHeight] = new Color(texVector);

                        //MessageBox.Show(normalVector.ToString() + " "+new Color(normalVector));
                    }
                    else
                    {
                        normX = new Vector3(0, 0, scale);
                        normY = new Vector3(0, 0, scale);
                        normalVector = normX + normY;
                        normalVector.Normalize();


                        Vector3 texVector = new Vector3();
                        texVector.X = (normalVector.X + 1) / 2f;
                        texVector.Y = (normalVector.Y + 1) / 2f;
                        texVector.Z = (normalVector.Z + 1) / 2f;
                        normalData[x + y * terrainHeight] = new Color(texVector);
                    }
                    normStore[x, y] = normalVector;

                    /////////////////////////////////////////////
                    //Fill Vertex Arrays
                    //Foreach vertex array...
                    for (int i = 0; i < numberOfVBs; i++)
                    {
                        //Vertex Buffers
                        // 0, 1, 2, 3... What about root 0?
                        // 4, 5, 6, 7
                        // 8, 9,10,11
                        //12,13,14,15
                        //Change to...
                        // 1, 2, 3, 4... root=0
                        // 5, 6, 7, 8
                        // 9,10,11,12
                        //13,14,15,16

                        //This works to sort the VB's. 
                        //It works to align the x,y and VBi values: only if an x/y coord is in an i VB. Uses 1st VB chart. Just use i+1
                        ///////////////////////////////////////////////////////////
                        //^^ If you understood the above comment, you're doing better than me. ^^
                        ///////////////////////////////////////////////////////////

                        //This is the 'multiple vertex buffers' algorithm, which puts vertices into their own VBuffers. Anything involving
                        //it won't be very well documented, because I can only vaguely remember writing it in the first place.

                        //I'm not entirely sure what that means, but I suspect I was either drunk or asleep at the time. Possibly both.
                        if (PlusXYVBIndex == i)
                        {
                            //allVertices[i+1][(x % VBsize) + (y % VBsize) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, -y * scale);
                            if (x < terrainHeight - 1)
                            {
                                //MessageBox.Show(x + " " + y + " " + x % (VBsize - 1) + " " + y % (VBsize - 1) + " " + i);

                                allVertices[i + 1][x % (VBsize - 1) + y % (VBsize - 1) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                //allVertices[i + 1][x % (VBsize - 1) + y % (VBsize - 1) * VBsize].Normal = normalVector;
                                //Add this vertex to VB i+1, at location (x % (VBsize-1) + y % (VBsize-1) * VBsize) 
                            }
                        }
                        else
                        {
                            //Bottom or left
                            if (PlusVBIndex == i)
                            {
                                if (PlusYVBIndex == i)
                                {
                                    //MessageBox.Show(x + "BotLeft&Y " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + y % (VBsize - 1) + " " + i);  
                                    allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                    //allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize].Normal = normalVector;

                                    //Add this vertex to VB i+1, at location (x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize)
                                }
                                else
                                {
                                    if (PlusXVBIndex == i)
                                    {
                                        //MessageBox.Show(x + "BotLeft&X " + y + " " + x % (VBsize - 1) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i);
                                        allVertices[i + 1][x % (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                        //allVertices[i + 1][x % (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Normal = normalVector;

                                        //Add this vertex to VB i+1, at location (x % (VBsize - 1)) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize)

                                    }
                                    else
                                    {
                                        //MessageBox.Show(x + "BotLeft " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i);
                                        allVertices[i + 1][x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                        //allVertices[i + 1][x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Normal = normalVector;
                                        //Add this vertex to VB i+1, at location (x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize)
                                    }
                                }
                            }
                            else
                            {
                                //Corner Left
                                if (PlusYVBIndex == i)
                                {
                                    if (y < terrainHeight - 1)
                                    {
                                        //MessageBox.Show(x + "Left " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + y % (VBsize - 1) + " " + i);
                                        allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1)) * VBsize)].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                        //allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1)) * VBsize)].Normal = normalVector;
                                        //Add this vertex to VB i+1, at location ((x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize)
                                    }
                                }
                                //Corner Bottom
                                if (PlusXVBIndex == i)
                                {
                                    if (x < terrainHeight - 1)
                                    {
                                        //MessageBox.Show(x + "Bot " + y + " " + x % (VBsize - 1) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i);
                                        allVertices[i + 1][(x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize)].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                        //allVertices[i + 1][(x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize)].Normal = normalVector;
                                        //Add this vertex to VB i+1, at location ((x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize)
                                    }
                                }
                            }
                        }


                        if (i == 0)
                        {
                            int stepSize = (terrainWidth - 1) / (vertexBufferSize - 1);
                            int numberOfSteps = (terrainWidth - 1) / stepSize;
                            if (x % stepSize == 0 && y % stepSize == 0)
                            {
                                allVertices[0][(x / stepSize) + (y / stepSize) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale);
                                //allVertices[0][(x / stepSize) + (y / stepSize) * VBsize].Normal = normalVector;
                                //Add this vertex to VB 0, at location ((x/stepSize) + (y/stepSize) * VBsize)
                            }
                        }
                    }
                }
            }
            //Generate the normal texture from the normal data generated a second ago.
            normalTexture.SetData<Color>(normalData);

            factory.MipMapTexture(ref normalTexture);            
                       

            ////////////////////////////////////////////////////////////
            //Add to vertex buffer
            for (int j = 0; j < numberOfVBs + 1; j++)
            {
                allVBs[j].SetData<VertexPosition>(allVertices[j]);
            }
            ////////////////////////////////////////////////////////////


            #region depricated
            // int[] nodeStatsArray = new int[6,6];
            //for (i=HeightMap.Height-1;i>

            //   rootNode = new QuadNode(HeightMap, SquareSize, 4, 0, 0);


            //NodeDepth     Nodes   Total Nodes
            //0             1       1
            //1             4       5
            //2             16      21
            //3             64      85
            //4             256     341
            //5             1024    1365

            //allQuadNodes = new List<QuadNode>();


            //int NodeDepth = 0;
            //NodeLevel = (int)Math.Pow(2, (NodeDepth));
            //NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1;
            //int stepSize = (NodeScale - 1) / (squareSize - 1);
            //QuadNode qNode;
            //QuadNode[] parentNode = new QuadNode[1];

            //int xPosition = 0;
            //int yPosition = 0;
            //qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition);
            //NodeDepth++;

            //while (xPosition < terrainWidth)
            //{
            //    while (yPosition < terrainHeight)
            //    {
            //        while (NodeDepth < maxNodeDepth - 5)
            //        {
            //            NodeLevel = (int)Math.Pow(2, (NodeDepth));
            //            NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1;
            //            qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition);
            //            allQuadNodes.Add(qNode);
            //            qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition + NodeScale - 1, yPosition);
            //            allQuadNodes.Add(qNode);
            //            qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition + NodeScale - 1);
            //            allQuadNodes.Add(qNode);
            //            qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition + NodeScale - 1, yPosition + NodeScale - 1);
            //            allQuadNodes.Add(qNode);
            //            parentNode[0] = qNode;
            //            NodeDepth++;
            //        }
            //        NodeDepth--;


            //        NodeLevel = (int)Math.Pow(2, (NodeDepth-1));
            //        NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1;




            //        //NodeDepth--;
            //        yPosition += NodeScale - 1;
            //    }
            //    xPosition += NodeScale - 1;
            //    yPosition = 0;
            //}

            //NodeDepth++;


            //int numQuadNodes = allQuadNodes.Count;
            //int[] indexBufferArray = new int[numQuadNodes * ((squareSize - 1) * (squareSize - 1) * 6)];

            #endregion

            //Define Quadnode List
            allQuadNodes = new List<QuadNode>();

            //Create RootNode
            RootNode = new QuadNode(HeightMap, normStore, SquareSize, VBsize, Scale, 0, 0, 0, null, allVertices);
            allQuadNodes.Add(RootNode);


            ////////////////////////////////////////////////
            //Creates all quadnodes in the entire quadtree
            //
            //This is a recursive function. It breaks the rootnode into 4 new quadnodes, then applies itself to each of 
            //these children nodes, in turn breaking them. See it's definition for a more complete explanation.
            RecursiveCreateQuad(RootNode);
            ////////////////////////////////////////////////

            //Set Adjacent Nodes for each Quadnode, for stitching purposes.
            for (int i = 0; i < allQuadNodes.Count; i++)
            {
                if (allQuadNodes[i].NodeDepth > 0)
                {
                    foreach (QuadNode qNode in allQuadNodes)
                    {
                        if (qNode.XPosition == allQuadNodes[i].XPosition + allQuadNodes[i].NodeScale - 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.YPosition == allQuadNodes[i].YPosition)
                        {
                            allQuadNodes[i].adjacentNorthQuad = qNode;
                        }
                        if (qNode.YPosition == allQuadNodes[i].YPosition + allQuadNodes[i].NodeScale - 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.XPosition == allQuadNodes[i].XPosition)
                        {
                            allQuadNodes[i].adjacentEastQuad = qNode;
                        }
                        if (qNode.XPosition == allQuadNodes[i].XPosition - allQuadNodes[i].NodeScale + 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.YPosition == allQuadNodes[i].YPosition)
                        {
                            allQuadNodes[i].adjacentSouthQuad = qNode;
                        }
                        if (qNode.YPosition == allQuadNodes[i].YPosition - allQuadNodes[i].NodeScale + 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.XPosition == allQuadNodes[i].XPosition)
                        {
                            allQuadNodes[i].adjacentWestQuad = qNode;
                        }
                    }
                }
            }

            ///////////////////////////////////////////////
            //Run an update on the terrain for it's initial state. See the update method.
            //I'm not entirely sure why this is necessary, but I'm sure there's a good reason.
            Matrix viewMatrix = Matrix.CreateLookAt(Vector3.Zero, Vector3.Forward, Vector3.Up);
            Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 10f, 1, 100);
            BoundingFrustum startFrustrum = new BoundingFrustum(viewMatrix * projectionMatrix);
#if DEBUG
            debugTimer = new Stopwatch();
#endif

            UpdateTerrain(new Vector3(), startFrustrum, 3.5f);
            allIBs = new DynamicIndexBuffer[allIndices.Length];
            for (int l = 0; l < allIndices.Length; l++)
            {
                allIBs[l] = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, (allVertices[l].Length), BufferUsage.WriteOnly);
            }
        }
        /// <summary>
        /// Loads the model.
        /// </summary>
        /// <param name="factory">The factory.</param>
        /// <param name="BatchInformations">The batch informations.</param>
        /// <param name="TextureInformations">The texture informations.</param>
        protected override void LoadModel(GraphicFactory factory, out BatchInformation[][] BatchInformations, out TextureInformation[][] TextureInformations)
        {
            int vertCount = bilboards.Count() * 4;
            int indexCount = bilboards.Count() * 6;
            int noVertices = vertCount;
            int noTriangles = indexCount / 3;

            VertexBuffer vertexBufferS = factory.CreateDynamicVertexBuffer(VertexPositionTexture.VertexDeclaration, vertCount, BufferUsage.WriteOnly);
            IndexBuffer IndexBufferS = factory.CreateDynamicIndexBuffer(IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly);

            BatchInformations = new BatchInformation[1][];
            BatchInformation[] b = new BatchInformation[1];
            b[0] = new BatchInformation(0, vertCount, noTriangles, 0, 0, VertexPositionTexture.VertexDeclaration, VertexPositionTexture.VertexDeclaration.VertexStride, BatchType.INDEXED);
            b[0].ModelLocalTransformation = Matrix.Identity;
            b[0].VertexBuffer = vertexBufferS;
            b[0].IndexBuffer = IndexBufferS;
            BatchInformations[0] = b;

            TextureInformations = new TextureInformation[1][];
            TextureInformations[0] = new TextureInformation[1];
            
            TextureInformations[0][0] = new TextureInformation(isInternal, factory, diffuseTextureName, null, null, null);
            TextureInformations[0][0].LoadTexture();
        }
Example #7
0
        protected override void LoadModel(GraphicFactory factory, out BatchInformation[][] BatchInformations, out TextureInformation[][] TextureInformation)
        {
            int vertCount  = vertices.Count();
            int indexCount = 0;

            if (indices != null)
            {
                indexCount = indices.Count();
            }
            int noVertices  = vertCount;
            int noTriangles = 0;

            if (indices != null)
            {
                noTriangles = indexCount / 3;
            }
            else
            {
                noTriangles = vertCount / 3;
            }

            VertexBuffer vertexBufferS;
            IndexBuffer  IndexBufferS = null;

            if (isDynamic)
            {
                vertexBufferS = factory.CreateDynamicVertexBuffer(vertices[0].VertexDeclaration, (int)(vertCount * dynamicMultiplier), BufferUsage);
                if (indices != null)
                {
                    IndexBufferS = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, (int)(indexCount * dynamicMultiplier), BufferUsage);
                }
            }
            else
            {
                vertexBufferS = factory.CreateVertexBuffer(vertices[0].VertexDeclaration, vertCount, BufferUsage);
                if (indices != null)
                {
                    IndexBufferS = factory.CreateIndexBuffer(IndexElementSize.ThirtyTwoBits, indexCount, BufferUsage);
                }
            }

            vertexBufferS.SetData <T>(vertices);
            if (indices != null)
            {
                IndexBufferS.SetData <int>(indices);
            }

            BatchInformations = new BatchInformation[1][];
            BatchInformation[] b = new BatchInformation[1];
            b[0] = new BatchInformation(0, vertCount, noTriangles, 0, 0, vertices[0].VertexDeclaration, vertices[0].VertexDeclaration.VertexStride,
                                        indices != null ? BatchType.INDEXED : BatchType.NORMAL);
            b[0].ModelLocalTransformation = transformation;
            b[0].VertexBuffer             = vertexBufferS;
            if (indices != null)
            {
                b[0].IndexBuffer = IndexBufferS;
            }
            BatchInformations[0] = b;

            TextureInformations    = new TextureInformation[1][];
            TextureInformations[0] = new TextureInformation[1];

            TextureInformations[0][0] = new TextureInformation(isInternal, factory, diffuseTextureName, null, null, null);
            TextureInformations[0][0].LoadTexture();
            TextureInformation = TextureInformations;

            if (!isDynamic)
            {
                vertices = null;
                indices  = null;
            }
        }