///------------------------------------------------------------------------------------------------- /// <summary> /// Creates geometries for the relevant BSP meshes that are to be included in the collada /// file. /// </summary> ///------------------------------------------------------------------------------------------------- private void CreateGeometryList() { IHalo1BSPDataProvider provider = GetDataProvider <IHalo1BSPDataProvider>(); H1.Tags.structure_bsp_group definition = mTagManager.TagDefinition as H1.Tags.structure_bsp_group; if (provider.IncludeRenderMesh) { for (int i = 0; i < definition.Lightmaps.Count; i++) { CreateRenderGeometry(i); } } if (provider.IncludePortals) { for (int i = 0; i < definition.ClusterPortals.Count; i++) { CreatePortalsGeometry(i); } } if (provider.IncludeFogPlanes) { for (int i = 0; i < definition.FogPlanes.Count; i++) { CreateFogPlaneGeometry(i); } } }
/// <summary> /// Creates geometries for the relevant BSP meshes that are to be included in the collada file /// </summary> void CreateGeometryList() { H1.Tags.structure_bsp_group definition = tagManager.TagDefinition as H1.Tags.structure_bsp_group; if (bspInfo.IncludeRenderMesh()) { for (int i = 0; i < definition.Lightmaps.Count; i++) { CreateRenderGeometry(i); } } if (bspInfo.IncludePortalsMesh()) { for (int i = 0; i < definition.ClusterPortals.Count; i++) { CreatePortalsGeometry(i); } } if (bspInfo.IncludeFogPlanesMesh()) { for (int i = 0; i < definition.FogPlanes.Count; i++) { CreateFogPlaneGeometry(i); } } }
/// <summary> /// Creates nodes for all the geometry elements in the collada file /// </summary> void CreateNodeList() { H1.Tags.structure_bsp_group definition = tagManager.TagDefinition as H1.Tags.structure_bsp_group; // create a list of ever shader used List <string> shader_list = new List <string>(); for (int shader_index = 0; shader_index < shaderInfo.GetShaderCount(); shader_index++) { shader_list.Add(ColladaUtilities.FormatName(Path.GetFileNameWithoutExtension(shaderInfo.GetShaderName(shader_index)), " ", "_")); } // if portals are included add the portals shader to the names if (bspInfo.IncludePortalsMesh()) { shader_list.Add("portals"); } // if fogplanes are included add the fogplanes shader to the names if (bspInfo.IncludeFogPlanesMesh()) { shader_list.Add("fogplanes"); } int geometry_offset = 0; if (bspInfo.IncludeRenderMesh()) { // create geometry instance for all of the lightmaps for (int i = 0; i < definition.Lightmaps.Count; i++) { CreateNodeInstanceGeometry(listGeometry[geometry_offset + i].Name, geometry_offset + i, shader_list); } geometry_offset += definition.Lightmaps.Count; } if (bspInfo.IncludePortalsMesh()) { // create geometry instance for all of the portal meshes for (int i = 0; i < definition.ClusterPortals.Count; i++) { CreateNodeInstanceGeometry(listGeometry[geometry_offset + i].Name, geometry_offset + i, shader_list); } geometry_offset += definition.ClusterPortals.Count; } if (bspInfo.IncludeFogPlanesMesh()) { // create geometry instance for all of the fogplane meshes for (int i = 0; i < definition.FogPlanes.Count; i++) { CreateNodeInstanceGeometry(listGeometry[geometry_offset + i].Name, geometry_offset + i, shader_list); } geometry_offset += definition.FogPlanes.Count; } }
/// <summary> /// Creates a vertex index list from a set of bsp surfaces /// </summary> /// <param name="definition">The bsp tag definition</param> /// <param name="surface_offset">The surface index to start collecting indices from</param> /// <param name="surface_count">The number of surfaces to collect indices from</param> /// <param name="index_offset">The amount to offset the collected indices by</param> /// <returns></returns> List <int> CreateIndicesBSP(H1.Tags.structure_bsp_group definition, int surface_offset, int surface_count, int index_offset) { List <int> indices = new List <int>(); for (int i = 0; i < surface_count; i++) { indices.Add(definition.Surfaces[surface_offset + i].A3 + index_offset); indices.Add(definition.Surfaces[surface_offset + i].A2 + index_offset); indices.Add(definition.Surfaces[surface_offset + i].A1 + index_offset); } return(indices); }
/// <summary> /// Creates nodes for the BSP markers /// </summary> void CreateMarkerList() { H1.Tags.structure_bsp_group definition = tagManager.TagDefinition as H1.Tags.structure_bsp_group; List <Marker> marker_list = new List <Marker>(); // create common marker definitions for the bsp markers foreach (var marker in definition.Markers) { Marker common_marker = new Marker(marker.Name, marker.Position.ToPoint3D(100), TagInterface.RealQuaternion.Invert(marker.Rotation), -1); marker_list.Add(common_marker); } // create the marker node elements CreateMarkers(marker_list, RotationVectorY, RotationVectorP, RotationVectorR); }
///------------------------------------------------------------------------------------------------- /// <summary> Creates a geometry element for a single fog plane. </summary> /// <param name="index"> Index of the fog plane to create a geometry element for. </param> ///------------------------------------------------------------------------------------------------- private void CreateFogPlaneGeometry(int index) { H1.Tags.structure_bsp_group definition = mTagManager.TagDefinition as H1.Tags.structure_bsp_group; Geometry geometryData = new Geometry("fogplane-" + index.ToString() , 0 , Geometry.VertexComponent.POSITION); foreach (var vertex in definition.FogPlanes[index].Vertices) { geometryData.AddVertex(new Geometry.Vertex(vertex.Value.ToPoint3D(100))); } // we only have one part since it only has one material Geometry.Part common_part = new Geometry.Part("fogplanes"); common_part.AddIndices(BuildFaceIndices(definition.FogPlanes[index].Vertices.Count)); geometryData.AddPart(common_part); // create the geometry element CreateGeometry(geometryData); }
/// <summary> /// Creates a geometry element for a single fog plane /// </summary> /// <param name="index">Index of the fog plane to create a geometry element for</param> /// <returns></returns> void CreateFogPlaneGeometry(int index) { H1.Tags.structure_bsp_group definition = tagManager.TagDefinition as H1.Tags.structure_bsp_group; List <Vertex> common_vertices = new List <Vertex>(); foreach (var vertex in definition.FogPlanes[index].Vertices) { common_vertices.Add(new Vertex(vertex.Value.ToPoint3D(100))); } List <Part> common_parts = new List <Part>(); // we only have one part since it only has one material Part common_part = new Part("fogplanes"); common_part.AddIndices(BuildFaceIndices(definition.FogPlanes[index].Vertices.Count)); common_parts.Add(common_part); // create the geometry element CreateGeometry("fogplane-" + index.ToString(), 0, VertexComponent.POSITION, common_vertices, common_parts); }
///------------------------------------------------------------------------------------------------- /// <summary> Creates a geometry element for a single cluster portal. </summary> /// <param name="index"> The lightmap index to create a geometry from. </param> ///------------------------------------------------------------------------------------------------- private void CreatePortalsGeometry(int index) { H1.Tags.structure_bsp_group definition = mTagManager.TagDefinition as H1.Tags.structure_bsp_group; Geometry geometryData = new Geometry("portal-" + index.ToString() , 0 , Geometry.VertexComponent.POSITION | Geometry.VertexComponent.NORMAL); foreach (var vertex in definition.ClusterPortals[index].Vertices) { geometryData.AddVertex(new Geometry.Vertex(vertex.Value.ToPoint3D(100), new LowLevel.Math.real_vector3d(0, 0, 1))); } // we only have one part since it only has one material Geometry.Part common_part = new Geometry.Part("portals"); common_part.AddIndices(BuildFaceIndices(definition.ClusterPortals[index].Vertices.Count)); geometryData.AddPart(common_part); // create the geometry element CreateGeometry(geometryData); }
/// <summary> /// Creates a geometry element for a BSP lightmap /// </summary> /// <param name="index">The lightmap index to create a geometry from</param> /// <returns></returns> void CreateRenderGeometry(int index) { H1.Tags.structure_bsp_group definition = tagManager.TagDefinition as H1.Tags.structure_bsp_group; List <Vertex> common_vertices = new List <Vertex>(); // add all of the vertices used in the render geometry foreach (var material in definition.Lightmaps[index].Materials) { // read vertex information from the uncompressed vertex data System.IO.BinaryReader uncompressed_reader = new System.IO.BinaryReader( new System.IO.MemoryStream(material.UncompressedVertices.Value)); int vertex_count = material.VertexBuffersCount1; for (int vertex_index = 0; vertex_index < vertex_count; vertex_index++) { Vertex common_vertex = new Vertex( //RealPoint3D position new LowLevel.Math.real_point3d( uncompressed_reader.ReadSingle() * 100, uncompressed_reader.ReadSingle() * 100, uncompressed_reader.ReadSingle() * 100), //RealVector3D normal new LowLevel.Math.real_vector3d( uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle()), //RealVector3D binormal new LowLevel.Math.real_vector3d( uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle()), //RealVector3D tangent new LowLevel.Math.real_vector3d( uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle(), uncompressed_reader.ReadSingle())); //RealPoint2D texcoord0 common_vertex.AddTexcoord(new LowLevel.Math.real_point2d( uncompressed_reader.ReadSingle(), (uncompressed_reader.ReadSingle() * -1) + 1)); //RealPoint2D texcoord1 if (material.VertexBuffersCount2 != 0) { int position = (int)uncompressed_reader.BaseStream.Position; uncompressed_reader.BaseStream.Position = (material.VertexBuffersCount1 * 56) + (vertex_index * 20) + 12; common_vertex.AddTexcoord(new LowLevel.Math.real_point2d( uncompressed_reader.ReadSingle(), (uncompressed_reader.ReadSingle() * -1) + 1)); uncompressed_reader.BaseStream.Position = position; } else { common_vertex.AddTexcoord(new LowLevel.Math.real_point2d(0, 1)); } common_vertices.Add(common_vertex); } ; } List <Part> common_parts = new List <Part>(); // add part definitions for the lightmap materials // an index offset is necessary since the vertex list is global for this geometry, rather than local to each material int index_offset = 0; foreach (var material in definition.Lightmaps[index].Materials) { Part common_part = new Part(Path.GetFileNameWithoutExtension(material.Shader.ToString())); common_part.AddIndices(CreateIndicesBSP(definition, material.Surfaces, material.SurfaceCount, index_offset)); index_offset += material.VertexBuffersCount1; common_parts.Add(common_part); } // create the geometry element CreateGeometry(ColladaUtilities.FormatName(tagName, " ", "_") + "-" + definition.Lightmaps[index].Bitmap.ToString(), 2, VertexComponent.POSITION | VertexComponent.NORMAL | VertexComponent.BINORMAL | VertexComponent.TANGENT | VertexComponent.TEXCOORD, common_vertices, common_parts); }