/// <summary> /// Creates a list of vertex indices for a Halo2 geometry section, assuming the data is in a triangle list /// </summary> /// <param name="section">The geometry section containing the requested part</param> /// <param name="part_index">The part index to create indices for</param> /// <returns></returns> protected List <int> CreateIndicesWorldSpace(H2.Tags.global_geometry_section_struct section, int part_index) { List <int> indices = new List <int>(); // add the strip indices to an easier to handle index list, ignoring invalid indices List <int> index_list = new List <int>(); { var part = section.Parts[part_index]; for (int i = 0; i < part.StripLength; i++) { if (section.StripIndices[part.StripStartIndex + i].Index.Value != -1) { index_list.Add(section.StripIndices[part.StripStartIndex + i].Index.Value); } } } // add indices to the list, assuming each 3 indices is one triangle for (int surface_index = 0; surface_index < index_list.Count; surface_index += 3) { indices.Add((int)index_list[surface_index + 0]); indices.Add((int)index_list[surface_index + 1]); indices.Add((int)index_list[surface_index + 2]); } return(indices); }
/// <summary> /// Creates a list of vertex indices for a Halo2 geometry section, assuming the data is in a triangle strip /// </summary> /// <param name="section">The geometry section containing the requested part</param> /// <param name="part_index">The part index to create indices for</param> /// <returns></returns> protected List <int> CreateIndicesSkinned(H2.Tags.global_geometry_section_struct section, int part_index) { List <int> indices = new List <int>(); // the strip indices for all of the parts are generated in one go and are all connected, so the strip start and length // variables have to be used, so that the useless faces connecting the parts are ignored // add the strip indices to an easier to handle index list, ignoring invalid indices List <int> index_list = new List <int>(); for (int i = 0; i < section.Parts[part_index].StripLength; i++) { if (section.StripIndices[section.Parts[part_index].StripStartIndex + i].Index.Value != -1) { index_list.Add(section.StripIndices[section.Parts[part_index].StripStartIndex + i].Index.Value); } } // return the index list after converting it to a triangle list return(ConvertTriStripToList(index_list)); }
/// <summary> /// Creates a geometry element for a Halo geometry section /// </summary> /// <param name="name">The name for the geometry</param> /// <param name="is_skinned">Controls whether the strip indices should be treated as a triangle strip or a triangle list</param> /// <param name="section">The geometry section to create an element for</param> /// <param name="shader_names">A string list containing all of the shader names</param> protected void CreateGeometryHalo2(string name, bool is_skinned, H2.Tags.global_geometry_section_info_struct section_info, H2.Tags.global_geometry_section_struct section, List <string> shader_names) { List <Vertex> common_vertices = new List <Vertex>(); // create a generic list of vertices foreach (var vertex in section.RawVertices) { Vertex common_vertex = new Vertex( vertex.Point.Position.ToPoint3D(100), vertex.Normal.ToVector3D(), vertex.Binormal.ToVector3D(), vertex.Tangent.ToVector3D()); common_vertex.AddTexcoord(new LowLevel.Math.real_point2d( vertex.Texcoord.X, (vertex.Texcoord.Y * -1) + 1)); common_vertex.AddTexcoord(new LowLevel.Math.real_point2d( vertex.SecondaryTexcoord.X, (vertex.SecondaryTexcoord.Y * -1) + 1)); common_vertex.AddTexcoord(new LowLevel.Math.real_point2d( vertex.PrimaryLightmapTexcoord.X, (vertex.PrimaryLightmapTexcoord.Y * -1) + 1)); common_vertices.Add(common_vertex); } List <Part> commom_parts = new List <Part>(); // create the generic part definition list for (int part_index = 0; part_index < section.Parts.Count; part_index++) { string shader_name; if (shader_names.Count == 0) { shader_name = ""; } else { shader_name = shader_names[section.Parts[part_index].Material]; } Part common_part = new Part(shader_name); if (is_skinned) { common_part.AddIndices(CreateIndicesSkinned(section, part_index)); } else { common_part.AddIndices(CreateIndicesWorldSpace(section, part_index)); } commom_parts.Add(common_part); } // create the geometry element CreateGeometry(name, 3, VertexComponent.POSITION | VertexComponent.NORMAL | VertexComponent.BINORMAL | VertexComponent.TANGENT | VertexComponent.TEXCOORD, common_vertices, commom_parts); }