/// <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 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 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); }
/// <summary> /// Searches a shader for a specific parameter by name /// </summary> /// <param name="shader">The shader to search in</param> /// <param name="parameter_name">The name of the parameter to find</param> /// <returns></returns> H2.Tags.global_shader_parameter_block FindParameter(H2.Tags.shader_group shader, string parameter_name) { foreach (var block in shader.Parameters) if (block.Name.ToString().Equals(parameter_name)) return block; return null; }