/// <summary> /// If the incoming vertex does already exist in the vertex collection of the meshObject it returns the index of the already existing item. /// Else it adds the incoming vertex to the collection and returns its current index. /// </summary> /// <param name="index"></param> /// <param name="vertex"></param> /// <returns></returns> private int AddVertex(int index, PositionNormalTextureVertex vertex) { // TODO PERFORMANCE LEAK for large meshes //if (_mesh_object_file.Vertices.Contains(vertex)) //{ // return _mesh_object_file.Vertices.IndexOf(vertex); //} //else { _mesh_object_file.Vertices.Add(vertex); return _mesh_object_file.Vertices.Count - 1; } }
/// <summary> /// Dispatcher for the geometry file. /// Formats: f int int int | f int/int int/int int/int | f int/int/int int/int/int int/int/int /// Collects the data from the temporary lists and assign them to the mesh. /// Faces are stored as series of three vertices in clockwise order. Vertices are described by their /// position, optional texture coordinate, and optional normal, encoded as indices into the respective /// temporary component list. /// </summary> /// <param name="splitted"></param> private void AddFaces(string[] splitted) { if (splitted.Length >= 4) { int index_position = 0, index_texcoord, index_normal; int vertex_in_face, first_index; int[] index_helper = new int[4]; PositionNormalTextureVertex vertex = new PositionNormalTextureVertex(); if (splitted[1] == string.Empty) { // more than 1 space distance int old_length = splitted.Length; // remove additional spacings List<String> tmp_space_split = new List<string>(); for (int i = 0; i < old_length; i++) { if (splitted[i] != string.Empty) { tmp_space_split.Add(splitted[i]); } } splitted = tmp_space_split.ToArray(); } vertex_in_face = splitted.Length - 1; for (int index_face = 0; index_face < vertex_in_face; index_face++) { // get indices for position, texcoords and normals out of the file and get with them the values from the according normal, position or texcoords list // for a single vertice string[] vertice_series = splitted[1 + index_face].Split('/'); if (vertice_series.Length >= 1) { // is in format: f int int int index_position = Int32.Parse(vertice_series[0]); vertex.Position = _tmp_positions[index_position - 1]; } if (vertice_series.Length >= 2) { // format: f int/int int/int int/int if (!String.IsNullOrEmpty(vertice_series[1])) { index_texcoord = Int32.Parse(vertice_series[1]); vertex.TextureCoordinate = _tmp_tex_coords[index_texcoord - 1]; } } if (vertice_series.Length >= 3) { // format: int/int/int .. index_normal = Int32.Parse(vertice_series[2]); vertex.Normal = _tmp_normals[index_normal - 1]; } // if a duplicate vertex doesn't exist, add this vertex to the vertices list and store the index in the indices list. // after the fileinput these data eventually become the vertex buffer and index buffer for the mesh. int index = AddVertex(index_position, vertex); // faces helper for four faces -> f 1 2 3 4 if(vertex_in_face == 4 && index_face >= 0 && index_face < 4) { index_helper[index_face] = index; } if(index_face < 3) { _mesh_object_file.Indices.Add(index); } else { _mesh_object_file.Attributes.Add(_current_material_subset_index); // add new trianglestrip //for (int i = 2; i >= 0; i--) // _mesh_object_file.Indices.Add(index_helper[i]); _mesh_object_file.Indices.Add(index_helper[0]); _mesh_object_file.Indices.Add(index_helper[2]); _mesh_object_file.Indices.Add(index_helper[3]); _mesh_object_file.Attributes.Add(_current_material_subset_index); } } if (vertex_in_face < 4) _mesh_object_file.Attributes.Add(_current_material_subset_index); } }