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); } }
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; } }