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