示例#1
0
        static void Main(string[] args)
        {
            // Check args length
            if (args.Length < 1)
            {
                LogToConsole("ERROR! Wrong syntax! asetotfx.exe [ASE FILE] [TFX PREFIX]", ConsoleColor.Red);
                return;
            }

            // Load args
            string asefile        = args[0];
            string hairFilePrefix = args[1];

            // Start parsing the file
            LogToConsole("Loading ASE File...", ConsoleColor.Blue);
            string[] aseContent = File.ReadAllLines(asefile);
            List <TressFXStrand[]> currentStrands = new List <TressFXStrand[]>();
            int   currentStrand      = 0;
            int   currentHairId      = -1;
            float texcoordMultiplier = 0;

            LogToConsole("Starting ASE parsing... This may take a LONG while..", ConsoleColor.Blue);

            // 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")
                    {
                        currentStrands.Add(new TressFXStrand[int.Parse(tokens[1])]);
                        currentStrand = 0;
                        currentHairId++;

                        texcoordMultiplier = 1.0f / (float)int.Parse(tokens[1]);
                        LogToConsole("Starting parse hair: " + currentHairId + ", lines count: " + int.Parse(tokens[1]), ConsoleColor.Yellow);
                    }
                    else if (tokens[0] == "*SHAPE_LINE")
                    {
                        // Parse the current line
                        Vector3[] positions = null;

                        string[] vertexCountTokens = aseContent[i + 1].Split(' ');
                        positions = new Vector3[int.Parse(vertexCountTokens[1])];

                        // Parse vertices
                        for (int j = 0; j < positions.Length; j++)
                        {
                            string[] vertexTokens = aseContent[i + 2 + j].Replace('.', ',').Split('\t');

                            positions[j] = new Vector3(float.Parse(vertexTokens[4]), float.Parse(vertexTokens[5]), float.Parse(vertexTokens[6]));
                        }

                        currentStrands[currentHairId][currentStrand]           = new TressFXStrand();
                        currentStrands[currentHairId][currentStrand].vertices  = positions;
                        currentStrands[currentHairId][currentStrand].texcoordX = texcoordMultiplier * currentStrand;

                        i = i + 1 + positions.Length;

                        currentStrand++;
                    }
                }
            }

            LogToConsole("Asefile Parsed! Hairs parsed: " + currentHairId + " starting TressFX Export...", ConsoleColor.Green);

            // Build TFX files
            for (int i = 0; i < currentStrands.Count; i++)
            {
                LogToConsole("Exporting hair " + i + "...", ConsoleColor.Yellow);
                StringBuilder currentHairBuilder = new StringBuilder();
                currentHairBuilder.Append("numStrands " + currentStrands[i].Length + "\r\nis sorted 1\r\n");

                // Write strands
                for (int j = 0; j < currentStrands[i].Length; j++)
                {
                    currentHairBuilder.Append("strand " + j + " numVerts " + currentStrands[i][j].vertices.Length + " texcoord " + currentStrands[i][j].texcoordX + " 000000\r\n");
                    for (int k = 0; k < currentStrands[i][j].vertices.Length; k++)
                    {
                        currentHairBuilder.Append(currentStrands[i][j].vertices[k].x + " " + currentStrands[i][j].vertices[k].y + " " + currentStrands[i][j].vertices[k].z + "\r\n");
                    }
                }

                File.WriteAllText(hairFilePrefix + "_" + i + ".txt", currentHairBuilder.ToString().Replace(",", "."));
                LogToConsole("Exported hair " + i + "!", ConsoleColor.Green);
                currentStrands[i] = null;
            }


            LogToConsole("Everything done :->", ConsoleColor.Green);
            Console.ReadLine();
        }
示例#2
0
    /// <summary>
    /// Loads the hair tfx (text) file.
    /// This will generate the hair vertices and strandindices and store them in the passed lists.
    /// </summary>
    /// <param name="hairData">Hair mesh data (text from tfx file)</param>
    /// <param name="verticeList">The list where the vertices should go.</param>
    /// <param name="strandIndices">The list where the StrandIndices should go.</param>
    /// <param name="hairId">The HairID (starts at 0)</param>
    private int LoadHairTFX(string hairData, List <TressFXStrand> strandsList, int hairId)   // string hairData, List<Vector4> verticeList, List<StrandIndex> strandIndices, List<int> verticesOffsets, int hairId) //, List<Vector3> normalList)
    {
        int vertexCount = 0;

        // Start parsing hair file
        string[] hairLines = hairData.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

        // Wrong line endings?
        if (hairLines.Length < 2)
        {
            hairLines = hairData.Split(new string[] { "\n" }, StringSplitOptions.None);
        }

        // Properties
        int numStrands = 0;

        // Read every line of the data
        int i = 0;

        while (i < hairLines.Length)
        {
            string[] stringTokens = hairLines[i].Split(' ');

            // Hair definition
            if (stringTokens[0] == "numStrands")
            {
                // Strands definition
                numStrands = int.Parse(stringTokens[1]);
            }
            // Strand definition
            else if (stringTokens[0] == "strand")
            {
                // Parse informations about the strand
                // int strandNum = int.Parse(stringTokens[1]);
                int   numStrandVertices = int.Parse(stringTokens[3]);
                float texcoordX         = float.Parse(stringTokens[5]);

                TressFXStrand strand = new TressFXStrand(numStrandVertices);

                // Used for corruption check
                // If a strand or just one vertex of it is corrupted it will get ignored
                bool corrupted = false;

                int j;

                // Read all vertices
                for (j = 0; j < numStrandVertices; j++)
                {
                    // String tokens
                    string[] vertexData = hairLines[i + 1].Split(' ');

                    // Strand corrupted?
                    if (vertexData[0] == "-1.#INF" || vertexData[1] == "-1.#INF" || vertexData[2] == "-1.#INF")
                    {
                        corrupted = true;
                        break;
                    }

                    // invMass = 1 means strand movable, 0 means not movable
                    float invMass = 1.0f;

                    if (j == 0 || j == 1 || (j == numStrandVertices - 1 && this.hairs[hairId].makeBothEndsImmovable))
                    {
                        invMass = 0.0f;
                    }

                    // Set TressFX Strand data
                    strand.vertices[j]     = new TressFXVertex();
                    strand.vertices[j].pos = new Vector3(float.Parse(vertexData[0]),                                    // X
                                                         float.Parse(vertexData[1]),                                    // Y
                                                         float.Parse(vertexData[2]));                                   // Z
                    strand.vertices[j].pos.Scale(this.transform.lossyScale);

                    // Load UVs
                    strand.vertices[j].texcoords.x = texcoordX;
                    strand.vertices[j].texcoords.y = (1.0f / (float)numStrandVertices) * (float)(j + 1);

                    strand.vertices[j].invMass = invMass;
                    strand.hairId = hairId;

                    i++;
                }

                // Corrupted strands
                if (corrupted)
                {
                    // Delete this strand
                    numStrands--;
                }
                else
                {
                    vertexCount += j;
                    strandsList.Add(strand);
                }
            }

            i++;
        }

        return(vertexCount);
    }