Exemple #1
0
        public static HsfFile Import(STGenericScene scene, ImportSettings settings)
        {
            HsfFile hsf  = new HsfFile();
            var     root = ObjectDataSection.CreateNewObject(ObjectType.Root);

            hsf.ObjectData.Objects.Add(root);
            hsf.ObjectData.ObjectNames.Add("Root");

            foreach (var tex in scene.Models[0].Textures)
            {
                Console.WriteLine($"tex {tex.Name}");

                var newtex = CreateTexture(tex);
                newtex.Name = tex.Name;
                hsf.Textures.Add(newtex);
            }

            if (hsf.Textures.Count == 0)
            {
            }

            var newtex2 = CreateTexture(new GenericBitmapTexture("dummy.png"));

            newtex2.Name = "dummy";
            hsf.Textures.Add(newtex2);

            hsf.FogData.Count      = 1;
            hsf.FogData.ColorStart = new Vector4(77, 77, 77, 128);
            hsf.FogData.ColorEnd   = new Vector4(255, 0, 0, 255);
            hsf.FogData.Start      = 0;
            hsf.FogData.End        = 10000;

            Console.WriteLine("Importing Models");

            foreach (var model in scene.Models)
            {
                foreach (var material in model.GetMaterials())
                {
                    var mat = HSF_MaterialConverter.Import($"mat1.json");
                    mat.MaterialData.VertexMode = 2;
                    mat.Name = material.Name;
                    hsf.Materials.Add(mat);

                    if (material.TextureMaps.Count > 0)
                    {
                        var texMap = material.TextureMaps[0].Name;
                        int index  = hsf.Textures.FindIndex(x => x.Name == texMap);
                        if (index != -1)
                        {
                            mat.Textures[0].Item2.TextureIndex = index;
                        }
                    }
                    mat.Textures[0].Item2.WrapS = 1;
                    mat.Textures[0].Item2.WrapT = 1;
                }

                if (hsf.Materials.Count == 0)
                {
                    var mat = HSF_MaterialConverter.Import($"mat1.json");
                    mat.MaterialData.VertexMode = 2;
                    mat.Name = "Basic";
                    hsf.Materials.Add(mat);
                }

                foreach (var mesh in model.Meshes)
                {
                    root.ChildrenCount += 1;

                    List <Vector3> positions = new List <Vector3>();
                    List <Vector3> normals   = new List <Vector3>();
                    List <Vector2> texCoords = new List <Vector2>();
                    List <Vector4> colors    = new List <Vector4>();

                    for (int v = 0; v < mesh.Vertices.Count; v++)
                    {
                        var vertex = mesh.Vertices[v];

                        if (!positions.Contains(vertex.Position))
                        {
                            positions.Add(vertex.Position);
                        }

                        if (!normals.Contains(vertex.Normal))
                        {
                            normals.Add(vertex.Normal);
                        }

                        if (vertex.Colors.Length > 0)
                        {
                            if (!colors.Contains(vertex.Colors[0]))
                            {
                                colors.Add(vertex.Colors[0]);
                            }
                        }
                        if (vertex.TexCoords.Length > 0)
                        {
                            if (!texCoords.Contains(vertex.TexCoords[0]))
                            {
                                texCoords.Add(vertex.TexCoords[0]);
                            }
                        }
                    }

                    var bounding = GenerateBoundingBox(mesh);

                    ObjectData objData = ObjectDataSection.CreateNewObject(ObjectType.Mesh);
                    objData.CullBoxMax     = bounding.Max;
                    objData.CullBoxMin     = bounding.Min;
                    objData.AttributeIndex = 0;
                    objData.ParentIndex    = 0;
                    hsf.ObjectData.Objects.Add(objData);
                    hsf.ObjectData.ObjectNames.Add(mesh.Name);

                    Mesh msh = new Mesh(objData, mesh.Name);
                    msh.Positions.AddRange(positions);
                    msh.Normals.AddRange(normals);
                    msh.TexCoords.AddRange(texCoords);
                    msh.Colors.AddRange(colors);

                    foreach (var group in mesh.PolygonGroups)
                    {
                        int materialIndex = 0;
                        if (group.MaterialIndex != -1 && hsf.Materials.Count > group.MaterialIndex)
                        {
                            materialIndex = group.MaterialIndex;
                        }

                        byte mode = 2;
                        if (colors.Count > 0)
                        {
                            mode = 5;
                        }

                        hsf.Materials[materialIndex].MaterialData.VertexMode = mode;

                        Weight[] weightList = new Weight[mesh.Vertices.Count];
                        for (int i = 0; i < mesh.Vertices.Count; i++)
                        {
                            Weight vertWeight = new Weight();
                            for (int j = 0; j < mesh.Vertices[i].BoneIndices.Count; j++)
                            {
                                int   boneId     = mesh.Vertices[i].BoneIndices[j];
                                float boneWeight = mesh.Vertices[i].BoneWeights[j];
                                vertWeight.AddWeight(boneWeight, boneId);
                            }
                            weightList[i] = vertWeight;
                        }

                        List <PrimitiveBrawl> primlist = new List <PrimitiveBrawl>();

                        //Turn triangle set into triangle strips
                        if (settings.UseTriStrips)
                        {
                            TriStripper stripper = new TriStripper(mesh.Faces.ToArray(), weightList);
                            primlist = stripper.Strip();
                        }
                        else
                        {
                            primlist = new List <PrimitiveBrawl>();
                            for (int i = 0; i < mesh.Faces.Count; i++)
                            {
                                PrimitiveBrawl prim = new PrimitiveBrawl(PrimType.TriangleList); // Trilist
                                prim.Indices.Add(mesh.Faces[i++]);
                                prim.Indices.Add(mesh.Faces[i++]);
                                prim.Indices.Add(mesh.Faces[i]);
                                primlist.Add(prim);
                            }
                        }

                        foreach (var primitive in primlist)
                        {
                            PrimitiveObject prim = new PrimitiveObject();
                            prim.Type = PrimitiveType.Triangle;
                            if (settings.UseTriStrips)
                            {
                                prim.Type = PrimitiveType.TriangleStrip;
                            }

                            prim.Flags   = 0;
                            prim.NbtData = new OpenTK.Vector3(1, 0, 0);
                            if (hsf.Materials.Count > materialIndex)
                            {
                                prim.MaterialIndex = materialIndex;
                            }

                            if (settings.UseTriStrips)
                            {
                                prim.Vertices = new VertexGroup[primitive.Indices.Count + 1];
                            }
                            else
                            {
                                prim.Vertices    = new VertexGroup[4];
                                prim.Vertices[3] = new VertexGroup(); //Empty last grou
                            }
                            msh.Primitives.Add(prim);

                            if (prim.Type == PrimitiveType.TriangleStrip)
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }

                                prim.Vertices[3] = new VertexGroup();
                                for (int i = 4; i < prim.Vertices.Length; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i - 1];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }
                            }
                            else
                            {
                                for (int i = 0; i < primitive.Indices.Count; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }
                            }
                        }
                    }

                    hsf.Meshes.Add(msh);
                }
            }

            Console.WriteLine("Finished generating HSF binary!");

            return(hsf);
        }
Exemple #2
0
        public void ProcessVerticesWithoutWeights(Mesh mesh, VertexData vertData)
        {
            Packet pack = new Packet();


            List <Enums.GXVertexAttribute> activeAttribs = Descriptor.GetActiveAttributes();

            AttributeData.SetAttributesFromList(activeAttribs);

            //Console.WriteLine("Calculating triangle strips");

            uint[]                triindices = MakeTriIndexList(mesh);
            TriStripper           stripper   = new TriStripper(triindices);
            List <PrimitiveBrawl> primlist   = stripper.Strip();

            //Console.WriteLine(String.Format("Done, {0} primitives", primlist.Count));

            foreach (PrimitiveBrawl primbrawl in primlist)
            {
                //Primitive prim = new Primitive(Enums.GXPrimitiveType.TriangleStrip);
                Primitive prim = new Primitive((Enums.GXPrimitiveType)primbrawl.Type);
                //Console.WriteLine(String.Format("Primitive type {0}", (Enums.GXPrimitiveType)primbrawl.Type));
                foreach (int vertIndex in primbrawl.Indices)
                {
                    Vertex vert = new Vertex();

                    Weight rootWeight = new Weight();
                    rootWeight.AddWeight(1.0f, 0);

                    vert.SetWeight(rootWeight);
                    //int vertIndex = face.Indices[i];

                    foreach (Enums.GXVertexAttribute attrib in activeAttribs)
                    {
                        switch (attrib)
                        {
                        case Enums.GXVertexAttribute.Position:
                            List <Vector3> posData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Position);
                            Vector3        vertPos = mesh.Vertices[vertIndex].ToOpenTKVector3();

                            if (!posData.Contains(vertPos))
                            {
                                posData.Add(vertPos);
                            }
                            AttributeData.Positions.Add(vertPos);

                            vert.SetAttributeIndex(Enums.GXVertexAttribute.Position, (uint)posData.IndexOf(vertPos));
                            break;

                        case Enums.GXVertexAttribute.Normal:
                            List <Vector3> normData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Normal);
                            Vector3        vertNrm  = mesh.Normals[vertIndex].ToOpenTKVector3();

                            if (!normData.Contains(vertNrm))
                            {
                                normData.Add(vertNrm);
                            }
                            AttributeData.Normals.Add(vertNrm);

                            vert.SetAttributeIndex(Enums.GXVertexAttribute.Normal, (uint)normData.IndexOf(vertNrm));
                            break;

                        case Enums.GXVertexAttribute.Color0:
                        case Enums.GXVertexAttribute.Color1:
                            int          colNo   = (int)attrib - 11;
                            List <Color> colData = (List <Color>)vertData.GetAttributeData(Enums.GXVertexAttribute.Color0 + colNo);
                            Color        vertCol = mesh.VertexColorChannels[colNo][vertIndex].ToSuperBMDColorRGBA();


                            if (colNo == 0)
                            {
                                AttributeData.Color_0.Add(vertCol);
                            }
                            else
                            {
                                AttributeData.Color_1.Add(vertCol);
                            }


                            vert.SetAttributeIndex(Enums.GXVertexAttribute.Color0 + colNo, (uint)colData.IndexOf(vertCol));
                            break;

                        case Enums.GXVertexAttribute.Tex0:
                        case Enums.GXVertexAttribute.Tex1:
                        case Enums.GXVertexAttribute.Tex2:
                        case Enums.GXVertexAttribute.Tex3:
                        case Enums.GXVertexAttribute.Tex4:
                        case Enums.GXVertexAttribute.Tex5:
                        case Enums.GXVertexAttribute.Tex6:
                        case Enums.GXVertexAttribute.Tex7:
                            int            texNo        = (int)attrib - 13;
                            List <Vector2> texCoordData = (List <Vector2>)vertData.GetAttributeData(Enums.GXVertexAttribute.Tex0 + texNo);
                            Vector2        vertTexCoord = mesh.TextureCoordinateChannels[texNo][vertIndex].ToOpenTKVector2();
                            vertTexCoord = new Vector2(vertTexCoord.X, 1.0f - vertTexCoord.Y);


                            switch (texNo)
                            {
                            case 0:
                                AttributeData.TexCoord_0.Add(vertTexCoord);
                                break;

                            case 1:
                                AttributeData.TexCoord_1.Add(vertTexCoord);
                                break;

                            case 2:
                                AttributeData.TexCoord_2.Add(vertTexCoord);
                                break;

                            case 3:
                                AttributeData.TexCoord_3.Add(vertTexCoord);
                                break;

                            case 4:
                                AttributeData.TexCoord_4.Add(vertTexCoord);
                                break;

                            case 5:
                                AttributeData.TexCoord_5.Add(vertTexCoord);
                                break;

                            case 6:
                                AttributeData.TexCoord_6.Add(vertTexCoord);
                                break;

                            case 7:
                                AttributeData.TexCoord_7.Add(vertTexCoord);
                                break;
                            }

                            vert.SetAttributeIndex(Enums.GXVertexAttribute.Tex0 + texNo, (uint)texCoordData.IndexOf(vertTexCoord));
                            break;
                        }
                    }

                    //triindices[vertIndex] = 1;
                    prim.Vertices.Add(vert);
                }

                pack.Primitives.Add(prim);
            }


            pack.MatrixIndices.Add(0);
            Packets.Add(pack);

            Bounds.GetBoundsValues(AttributeData.Positions);
        }
Exemple #3
0
        public void ProcessVerticesWithWeights(Mesh mesh, VertexData vertData, Dictionary <string, int> boneNames, EVP1 envelopes, DRW1 partialWeight, bool doStrip = true)
        {
            Weight[] weights = new Weight[mesh.Vertices.Count];

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                int    vertexid   = i;
                Weight vertWeight = new Weight();

                foreach (Assimp.Bone bone in mesh.Bones)
                {
                    foreach (VertexWeight weight in bone.VertexWeights)
                    {
                        if (weight.VertexID == vertexid)
                        {
                            vertWeight.AddWeight(weight.Weight, boneNames[bone.Name]);
                        }
                    }
                }
                vertWeight.reorderBones();
                weights[vertexid] = vertWeight;
            }

            //Primitive prim = new Primitive(Enums.GXPrimitiveType.Triangles);
            List <Enums.GXVertexAttribute> activeAttribs = Descriptor.GetActiveAttributes();

            AttributeData.SetAttributesFromList(activeAttribs);


            uint[] triindices = MakeTriIndexList(mesh);

            List <PrimitiveBrawl> primlist;

            if (doStrip)
            {
                //Console.WriteLine("Calculating triangle strips for Weighted");
                TriStripper stripper = new TriStripper(triindices, weights);
                primlist = stripper.Strip();
            }
            else
            {
                //Console.WriteLine("Calculating triangle list for Weighted");
                primlist = new List <PrimitiveBrawl>();
                PrimitiveBrawl prim = new PrimitiveBrawl(PrimType.TriangleList); // Trilist
                foreach (uint index in triindices)
                {
                    prim.Indices.Add(index);
                }
                primlist.Add(prim);
            }

            //Console.WriteLine(String.Format("Done, {0} primitives", primlist.Count));



            Packet        pack          = new Packet();
            List <Weight> packetWeights = new List <Weight>();
            int           numMatrices   = 0;

            foreach (PrimitiveBrawl primbrawl in primlist)
            {
                int numNewMatricesForFirstThreeVerts = 0;
                if (!packetWeights.Contains(weights[primbrawl.Indices[0]]))
                {
                    numNewMatricesForFirstThreeVerts++;
                }
                if (!packetWeights.Contains(weights[primbrawl.Indices[1]]))
                {
                    numNewMatricesForFirstThreeVerts++;
                }
                if (!packetWeights.Contains(weights[primbrawl.Indices[2]]))
                {
                    numNewMatricesForFirstThreeVerts++;
                }
                if (numMatrices + numNewMatricesForFirstThreeVerts > MaxMatricesPerPacket)
                {
                    // We won't be able to fit even the first 3 vertices of this primitive without going over the matrix limit.
                    // So we need to start a new packet.
                    packetWeights.Clear();
                    numMatrices = 0;
                    Packets.Add(pack);
                    pack = new Packet();
                }


                Primitive prim = new Primitive((Enums.GXPrimitiveType)primbrawl.Type);

                int currvert = -1;
                int maxvert  = primbrawl.Indices.Count - 1;
                Enums.GXPrimitiveType primtype = (Enums.GXPrimitiveType)primbrawl.Type;

                if (primtype == Enums.GXPrimitiveType.TriangleStrip)
                {
                    //Console.WriteLine("Doing Tristrip");
                    foreach (int vertIndex in primbrawl.Indices)
                    {
                        currvert++;
                        Weight vertWeight = weights[vertIndex];

                        int oldmat = numMatrices;
                        if (!packetWeights.Contains(vertWeight))
                        {
                            packetWeights.Add(vertWeight);
                            numMatrices++;
                        }

                        //Console.WriteLine(String.Format("Added {0} matrices, is now {1}", numMatrices - oldmat, numMatrices));

                        // There are too many matrices, we need to create a new packet
                        if (numMatrices > MaxMatricesPerPacket)
                        {
                            // If we break up and the resulting TriStrip becomes invalid,
                            // then we need to handle those cases.

                            //Console.WriteLine(String.Format("Breaking up because over the limit: {0}", numMatrices));

                            if (prim.PrimitiveType == Enums.GXPrimitiveType.TriangleStrip)
                            {
                                Debug.Assert(prim.Vertices.Count >= 3);
                            }
                            else if (prim.PrimitiveType == Enums.GXPrimitiveType.Triangles)
                            {
                                Debug.Assert(prim.Vertices.Count % 3 == 0);
                            }
                            pack.Primitives.Add(prim);


                            Primitive newprim = new Primitive(Enums.GXPrimitiveType.TriangleStrip);
                            Vertex    prev3   = new Vertex(prim.Vertices[prim.Vertices.Count - 3]);
                            Vertex    prev2   = new Vertex(prim.Vertices[prim.Vertices.Count - 2]);
                            Vertex    prev    = new Vertex(prim.Vertices[prim.Vertices.Count - 1]);
                            bool      isOdd   = currvert % 2 != 0;
                            if (isOdd)
                            {
                                // Need to preserve whether each vertex is even or odd inside the triangle strip.
                                // Do this by adding an extra vertex from the previous packet to the start of this one.
                                newprim.Vertices.Add(prev3);
                            }
                            newprim.Vertices.Add(prev2);
                            newprim.Vertices.Add(prev);

                            prim = newprim;

                            packetWeights.Clear();
                            numMatrices = 0;
                            Packets.Add(pack);
                            Packet oldPack = pack;
                            pack = new Packet();

                            // Calculate matrices for current packet in case we added vertices
                            foreach (Vertex vertex in prim.Vertices)
                            {
                                if (!packetWeights.Contains(vertex.VertexWeight))
                                {
                                    packetWeights.Add(vertex.VertexWeight);
                                    numMatrices++;
                                }

                                // Re-add the matrix index for the duplicated verts to the new packet.
                                // And recalculate the matrix index index in each vert's attribute data.
                                uint oldMatrixIndexIndex = vertex.GetAttributeIndex(Enums.GXVertexAttribute.PositionMatrixIdx);
                                int  matrixIndex         = oldPack.MatrixIndices[(int)oldMatrixIndexIndex];

                                if (!pack.MatrixIndices.Contains(matrixIndex))
                                {
                                    pack.MatrixIndices.Add(matrixIndex);
                                }
                                vertex.SetAttributeIndex(Enums.GXVertexAttribute.PositionMatrixIdx, (uint)pack.MatrixIndices.IndexOf(matrixIndex));
                            }

                            if (!packetWeights.Contains(vertWeight))
                            {
                                packetWeights.Add(vertWeight);
                                numMatrices++;
                            }
                        }

                        Vertex vert      = new Vertex();
                        Weight curWeight = vertWeight;

                        vert.SetWeight(curWeight);

                        foreach (Enums.GXVertexAttribute attrib in activeAttribs)
                        {
                            switch (attrib)
                            {
                            case Enums.GXVertexAttribute.PositionMatrixIdx:
                                int newMatrixIndex = -1;

                                if (curWeight.WeightCount == 1)
                                {
                                    newMatrixIndex = partialWeight.MeshWeights.IndexOf(curWeight);
                                }
                                else
                                {
                                    if (!envelopes.Weights.Contains(curWeight))
                                    {
                                        envelopes.Weights.Add(curWeight);
                                    }

                                    int envIndex = envelopes.Weights.IndexOf(curWeight);
                                    int drwIndex = partialWeight.MeshWeights.IndexOf(curWeight);

                                    if (drwIndex == -1)
                                    {
                                        throw new System.Exception($"Model has unweighted vertices in mesh \"{mesh.Name}\". Please weight all vertices to at least one bone.");
                                    }

                                    newMatrixIndex = drwIndex;
                                    partialWeight.Indices[drwIndex] = envIndex;
                                }

                                if (!pack.MatrixIndices.Contains(newMatrixIndex))
                                {
                                    pack.MatrixIndices.Add(newMatrixIndex);
                                }

                                vert.SetAttributeIndex(Enums.GXVertexAttribute.PositionMatrixIdx, (uint)pack.MatrixIndices.IndexOf(newMatrixIndex));
                                break;

                            case Enums.GXVertexAttribute.Position:
                                List <Vector3> posData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Position);
                                Vector3        vertPos = mesh.Vertices[vertIndex].ToOpenTKVector3();

                                if (curWeight.WeightCount == 1)
                                {
                                    Matrix4 ibm = envelopes.InverseBindMatrices[curWeight.BoneIndices[0]];

                                    Vector3 transVec = Vector3.TransformPosition(vertPos, ibm);
                                    if (!posData.Contains(transVec))
                                    {
                                        posData.Add(transVec);
                                    }
                                    AttributeData.Positions.Add(transVec);
                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.Position, (uint)posData.IndexOf(transVec));
                                }
                                else
                                {
                                    if (!posData.Contains(vertPos))
                                    {
                                        posData.Add(vertPos);
                                    }
                                    AttributeData.Positions.Add(vertPos);

                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.Position, (uint)posData.IndexOf(vertPos));
                                }
                                break;

                            case Enums.GXVertexAttribute.Normal:
                                List <Vector3> normData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Normal);
                                Vector3        vertNrm  = mesh.Normals[vertIndex].ToOpenTKVector3();

                                if (curWeight.WeightCount == 1)
                                {
                                    Matrix4 ibm = envelopes.InverseBindMatrices[curWeight.BoneIndices[0]];
                                    vertNrm = Vector3.TransformNormal(vertNrm, ibm);
                                    if (!normData.Contains(vertNrm))
                                    {
                                        normData.Add(vertNrm);
                                    }
                                }
                                else
                                {
                                    if (!normData.Contains(vertNrm))
                                    {
                                        normData.Add(vertNrm);
                                    }
                                }

                                AttributeData.Normals.Add(vertNrm);
                                vert.SetAttributeIndex(Enums.GXVertexAttribute.Normal, (uint)normData.IndexOf(vertNrm));
                                break;

                            case Enums.GXVertexAttribute.Color0:
                            case Enums.GXVertexAttribute.Color1:
                                int          colNo   = (int)attrib - 11;
                                List <Color> colData = (List <Color>)vertData.GetAttributeData(Enums.GXVertexAttribute.Color0 + colNo);
                                Color        vertCol = mesh.VertexColorChannels[colNo][vertIndex].ToSuperBMDColorRGBA();

                                if (colNo == 0)
                                {
                                    AttributeData.Color_0.Add(vertCol);
                                }
                                else
                                {
                                    AttributeData.Color_1.Add(vertCol);
                                }

                                vert.SetAttributeIndex(Enums.GXVertexAttribute.Color0 + colNo, (uint)colData.IndexOf(vertCol));
                                break;

                            case Enums.GXVertexAttribute.Tex0:
                            case Enums.GXVertexAttribute.Tex1:
                            case Enums.GXVertexAttribute.Tex2:
                            case Enums.GXVertexAttribute.Tex3:
                            case Enums.GXVertexAttribute.Tex4:
                            case Enums.GXVertexAttribute.Tex5:
                            case Enums.GXVertexAttribute.Tex6:
                            case Enums.GXVertexAttribute.Tex7:
                                int            texNo        = (int)attrib - 13;
                                List <Vector2> texCoordData = (List <Vector2>)vertData.GetAttributeData(Enums.GXVertexAttribute.Tex0 + texNo);
                                Vector2        vertTexCoord = mesh.TextureCoordinateChannels[texNo][vertIndex].ToOpenTKVector2();
                                vertTexCoord = new Vector2(vertTexCoord.X, 1.0f - vertTexCoord.Y);

                                switch (texNo)
                                {
                                case 0:
                                    AttributeData.TexCoord_0.Add(vertTexCoord);
                                    break;

                                case 1:
                                    AttributeData.TexCoord_1.Add(vertTexCoord);
                                    break;

                                case 2:
                                    AttributeData.TexCoord_2.Add(vertTexCoord);
                                    break;

                                case 3:
                                    AttributeData.TexCoord_3.Add(vertTexCoord);
                                    break;

                                case 4:
                                    AttributeData.TexCoord_4.Add(vertTexCoord);
                                    break;

                                case 5:
                                    AttributeData.TexCoord_5.Add(vertTexCoord);
                                    break;

                                case 6:
                                    AttributeData.TexCoord_6.Add(vertTexCoord);
                                    break;

                                case 7:
                                    AttributeData.TexCoord_7.Add(vertTexCoord);
                                    break;
                                }

                                vert.SetAttributeIndex(Enums.GXVertexAttribute.Tex0 + texNo, (uint)texCoordData.IndexOf(vertTexCoord));
                                break;
                            }
                        }
                        prim.Vertices.Add(vert);
                    }
                }
                else if (primtype == Enums.GXPrimitiveType.Triangles)
                {
                    for (int j = 0; j < primbrawl.Indices.Count / 3; j++)
                    {
                        int    vert1Index  = (int)primbrawl.Indices[j * 3 + 0];
                        int    vert2Index  = (int)primbrawl.Indices[j * 3 + 1];
                        int    vert3Index  = (int)primbrawl.Indices[j * 3 + 2];
                        Weight vert1Weight = weights[vert1Index];
                        Weight vert2Weight = weights[vert2Index];
                        Weight vert3Weight = weights[vert3Index];
                        int    oldcount    = numMatrices;
                        if (!packetWeights.Contains(vert1Weight))
                        {
                            packetWeights.Add(vert1Weight);
                            numMatrices++;
                        }
                        if (!packetWeights.Contains(vert2Weight))
                        {
                            packetWeights.Add(vert2Weight);
                            numMatrices++;
                        }
                        if (!packetWeights.Contains(vert3Weight))
                        {
                            packetWeights.Add(vert3Weight);
                            numMatrices++;
                        }

                        // There are too many matrices, we need to create a new packet
                        if (numMatrices > MaxMatricesPerPacket)
                        {
                            //Console.WriteLine(String.Format("Making new packet because previous one would have {0}", numMatrices));
                            //Console.WriteLine(oldcount);
                            pack.Primitives.Add(prim);
                            Packets.Add(pack);

                            prim = new Primitive(Enums.GXPrimitiveType.Triangles);
                            pack = new Packet();

                            packetWeights.Clear();
                            numMatrices = 0;

                            if (!packetWeights.Contains(vert1Weight))
                            {
                                packetWeights.Add(vert1Weight);
                                numMatrices++;
                            }
                            if (!packetWeights.Contains(vert2Weight))
                            {
                                packetWeights.Add(vert2Weight);
                                numMatrices++;
                            }
                            if (!packetWeights.Contains(vert3Weight))
                            {
                                packetWeights.Add(vert3Weight);
                                numMatrices++;
                            }
                        }

                        int[]    vertexIndexArray = new int[] { vert1Index, vert2Index, vert3Index };
                        Weight[] vertWeightArray  = new Weight[] { vert1Weight, vert2Weight, vert3Weight };

                        for (int i = 0; i < 3; i++)
                        {
                            Vertex vert      = new Vertex();
                            int    vertIndex = vertexIndexArray[i];
                            Weight curWeight = vertWeightArray[i];

                            vert.SetWeight(curWeight);

                            foreach (Enums.GXVertexAttribute attrib in activeAttribs)
                            {
                                switch (attrib)
                                {
                                case Enums.GXVertexAttribute.PositionMatrixIdx:
                                    int newMatrixIndex = -1;

                                    if (curWeight.WeightCount == 1)
                                    {
                                        newMatrixIndex = partialWeight.MeshWeights.IndexOf(curWeight);
                                    }
                                    else
                                    {
                                        if (!envelopes.Weights.Contains(curWeight))
                                        {
                                            envelopes.Weights.Add(curWeight);
                                        }

                                        int envIndex = envelopes.Weights.IndexOf(curWeight);
                                        int drwIndex = partialWeight.MeshWeights.IndexOf(curWeight);

                                        if (drwIndex == -1)
                                        {
                                            throw new System.Exception($"Model has unweighted vertices in mesh \"{mesh.Name}\". Please weight all vertices to at least one bone.");
                                        }

                                        newMatrixIndex = drwIndex;
                                        partialWeight.Indices[drwIndex] = envIndex;
                                    }

                                    if (!pack.MatrixIndices.Contains(newMatrixIndex))
                                    {
                                        pack.MatrixIndices.Add(newMatrixIndex);
                                    }

                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.PositionMatrixIdx, (uint)pack.MatrixIndices.IndexOf(newMatrixIndex));
                                    break;

                                case Enums.GXVertexAttribute.Position:
                                    List <Vector3> posData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Position);
                                    Vector3        vertPos = mesh.Vertices[vertIndex].ToOpenTKVector3();

                                    if (curWeight.WeightCount == 1)
                                    {
                                        Matrix4 ibm = envelopes.InverseBindMatrices[curWeight.BoneIndices[0]];

                                        Vector3 transVec = Vector3.TransformPosition(vertPos, ibm);
                                        if (!posData.Contains(transVec))
                                        {
                                            posData.Add(transVec);
                                        }
                                        AttributeData.Positions.Add(transVec);
                                        vert.SetAttributeIndex(Enums.GXVertexAttribute.Position, (uint)posData.IndexOf(transVec));
                                    }
                                    else
                                    {
                                        if (!posData.Contains(vertPos))
                                        {
                                            posData.Add(vertPos);
                                        }
                                        AttributeData.Positions.Add(vertPos);

                                        vert.SetAttributeIndex(Enums.GXVertexAttribute.Position, (uint)posData.IndexOf(vertPos));
                                    }
                                    break;

                                case Enums.GXVertexAttribute.Normal:
                                    List <Vector3> normData = (List <Vector3>)vertData.GetAttributeData(Enums.GXVertexAttribute.Normal);
                                    Vector3        vertNrm  = mesh.Normals[vertIndex].ToOpenTKVector3();

                                    if (curWeight.WeightCount == 1)
                                    {
                                        Matrix4 ibm = envelopes.InverseBindMatrices[curWeight.BoneIndices[0]];
                                        vertNrm = Vector3.TransformNormal(vertNrm, ibm);
                                        if (!normData.Contains(vertNrm))
                                        {
                                            normData.Add(vertNrm);
                                        }
                                    }
                                    else
                                    {
                                        if (!normData.Contains(vertNrm))
                                        {
                                            normData.Add(vertNrm);
                                        }
                                    }

                                    AttributeData.Normals.Add(vertNrm);
                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.Normal, (uint)normData.IndexOf(vertNrm));
                                    break;

                                case Enums.GXVertexAttribute.Color0:
                                case Enums.GXVertexAttribute.Color1:
                                    int          colNo   = (int)attrib - 11;
                                    List <Color> colData = (List <Color>)vertData.GetAttributeData(Enums.GXVertexAttribute.Color0 + colNo);
                                    Color        vertCol = mesh.VertexColorChannels[colNo][vertIndex].ToSuperBMDColorRGBA();

                                    if (colNo == 0)
                                    {
                                        AttributeData.Color_0.Add(vertCol);
                                    }
                                    else
                                    {
                                        AttributeData.Color_1.Add(vertCol);
                                    }

                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.Color0 + colNo, (uint)colData.IndexOf(vertCol));
                                    break;

                                case Enums.GXVertexAttribute.Tex0:
                                case Enums.GXVertexAttribute.Tex1:
                                case Enums.GXVertexAttribute.Tex2:
                                case Enums.GXVertexAttribute.Tex3:
                                case Enums.GXVertexAttribute.Tex4:
                                case Enums.GXVertexAttribute.Tex5:
                                case Enums.GXVertexAttribute.Tex6:
                                case Enums.GXVertexAttribute.Tex7:
                                    int            texNo        = (int)attrib - 13;
                                    List <Vector2> texCoordData = (List <Vector2>)vertData.GetAttributeData(Enums.GXVertexAttribute.Tex0 + texNo);
                                    Vector2        vertTexCoord = mesh.TextureCoordinateChannels[texNo][vertIndex].ToOpenTKVector2();
                                    vertTexCoord = new Vector2(vertTexCoord.X, 1.0f - vertTexCoord.Y);

                                    switch (texNo)
                                    {
                                    case 0:
                                        AttributeData.TexCoord_0.Add(vertTexCoord);
                                        break;

                                    case 1:
                                        AttributeData.TexCoord_1.Add(vertTexCoord);
                                        break;

                                    case 2:
                                        AttributeData.TexCoord_2.Add(vertTexCoord);
                                        break;

                                    case 3:
                                        AttributeData.TexCoord_3.Add(vertTexCoord);
                                        break;

                                    case 4:
                                        AttributeData.TexCoord_4.Add(vertTexCoord);
                                        break;

                                    case 5:
                                        AttributeData.TexCoord_5.Add(vertTexCoord);
                                        break;

                                    case 6:
                                        AttributeData.TexCoord_6.Add(vertTexCoord);
                                        break;

                                    case 7:
                                        AttributeData.TexCoord_7.Add(vertTexCoord);
                                        break;
                                    }

                                    vert.SetAttributeIndex(Enums.GXVertexAttribute.Tex0 + texNo, (uint)texCoordData.IndexOf(vertTexCoord));
                                    break;
                                }
                            }

                            prim.Vertices.Add(vert);
                        }
                    }
                }

                /*
                 * if (prim.PrimitiveType == Enums.GXPrimitiveType.TriangleStrip) {
                 *  Debug.Assert(prim.Vertices.Count >= 3);
                 * }
                 * else if (prim.PrimitiveType == Enums.GXPrimitiveType.Triangles) {
                 *  Debug.Assert(prim.Vertices.Count % 3 == 0);
                 * }*/
                //Console.WriteLine(String.Format("We had this many matrices: {0}", numMatrices));
                pack.Primitives.Add(prim);
            }
            Packets.Add(pack);

            int mostmatrices = 0;

            if (true)
            {
                List <Weight> packWeights = new List <Weight>();
                foreach (Packet packet in Packets)
                {
                    int matrices = 0;

                    foreach (Primitive prim in packet.Primitives)
                    {
                        foreach (Vertex vert in prim.Vertices)
                        {
                            if (!packWeights.Contains(vert.VertexWeight))
                            {
                                packWeights.Add(vert.VertexWeight);
                                matrices++;
                            }
                        }


                        if (prim.PrimitiveType == Enums.GXPrimitiveType.TriangleStrip)
                        {
                            Debug.Assert(prim.Vertices.Count >= 3);
                        }
                        else if (prim.PrimitiveType == Enums.GXPrimitiveType.Triangles)
                        {
                            Debug.Assert(prim.Vertices.Count % 3 == 0);
                        }
                    }
                    if (matrices > mostmatrices)
                    {
                        mostmatrices = matrices;
                    }
                    //Debug.Assert(matrices <= MaxMatricesPerPacket);
                    //Console.WriteLine(matrices);
                    packWeights.Clear();
                }
            }
            //Console.WriteLine(String.Format("Most matrices: {0}", mostmatrices));
        }
Exemple #4
0
        private void GetPolygons(Dictionary <int, int> matMap)
        {
            var posScale = _imd.Body.ModelInfo.PosScale;
            var rootNode = _imd.Body.NodeArray.Nodes[0];

            var polygonId = 0;

            foreach (var mesh in _meshes)
            {
                var meshId     = mesh.Key;
                var sceneMesh  = _scene.Meshes[meshId];
                var materialId = matMap[sceneMesh.MaterialIndex];
                var material   = _imd.Body.MaterialArray.Materials[materialId];
                var useNormals = material.Light0 == "on" || material.Light1 == "on" || material.Light2 == "on" ||
                                 material.Light3 == "on";

                var texture = material.TexImageIdx != -1
                    ? _imd.Body.TexImageArray.TexImages[material.TexImageIdx]
                    : null;

                var polygon = new Polygon
                {
                    Index   = polygonId,
                    Name    = $"polygon{polygonId}",
                    ClrFlag = !useNormals && sceneMesh.HasVertexColors(0) ? "on" : "off",
                    TexFlag = texture != null ? "on" : "off",
                    NrmFlag = useNormals ? "on" : "off",
                };

                var matrixPrimitive = new MatrixPrimitive
                {
                    Index          = 0,
                    PrimitiveArray = new PrimitiveArray
                    {
                        Primitives = new List <Primitive>()
                    }
                };
                polygon.MatrixPrimitives.Add(matrixPrimitive);

                var finalPrimList = new List <Primitive>();

                var primList = new List <Stripping.Primitive>();
                var posList  = new Dictionary <VecFx32, int>();
                var clrList  = new Dictionary <(int r, int g, int b), int>();
                var texList  = new Dictionary <(int s, int t), int>();
                var nrmList  = new Dictionary <(int x, int y, int z), int>();
                foreach (var face in sceneMesh.Faces)
                {
                    var prim = new Stripping.Primitive();
                    if (face.IndexCount == 3)
                    {
                        prim.Type = Stripping.Primitive.PrimitiveType.Triangles;
                        polygon.TriangleSize++;
                    }
                    else if (face.IndexCount == 4)
                    {
                        prim.Type = Stripping.Primitive.PrimitiveType.Quads;
                        polygon.QuadSize++;
                    }
                    else
                    {
                        continue; //Other shapes????!
                    }
                    polygon.PolygonSize++;

                    foreach (var vertexIndex in face.Indices)
                    {
                        var vertex = _meshes[meshId][vertexIndex];

                        prim.Matrices.Add(-1);

                        //Vertex Colors
                        if (!useNormals && sceneMesh.HasVertexColors(0))
                        {
                            var c   = sceneMesh.VertexColorChannels[0][vertexIndex];
                            var clr = ((int)Math.Round(c.R * 31), (int)Math.Round(c.G * 31), (int)Math.Round(c.B * 31));

                            int clrIdx = clrList.Count;
                            if (clrList.ContainsKey(clr))
                            {
                                clrIdx = clrList[clr];
                            }
                            else
                            {
                                clrList.Add(clr, clrIdx);
                            }
                            prim.Colors.Add(clrIdx);
                        }
                        else
                        {
                            prim.Colors.Add(-1);
                        }

                        //Texture Coordinates
                        if (texture != null)
                        {
                            var texCoord = sceneMesh.TextureCoordinateChannels[0][vertexIndex];
                            var texC     = ((int)Math.Round(texCoord.X * texture.Width * 16),
                                            (int)Math.Round((-texCoord.Y * texture.Height + texture.Height) * 16));

                            int texIdx = texList.Count;
                            if (texList.ContainsKey(texC))
                            {
                                texIdx = texList[texC];
                            }
                            else
                            {
                                texList.Add(texC, texIdx);
                            }
                            prim.TexCoords.Add(texIdx);
                        }
                        else
                        {
                            prim.TexCoords.Add(-1);
                        }

                        //Normals
                        if (useNormals)
                        {
                            var normal = sceneMesh.Normals[vertexIndex];
                            int nx     = (int)Math.Round(normal.X * 512) & 0x3FF;
                            if (nx == 512)
                            {
                                nx--;
                            }
                            int ny = (int)Math.Round(normal.Y * 512) & 0x3FF;
                            if (ny == 512)
                            {
                                ny--;
                            }
                            int nz = (int)Math.Round(normal.Z * 512) & 0x3FF;
                            if (nz == 512)
                            {
                                nz--;
                            }
                            var nrm = (nx, ny, nz);

                            int nrmIdx = nrmList.Count;
                            if (nrmList.ContainsKey(nrm))
                            {
                                nrmIdx = nrmList[nrm];
                            }
                            else
                            {
                                nrmList.Add(nrm, nrmIdx);
                            }
                            prim.Normals.Add(nrmIdx);
                        }
                        else
                        {
                            prim.Normals.Add(-1);
                        }

                        //Vertex
                        var posScaled = vertex >> posScale;

                        int posIdx = posList.Count;
                        if (posList.ContainsKey(posScaled))
                        {
                            posIdx = posList[posScaled];
                        }
                        else
                        {
                            posList.Add(posScaled, posIdx);
                        }
                        prim.Positions.Add(posIdx);
                    }

                    prim.VertexCount = face.IndexCount;
                    primList.Add(prim);
                }

                var poss = posList.Keys.ToArray();
                var clrs = clrList.Keys.ToArray();
                var texs = texList.Keys.ToArray();
                var nrms = nrmList.Keys.ToArray();

                Stripping.Primitive[] newPrims;

                if (_settings.UsePrimitiveStrip)
                {
                    newPrims = QuadStripper.Process(primList.ToArray());
                    newPrims = TriStripper.Process(newPrims);
                }
                else
                {
                    //No stripping
                    newPrims = primList.ToArray();
                }

                //merge all tris and quads
                {
                    var tmp = new List <Stripping.Primitive>(newPrims.Where(a =>
                                                                            a.Type == Stripping.Primitive.PrimitiveType.TriangleStrip ||
                                                                            a.Type == Stripping.Primitive.PrimitiveType.QuadStrip));
                    var tris = new Stripping.Primitive {
                        Type = Stripping.Primitive.PrimitiveType.Triangles
                    };
                    var quads = new Stripping.Primitive {
                        Type = Stripping.Primitive.PrimitiveType.Quads
                    };
                    foreach (var p in newPrims)
                    {
                        if (p.Type == Stripping.Primitive.PrimitiveType.Triangles)
                        {
                            tris.AddVtx(p, 0);
                            tris.AddVtx(p, 1);
                            tris.AddVtx(p, 2);
                        }
                        else if (p.Type == Stripping.Primitive.PrimitiveType.Quads)
                        {
                            quads.AddVtx(p, 0);
                            quads.AddVtx(p, 1);
                            quads.AddVtx(p, 2);
                            quads.AddVtx(p, 3);
                        }
                    }
                    if (tris.VertexCount != 0)
                    {
                        tmp.Add(tris);
                    }
                    if (quads.VertexCount != 0)
                    {
                        tmp.Add(quads);
                    }
                    newPrims = tmp.ToArray();
                }

                Array.Sort(newPrims);

                foreach (var prim in newPrims)
                {
                    var primitive = new Primitive();
                    switch (prim.Type)
                    {
                    case Stripping.Primitive.PrimitiveType.Triangles:
                        primitive.Type = "triangles";
                        break;

                    case Stripping.Primitive.PrimitiveType.Quads:
                        primitive.Type = "quads";
                        break;

                    case Stripping.Primitive.PrimitiveType.TriangleStrip:
                        primitive.Type = "triangle_strip";
                        break;

                    case Stripping.Primitive.PrimitiveType.QuadStrip:
                        primitive.Type = "quad_strip";
                        break;

                    default:
                        throw new Exception("Unexpected primitive type!");
                    }

                    var prevVtx    = new VecFx32();
                    int prevClrIdx = -1;

                    for (int i = 0; i < prim.VertexCount; i++)
                    {
                        if (texture != null)
                        {
                            primitive.Commands.Add(new TextureCoordCommand(texs[prim.TexCoords[i]].s / 16f,
                                                                           texs[prim.TexCoords[i]].t / 16f));
                        }

                        if (useNormals)
                        {
                            primitive.Commands.Add(new NormalCommand((nrms[prim.Normals[i]].x / 512f,
                                                                      nrms[prim.Normals[i]].y / 512f, nrms[prim.Normals[i]].z / 512f)));
                        }
                        else if (!useNormals && sceneMesh.HasVertexColors(0) && prevClrIdx != prim.Colors[i])
                        {
                            primitive.Commands.Add(new ColorCommand(clrs[prim.Colors[i]].r, clrs[prim.Colors[i]].g,
                                                                    clrs[prim.Colors[i]].b));
                            prevClrIdx = prim.Colors[i];
                        }

                        var vtx  = poss[prim.Positions[i]];
                        var diff = vtx - prevVtx;

                        if (i != 0 && diff.X == 0)
                        {
                            primitive.Commands.Add(new PosYzCommand(vtx.ToVector3()));
                        }
                        else if (i != 0 && diff.Y == 0)
                        {
                            primitive.Commands.Add(new PosXzCommand(vtx.ToVector3()));
                        }
                        else if (i != 0 && diff.Z == 0)
                        {
                            primitive.Commands.Add(new PosXyCommand(vtx.ToVector3()));
                        }
                        else if (i != 0 &&
                                 diff.X < 512 && diff.X >= -512 &&
                                 diff.Y < 512 && diff.Y >= -512 &&
                                 diff.Z < 512 && diff.Z >= -512)
                        {
                            primitive.Commands.Add(new PosDiffCommand(diff.ToVector3()));
                        }
                        else if ((vtx.X & 0x3F) == 0 && (vtx.Y & 0x3F) == 0 && (vtx.Z & 0x3F) == 0)
                        {
                            primitive.Commands.Add(new PosShortCommand(vtx.ToVector3()));
                        }
                        else
                        {
                            primitive.Commands.Add(new PosXyzCommand(vtx.ToVector3()));
                        }

                        prevVtx = vtx;

                        polygon.VertexSize++;
                        primitive.VertexSize++;
                    }

                    primitive.Index = finalPrimList.Count;
                    finalPrimList.Add(primitive);
                }

                if (finalPrimList.Count == 0)
                {
                    continue;
                }

                finalPrimList[0].Commands.Insert(0, new MatrixCommand {
                    Index = 0
                });

                matrixPrimitive.PrimitiveArray.Primitives.AddRange(finalPrimList);

                _imd.Body.PolygonArray.Polygons.Add(polygon);
                _imd.Body.OutputInfo.PolygonSize  += polygon.PolygonSize;
                _imd.Body.OutputInfo.TriangleSize += polygon.TriangleSize;
                _imd.Body.OutputInfo.QuadSize     += polygon.QuadSize;
                _imd.Body.OutputInfo.VertexSize   += polygon.VertexSize;

                if (_settings.CompressNodeMode == "unite_combine")
                {
                    rootNode.PolygonSize  += polygon.PolygonSize;
                    rootNode.TriangleSize += polygon.TriangleSize;
                    rootNode.QuadSize     += polygon.QuadSize;
                    rootNode.VertexSize   += polygon.VertexSize;

                    rootNode.Displays.Add(new NodeDisplay
                    {
                        Index    = rootNode.Displays.Count,
                        Polygon  = polygonId,
                        Material = materialId,
                        Priority = 0
                    });
                }
                else
                {
                    //throw new NotSupportedException("Only Compress Node Mode \"unite_combine\" is supported for now");
                }

                polygonId++;
            }
        }