Esempio n. 1
0
        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 });
        }
Esempio n. 2
0
        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());
        }