Exemple #1
0
        /// <summary>
        /// Writes the collision file out to a local file.
        /// </summary>
        /// <param name="clFile">The list of bytes to represent the collision file.</param>
        /// <param name="quadtreeData">Contains the quadtree information and details.</param>
        public static List <byte> GenerateFile(List <byte> clFile, QuadtreeGenerator quadtreeData)
        {
            // Allocate a buffer for the collision file.
            // The buffer size is 2MiB
            clFile = new List <byte>(2097152);

            // Calculate the file offsets.
            ClFileOffsets fileOffsets = CalculateClOffsets(quadtreeData);

            // Retrieve the header.
            CalculateCollisionHeader(fileOffsets, quadtreeData);

            // Write the file header.
            WriteCollisionFileHeader(clFile, quadtreeData);

            // Write the triangle reference list.
            WriteTriangleList(clFile, quadtreeData);

            // Write the quadnodes
            WriteQuadnodeList(clFile, quadtreeData);

            // Write all of the triangle entries.
            WriteTriangles(clFile);

            // Write the vertices.
            for (int x = 0; x < GeometryData.Vertices.Count; x++)
            {
                clFile.AddRange(BitConverter.GetBytes((float)GeometryData.Vertices[x].X).Reverse());
                clFile.AddRange(BitConverter.GetBytes((float)GeometryData.Vertices[x].Y).Reverse());
                clFile.AddRange(BitConverter.GetBytes((float)GeometryData.Vertices[x].Z).Reverse());
            }

            // Return collision file.
            return(clFile);
        }
        /// <summary>
        /// Alternative version, finds all triangles adjacent to the currently registered set of triangles.
        /// </summary>
        /// <param name="quadtreeGenerator">The quadtree containing the nodes which hold triangle references.</param>
        public static void CalculateTriangleAdjacentsV2(QuadtreeGenerator quadtreeGenerator)
        {
            // Assign null adjacent indices to each triangle
            foreach (var triangle in GeometryData.Triangles)
            {
                triangle.AdjacentTriangles = new int[3] {
                    -1, -1, -1
                };
            }

            // If adjacents are disabled, return.
            if (!CollisionGenerator.Properties.EnableAdjacents)
            {
                return;
            }

            // Retrieve all nodes with triangles.
            Quadnode[] quadnodesWithTriangles = QuadtreeGenerator.QuadNodes.Where(x => x.TrianglesInNode.Count > 0).ToArray();

            // Iterate over all bottom level nodes.
            foreach (var quadNode in quadnodesWithTriangles)
            {
                // Find all adjacent triangles within each individual node.
                QuadnodeFindTriangleAdjacents(quadNode);
            }
        }
Exemple #3
0
 /// <summary>
 /// Complete the file header for the output colliison struct based off of the already known data.
 /// </summary>
 /// <param name="quadtreeData">Contains the quadtree information and details.</param>
 private static void CalculateCollisionHeader(ClFileOffsets fileOffsets, QuadtreeGenerator quadtreeData)
 {
     // Fill in the necessary header data from all of the subclasses.
     HeroesHeader.BasePower         = CollisionGenerator.Properties.BasePower;
     HeroesHeader.NumberOfBytes     = (uint)fileOffsets.TotalFileSize;
     HeroesHeader.NumberOfNodes     = (ushort)QuadtreeGenerator.QuadNodes.Length;
     HeroesHeader.NumberOfTriangles = (ushort)GeometryData.Triangles.Count;
     HeroesHeader.NumberOfVertices  = (ushort)GeometryData.Vertices.Count;
     HeroesHeader.QuadtreeOffset    = (uint)fileOffsets.NodeSectionOffset;
     HeroesHeader.TriangleOffset    = (uint)fileOffsets.TriangleSectionOffset;
     HeroesHeader.VertexOffset      = (uint)fileOffsets.VertexSectionOffset;
 }
Exemple #4
0
        /// <summary>
        /// Writes the header of a collision CL file.
        /// </summary>
        /// <param name="ClFile">The list of bytes to represent the collision file.</param>
        /// <param name="quadtreeData">Contains the quadtree information and details.</param>
        private static void WriteCollisionFileHeader(List <byte> clFile, QuadtreeGenerator quadtreeData)
        {
            // Append the offsets of each of the individual file sections.
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.NumberOfBytes).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.QuadtreeOffset).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.TriangleOffset).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.VertexOffset).Reverse());

            // Append the quadtree center and the size to the header.
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.QuadtreeCenter.X).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.QuadtreeCenter.Y).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.QuadtreeCenter.Z).Reverse());
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.QuadtreeSize).Reverse());

            // Append the quadtree base power to the header as well as the length of each file section.
            clFile.AddRange(BitConverter.GetBytes(HeroesHeader.BasePower).Reverse());
            clFile.AddRange(BitConverter.GetBytes((ushort)GeometryData.Triangles.Count).Reverse());
            clFile.AddRange(BitConverter.GetBytes((ushort)GeometryData.Vertices.Count).Reverse());
            clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes.Length).Reverse());
        }
Exemple #5
0
        /// <summary>
        /// Calculates the offsets for the CL File.
        /// </summary>
        /// <param name="quadtreeData">Contains the quadtree information and details.</param>
        private static ClFileOffsets CalculateClOffsets(QuadtreeGenerator quadtreeData)
        {
            // File offsets.
            ClFileOffsets fileOffsets = new ClFileOffsets();

            // Current pointer in the nonexisting (yet) output file.
            int currentCursorPointer = HeroesHeader.HeaderLength;

            // Retrieve all nodes that contain triangles. (Nodes with triangles have no children)
            Quadnode[] quadnodesAtDepthLevel = QuadtreeGenerator.QuadNodes.Where(x => x.TrianglesInNode.Count > 0).ToArray();

            // Calculate offset for node section.
            foreach (var quadNode in quadnodesAtDepthLevel)
            {
                currentCursorPointer += (quadNode.TrianglesInNode.Count * 2);
            }

            // Set node section offset.
            fileOffsets.NodeSectionOffset = currentCursorPointer;

            // Calculate offset for triangle section.
            currentCursorPointer = currentCursorPointer + (0x20 * QuadtreeGenerator.QuadNodes.Length);

            // Set triangle section offset.
            fileOffsets.TriangleSectionOffset = currentCursorPointer;

            // Calculate Vertex Section Offset.
            currentCursorPointer = currentCursorPointer + (0x20 * GeometryData.Triangles.Count);

            // Set vertex section offset.
            fileOffsets.VertexSectionOffset = currentCursorPointer;

            // Calculate end of file
            currentCursorPointer = currentCursorPointer + (0x0C * GeometryData.Vertices.Count);

            // Set EOF.
            fileOffsets.TotalFileSize = currentCursorPointer;

            // Return the file offsets.
            return(fileOffsets);
        }
Exemple #6
0
        /// <summary>
        /// Writes the triangle list to the output CL File.
        /// </summary>
        /// <param name="ClFile">The list of bytes to represent the collision file.</param>
        /// <param name="quadtreeData">Contains the quadtree information and details.</param>
        private static void WriteTriangleList(List <byte> clFile, QuadtreeGenerator quadtreeData)
        {
            // Retrieve all nodes with triangles.
            Quadnode[] quadnodesWithTriangles = QuadtreeGenerator.QuadNodes.Where(x => x.TrianglesInNode.Count > 0).ToArray();

            // Loop over all bottom level nodes, add triangles.
            for (int x = 0; x < quadnodesWithTriangles.Length; x++)
            {
                // Set triangle list offset.
                quadnodesWithTriangles[x].TriangleListOffset = (uint)clFile.Count;

                // Add triangles.
                foreach (HeroesTriangle triangle in quadnodesWithTriangles[x].TrianglesInNode)
                {
                    clFile.AddRange(BitConverter.GetBytes((ushort)triangle.TriangleIndex).Reverse());
                }

                // Replace the original quadnode list element
                QuadtreeGenerator.QuadNodes[quadnodesWithTriangles[x].NodeIndices.NodeIndex] = quadnodesWithTriangles[x];
            }
        }
Exemple #7
0
        /// <summary>
        /// Writes the quadnode list to the output CL File.
        /// </summary>
        /// <param name="clFile"></param>
        /// <param name="quadtreeData">Contains the quadtree information and details.</param>
        private static void WriteQuadnodeList(List <byte> clFile, QuadtreeGenerator quadtreeData)
        {
            // For each node.
            for (int x = 0; x < QuadtreeGenerator.QuadNodes.Length; x++)
            {
                // Append the Node, Parent and Child node indices.
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeIndices.NodeIndex).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeIndices.NodeParent).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeIndices.NodeChild).Reverse());

                // Appens the calculated neighbour indices to the node.
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeNeighbours.RightNeightbourIndex).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeNeighbours.LeftNeightbourIndex).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeNeighbours.BottomNeighbourIndex).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].NodeNeighbours.TopNeighbourIndex).Reverse());

                // Append the amount of triangles present within this quadnode.
                // If the quadnode is not a bottom level node without children, we do not assign an offset.
                if (QuadtreeGenerator.QuadNodes[x].TriangleListOffset == 0)
                {
                    clFile.AddRange(BitConverter.GetBytes((ushort)0));
                }
                else
                {
                    clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].TrianglesInNode.Count).Reverse());
                }

                // Append the offset to the triangle list within the file.
                clFile.AddRange(BitConverter.GetBytes((uint)QuadtreeGenerator.QuadNodes[x].TriangleListOffset).Reverse());

                // Append the horizontal and vertical quadnode offset as well as the depth level.
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].PositioningHorizontalOffset).Reverse());
                clFile.AddRange(BitConverter.GetBytes((ushort)QuadtreeGenerator.QuadNodes[x].PositioningVerticalOffset).Reverse());
                clFile.Add((byte)(QuadtreeGenerator.QuadNodes[x].DepthLevel));

                // Dummy bytes that are not used in the original struct.
                clFile.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
            }
        }