Exemple #1
0
        private void ReleaseNode(QuadTreeNodeType theNode)
        {
            // Watch to see if this actually closes the Node structs.
            if (theNode.VertexBuffer == null)
            {
                return;
            }

            // Release the vertex array for this node.
            theNode.vertexArray = null;

            // Recursively go down the tree and release the bottom nodes first
            for (int i = 0; i < 4; i++)
            {
                if (theNode.Nodes[i].VertexBuffer != null)
                {
                    ReleaseNode(theNode.Nodes[i]);
                }
            }

            // Release the vertex buffer for this node
            theNode.VertexBuffer?.Dispose();
            theNode.VertexBuffer = null;
            // Release the index buffer for this node
            theNode.IndexBuffer?.Dispose();
            theNode.IndexBuffer = null;
        }
Exemple #2
0
        private void RenderNode(DeviceContext deviceContext, QuadTreeNodeType node, Frustrum frustrum, TerrainShader terrainShader)
        {
            // Check to see if the node can be viewed, height doesn't matter in a quad tree.
            // If it can't be seen then none of its children can either, so don't continue down the tree, this is where the speed is gained.
            if (!frustrum.CheckCube(new SharpDX.Vector3(node.positionX, 0.0f, node.positionZ), (node.width / 2.0f)))              //   63.7506409
            {
                return;
            }

            // If it can be seen then check all four child nodes to see if they can also be seen.
            int count = 0;

            for (int i = 0; i < 4; i++)
            {                                   // parentNode.width > 0.0f && parentNode.Nodes[i].VertexBuffer != null
                if (node.Nodes[i].width > 0.0f) //node.Nodes != null/ parentNode.Nodes[i].width > 0.0f
                {
                    count++;
                    RenderNode(deviceContext, node.Nodes[i], frustrum, terrainShader);
                }
            }

            // If there were any children nodes then there is no need to continue as parent nodes won't contain any triangles to render.
            if (count != 0)
            {
                return;
            }

            int vertexCount = node.TriangleCount * 3;

            // Otherwise if this node can be seen and has triangles in it then render these triangles.
            // Set vertex buffer stride and offset.
            // Set the vertex buffer to active in the input assembler so it can be rendered.
            deviceContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(node.VertexBuffer, SharpDX.Utilities.SizeOf <PositionTextureNormalVertex>(), 0));

            // Set the index buffer to active in the input assembler so it can be rendered.
            deviceContext.InputAssembler.SetIndexBuffer(node.IndexBuffer, Format.R32_UInt, 0);

            // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
            deviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            // Determine the number of indices in this node.
            int indexCount = node.TriangleCount * 3;

            // Call the terrain shader to render the polygons in this node.
            terrainShader.RenderShader(deviceContext, indexCount);

            // Increase the count of the number of polygons that have been rendered during this frame.
            DrawCount += node.TriangleCount;
        }
Exemple #3
0
        // Methods
        public bool Initialise(Terrain terrain, Device device)
        {
            int vertexCount = terrain.VertexCount;

            TriangleCount = vertexCount / 3;

            VertexList = new PositionTextureNormalVertex[vertexCount];

            VertexList = terrain.Vertices;

            CalculateMeshDimensions(vertexCount, out float centerX, out float centerZ, out float width);

            ParentNode = new QuadTreeNodeType();

            CreateTreeNode2(device, ParentNode, centerX, centerZ, width, out QuadTreeNodeType createdNode);

            ParentNode = createdNode;

            VertexList = null;

            return(true);
        }
Exemple #4
0
        private void CreateTreeNode2(SharpDX.Direct3D11.Device device, QuadTreeNodeType node, float positionX, float positionZ, float width, out QuadTreeNodeType createdNode)
        {
            // Store the node position and size.
            node.positionX = positionX;
            node.positionZ = positionZ;
            node.width     = width;

            // Initialize the triangle count to zero for the node.
            node.TriangleCount = 0;

            // Initialize the vertex and index buffer to null.
            node.VertexBuffer = null;
            node.IndexBuffer  = null;

            // Initialize the Nodes vertex array to null.
            node.vertexArray = null;

            // Count the number of triangles that are inside this node.
            int numTriangles = CountTriangles(positionX, positionZ, width);

            // Case 1: If there are no triangles in this node then return as it is empty and requires no processing.
            if (numTriangles == 0)
            {
                createdNode = node;
                return;
            }

            // Initialize the children nodes of this node to null.
            node.Nodes = new QuadTreeNodeType[4];

            // Case 2: If there are too many triangles in this node then split it into four equal sized smaller tree nodes.
            if (numTriangles > MAX_TRIANGLES)
            {
                for (int i = 0; i < 4; i++)
                {
                    // Calculate the position offsets for the new child node.
                    float offsetX = (((i % 2) < 1) ? -1.0f : 1.0f) * (width / 4.0f);
                    float offsetZ = (((i % 4) < 2) ? -1.0f : 1.0f) * (width / 4.0f);

                    // See if there are any triangles in the new node.
                    int count = CountTriangles((positionX + offsetX), (positionZ + offsetZ), (width / 2.0));

                    if (count > 0)
                    {
                        // If there are triangles inside where this new node would be then create the child node.
                        node.Nodes[i] = new QuadTreeNodeType();
                        QuadTreeNodeType aNewNode;

                        // Extend the tree starting from this new child node now.
                        CreateTreeNode2(device, node.Nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f), out aNewNode);

                        node.Nodes[i] = aNewNode;
                        createdNode   = aNewNode;
                    }
                }

                createdNode = node;
                return;
            }

            // Case 3: If this node is not empty and the triangle count for it is less than the max then this node is at the bottom of the tree so create the list of triangles to store in it.
            node.TriangleCount = numTriangles;

            // Calculate the number of vertices.
            int vertexCount = numTriangles * 3;

            // Create the vertex array.
            PositionTextureNormalVertex[] vertices = new PositionTextureNormalVertex[vertexCount];
            // Create the index array
            int[] indices = new int[vertexCount];

            // Create the vertex array.
            node.vertexArray = new XYZType[vertexCount];

            // Initialize the index for this new vertex and index array.
            int index = 0;

            // Go through all the triangles in the vertex list.
            for (int i = 0; i < TriangleCount; i++)
            {
                // If the triangle is inside this node then add it to the vertex array.
                if (IsTriangleContained(i, positionX, positionZ, width))
                {
                    // Calculate the index into the terrain vertex list.
                    int vertexIndex = i * 3;

                    // Get the three vertices of this triangle from the vertex list.
                    vertices[index] = VertexList[vertexIndex];
                    indices[index]  = index;
                    // Also store the vertex position information in the node vertex array.
                    node.vertexArray[index].x = VertexList[vertexIndex].position.X;
                    node.vertexArray[index].y = VertexList[vertexIndex].position.Y;
                    node.vertexArray[index].z = VertexList[vertexIndex].position.Z;

                    // Increment the indexes.
                    index++;
                    vertexIndex++;

                    vertices[index]           = VertexList[vertexIndex];
                    indices[index]            = index;
                    node.vertexArray[index].x = VertexList[vertexIndex].position.X;
                    node.vertexArray[index].y = VertexList[vertexIndex].position.Y;
                    node.vertexArray[index].z = VertexList[vertexIndex].position.Z;

                    // Increment the indexes.
                    index++;
                    vertexIndex++;
                    vertices[index]           = VertexList[vertexIndex];
                    indices[index]            = index;
                    node.vertexArray[index].x = VertexList[vertexIndex].position.X;
                    node.vertexArray[index].y = VertexList[vertexIndex].position.Y;
                    node.vertexArray[index].z = VertexList[vertexIndex].position.Z;

                    index++;
                }
            }

            // Set up the description of the vertex buffer. no Need its static
            // Create the vertex buffer.
            node.VertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, BindFlags.VertexBuffer, vertices);

            // Create the index buffer.
            node.IndexBuffer = SharpDX.Direct3D11.Buffer.Create(device, BindFlags.IndexBuffer, indices);

            // Release the vertex and index arrays now that the data is stored in the buffers in the node.
            vertices = null;
            indices  = null;

            createdNode = node;

            return;
        }
Exemple #5
0
        private bool FindNode(QuadTreeNodeType node, float x, float z, out float height)
        {
            height = 0.0f;

            Vector3 vertex1, vertex2, vertex3;

            // Calculate the dimensions of this node.
            float xMin = node.positionX - (node.width / 2.0f);
            float xMax = node.positionX + (node.width / 2.0f);
            float zMin = node.positionZ - (node.width / 2.0f);
            float zMax = node.positionZ + (node.width / 2.0f);

            // See if the x and z coordinate are in this node, if not then stop traversing this part of the tree.
            if ((x < xMin) || (x > xMax) || (z < zMin) || (z > zMax))
            {
                return(false);
            }

            // If the coordinates are in this node then check first to see if children nodes exist.
            int count = 0;

            for (int i = 0; i < 4; i++)
            {
                if (node.Nodes[i].width != 0)
                {
                    count++;
                    if (FindNode(node.Nodes[i], x, z, out height))
                    {
                        return(true);
                    }
                }
            }

            // If there were no children then the polygon must be in this node.  Check all the polygons in this node to find
            // the height of which one the polygon we are looking for.
            int index = 0;

            for (int i = 0; i < node.TriangleCount; i++)
            {
                index     = i * 3;
                vertex1.X = node.vertexArray[index].x;
                vertex1.Y = node.vertexArray[index].y;
                vertex1.Z = node.vertexArray[index].z;

                index++;
                vertex2.X = node.vertexArray[index].x;
                vertex2.Y = node.vertexArray[index].y;
                vertex2.Z = node.vertexArray[index].z;

                index++;
                vertex3.X = node.vertexArray[index].x;
                vertex3.Y = node.vertexArray[index].y;
                vertex3.Z = node.vertexArray[index].z;

                // Check to see if this is the polygon we are looking for.
                // If this was the triangle then quit the function and the height will be returned to the calling function.
                if (CheckHeightOfTriangle(x, z, out height, vertex1, vertex2, vertex3))
                {
                    return(true);
                }
            }

            return(false);
        }