public HairMesh[] Import(BinaryReader reader, string path, Hair hair, HairImportSettings importSettings) { reader.Close(); // Initialize the importer string[] objContent = File.ReadAllLines(path); List <Vector3> vertices = new List <Vector3>(); List <Line> indices = new List <Line>(); List <HairStrand> currentStrands = new List <HairStrand>(); // Parse all vertices and indices for (int i = 0; i < objContent.Length; i++) { // Get all parts List <string> partsList = new List <string>(objContent[i].Split(' ')); partsList.RemoveAll(x => string.IsNullOrEmpty(x.Replace(" ", ""))); string[] parts = partsList.ToArray(); switch (parts[0]) { case "v": { vertices.Add(Vector3.Multiply(new Vector3(SafeParse(parts[1]), SafeParse(parts[2]), SafeParse(parts[3])), importSettings.scale)); } break; case "l": { indices.Add(new Line(int.Parse(parts[1]) - 1, int.Parse(parts[2]) - 1)); } break; } } // Parse all strands List <int> alreadyLoadedIndices = new List <int>(640000); List <HairStrandVertex> currentStrandVertices = new List <HairStrandVertex>(64); for (int i = 0; i < indices.Count; i++) { // In order to detect when a new hair starts, we detect if the first index in a line was not added to the mesh already. // If it was NOT, we are in a new strand if (i != 0 && !alreadyLoadedIndices.Contains(indices[i].index1)) { // We are in a new hair strand HairStrand hs = new HairStrand(); currentStrandVertices[0].isMovable = false; currentStrandVertices.ForEach((sv) => { hs.vertices.Add(sv); }); hs.isGuidanceStrand = true; currentStrands.Add(hs); // Cleanup currentStrandVertices.Clear(); } // Add if (!alreadyLoadedIndices.Contains(indices[i].index1)) { currentStrandVertices.Add(new HairStrandVertex(vertices[indices[i].index1], Vector3.Zero, Vector4.Zero)); alreadyLoadedIndices.Add(indices[i].index1); } if (!alreadyLoadedIndices.Contains(indices[i].index2)) { currentStrandVertices.Add(new HairStrandVertex(vertices[indices[i].index2], Vector3.Zero, Vector4.Zero)); alreadyLoadedIndices.Add(indices[i].index2); } } // Shuffle strands currentStrands = FormatHelper.Shuffle(currentStrands); HairMesh hm = new HairMesh(); currentStrands.ForEach((item) => { hm.strands.Add(item); }); return(new HairMesh[] { hm }); }
public HairMesh[] Import(BinaryReader reader, string path, Hair hair, HairImportSettings importSettings) { reader.Close(); // Initialize the import // Load the ase file content // Create a List for all meshes // Create a list for the current-mesh strands string[] aseContent = File.ReadAllLines(path); List <HairMesh> hairMeshes = new List <HairMesh>(); List <HairStrand> currentStrands = new List <HairStrand>(); // Init "state"-variables int currentStrand = 0; int currentHairId = -1; // Now the hard part begins... for (int i = 0; i < aseContent.Length; i++) { string[] tokens = aseContent[i].Split('\t'); if (aseContent[i].Contains("*SHAPE_LINECOUNT")) { tokens = tokens[1].Split(' '); } else if (aseContent[i].Contains("SHAPE_LINE")) { tokens = tokens[1].Split(' '); } if (tokens.Length >= 2) { if (tokens[0] == "*SHAPE_LINECOUNT") { if (currentStrand > 0) { // Start parsing next mesh after flushing the current strands buffer currentHairId++; currentStrand = 0; // Add to mesh list / flush current strands buffer HairMesh hairMesh = new HairMesh(); foreach (HairStrand strand in currentStrands) { hairMesh.strands.Add(strand); } hairMeshes.Add(hairMesh); // Clear current strands currentStrands.Clear(); } } else if (tokens[0] == "*SHAPE_LINE") { HairStrand strand = new HairStrand(); strand.isGuidanceStrand = true; string[] vertexCountTokens = aseContent[i + 1].Split(' '); // Parse the current line int vertexCount = int.Parse(vertexCountTokens[1]); // Parse vertices for (int j = 0; j < vertexCount; j++) { string[] vertexTokens = aseContent[i + 2 + j].Replace('.', ',').Split('\t'); if (vertexTokens[2] == "*SHAPE_VERTEX_INTERP") { continue; } System.Globalization.NumberFormatInfo nf = new System.Globalization.NumberFormatInfo() { NumberGroupSeparator = "." }; vertexTokens[4] = vertexTokens[4].Replace(',', '.'); vertexTokens[5] = vertexTokens[5].Replace(',', '.'); vertexTokens[6] = vertexTokens[6].Replace(',', '.'); Vector3 position = new Vector3(float.Parse(vertexTokens[4], nf), float.Parse(vertexTokens[6], nf), float.Parse(vertexTokens[5], nf)); position = Vector3.Multiply(position, importSettings.scale); HairStrandVertex v = new HairStrandVertex(position, Vector3.Zero, Vector4.Zero); if (strand.vertices.Count == 0) { v.isMovable = false; } strand.vertices.Add(v); } currentStrands.Add(strand); // Increment file-line-pointer i = i + 1 + vertexCount; currentStrand++; } } } // Shuffle strands currentStrands = FormatHelper.Shuffle(currentStrands); // Get last mesh HairMesh lastMesh = new HairMesh(); lastMesh.strands.AddRange(currentStrands); hairMeshes.Add(lastMesh); return(hairMeshes.ToArray()); }