Beispiel #1
0
        public void Parse()
        {
            byte[] data = SrkBinary.GetBytesArray(this.FileName);

            string fileData = Encoding.ASCII.GetString(data);

            fileData = fileData.Replace("xmlns", "whocares");
            this.Document.LoadXml(fileData);


            XmlNodeList materials = this.Document.SelectNodes("//library_materials/material");

            if (materials != null)
            {
                for (int i = 0; i < materials.Count; i++)
                {
                    string materialID = materials[i].SelectNodes("@id")[0].InnerText;
                    string effectID   = materials[i].SelectNodes("instance_effect/@url")[0].InnerText.Remove(0, 1);

                    XmlNode     effectNode   = this.Document.SelectNodes("//library_effects/effect[@id='" + effectID + "']")[0];
                    string      imageID      = "";
                    XmlNodeList surfInitNode = effectNode.SelectNodes("profile_COMMON//surface/init_from");
                    if (surfInitNode != null && surfInitNode.Count > 0)
                    {
                        imageID = surfInitNode[0].InnerText;
                    }

                    XmlNodeList textureNode = effectNode.SelectNodes("profile_COMMON//texture/@texture");
                    if (imageID.Length == 0 && textureNode != null && textureNode.Count > 0)
                    {
                        imageID = textureNode[0].InnerText;
                    }
                    string fileName = this.Document.SelectNodes("//library_images/image[@id='" + imageID + "']/init_from")[0].InnerText;
                    fileName = fileName.Replace("file://", "");
                    fileName = fileName.Replace("../", "");
                    fileName = fileName.Replace("./", "");
                    fileName = fileName.Replace("/", "\\");


                    if (Path.GetExtension(fileName).Length == 0)
                    {
                        string dir         = Path.GetDirectoryName(fileName);
                        bool   notFoundExt = true;
                        if (Directory.Exists(dir))
                        {
                            string[] dirFiles = Directory.GetFiles(dir);
                            for (int d = 0; d < dirFiles.Length; d++)
                            {
                                if (Path.GetFileNameWithoutExtension(dirFiles[d]) == Path.GetFileNameWithoutExtension(fileName))
                                {
                                    fileName   += Path.GetExtension(dirFiles[d]);
                                    notFoundExt = false;
                                    break;
                                }
                            }
                        }
                        if (notFoundExt)
                        {
                            fileName += ".png";
                        }
                    }

                    string[] spli   = fileName.Split('\\');
                    bool     exists = false;

                    string fname = "";
                    if (spli.Length > 0)
                    {
                        fileName = spli[spli.Length - 1];
                        if (File.Exists(this.DirectoryName + @"\" + fileName))
                        {
                            fname  = this.DirectoryName + @"\" + fileName;
                            exists = true;
                        }
                    }

                    if (!exists)
                    {
                        fname  = fileName;
                        exists = true;
                    }

                    this.materialNames.Add(materialID);
                    this.materialFileNames.Add(fname);
                }
            }

            var         wrapnode   = this.Document.SelectNodes("//technique[@profile='MAYA']");
            bool        wrapUV     = wrapnode != null && wrapnode.Count > 0;
            XmlNodeList geometries = this.Document.SelectNodes("//library_geometries/geometry");

            for (int i = 0; i < geometries.Count; i++)
            {
                XmlNode mesh = geometries[i].SelectNodes("mesh")[0];
                this.GeometryIDs.Add(geometries[i].SelectNodes("@id")[0].InnerText);

                XmlNodeList inputs = mesh.SelectNodes("*/input[@semantic]");


                string vertexID   = "";
                string normalID   = "";
                string texcoordID = "";
                string colorID    = "";

                vertexTriInd.Add(-1);
                normalTriInd.Add(-1);
                uvTriInd.Add(-1);
                colorTriInd.Add(-1);
                int stride = 0;
                for (int j = 0; j < inputs.Count; j++)
                {
                    string      semanticAtt = inputs[j].SelectNodes("@semantic")[0].InnerText.ToUpper();
                    XmlNodeList offsetAtt   = inputs[j].SelectNodes("@offset");

                    switch (semanticAtt)
                    {
                    case "VERTEX":
                        vertexTriInd[vertexTriInd.Count - 1] = 0;
                        if (offsetAtt != null && offsetAtt.Count > 0)
                        {
                            vertexTriInd[vertexTriInd.Count - 1] = int.Parse(offsetAtt[0].InnerText);
                            stride++;
                        }
                        break;

                    case "POSITION":
                        vertexID = inputs[j].SelectNodes("@source")[0].InnerText.Remove(0, 1);
                        break;

                    case "NORMAL":
                        normalTriInd[normalTriInd.Count - 1] = 0;
                        if (offsetAtt != null && offsetAtt.Count > 0)
                        {
                            normalTriInd[normalTriInd.Count - 1] = int.Parse(offsetAtt[0].InnerText);
                            stride++;
                        }
                        normalID = inputs[j].SelectNodes("@source")[0].InnerText.Remove(0, 1);
                        break;

                    case "TEXCOORD":
                        uvTriInd[uvTriInd.Count - 1] = 0;
                        if (offsetAtt != null && offsetAtt.Count > 0)
                        {
                            uvTriInd[uvTriInd.Count - 1] = int.Parse(offsetAtt[0].InnerText);
                            stride++;
                        }
                        texcoordID = inputs[j].SelectNodes("@source")[0].InnerText.Remove(0, 1);
                        break;

                    case "COLOR":
                        colorTriInd[colorTriInd.Count - 1] = 0;
                        if (offsetAtt != null && offsetAtt.Count > 0)
                        {
                            colorTriInd[colorTriInd.Count - 1] = int.Parse(offsetAtt[0].InnerText);
                            stride++;
                        }
                        colorID = inputs[j].SelectNodes("@source")[0].InnerText.Remove(0, 1);
                        break;
                    }
                }

                if (vertexID.Length == 0)
                {
                    throw new Exception("Error: Mesh " + i + " does not have vertices. Remove this mesh before to use this tool.");
                }

                string[] vertexArray   = new string[0];
                string[] normalArray   = new string[0];
                string[] texcoordArray = new string[0];
                string[] colorArray    = new string[0];

                if (vertexID.Length > 0)
                {
                    vertexArray = Format(mesh.SelectNodes(@"source[@id='" + vertexID + "']/float_array")[0].InnerText).Split(' ');
                }
                if (normalID.Length > 0)
                {
                    normalArray = Format(mesh.SelectNodes(@"source[@id='" + normalID + "']/float_array")[0].InnerText).Split(' ');
                }
                if (texcoordID.Length > 0)
                {
                    texcoordArray = Format(mesh.SelectNodes(@"source[@id='" + texcoordID + "']/float_array")[0].InnerText).Split(' ');
                }
                if (colorID.Length > 0)
                {
                    colorArray = Format(mesh.SelectNodes(@"source[@id='" + colorID + "']/float_array")[0].InnerText).Split(' ');
                }

                this.Vertices.Add(new List <Vector3>(0));
                this.Normal.Add(new List <Vector3>(0));
                this.TextureCoordinates.Add(new List <Vector2>(0));
                this.VertexColor.Add(new List <byte[]>(0));

                this.Triangle.Add(new List <int[]>(0));

                this.Influences.Add(new List <List <float> >(0));
                this.InfluencesIndices.Add(new List <List <int> >(0));

                for (int j = 0; j < vertexArray.Length; j += 3)
                {
                    float x = Single.Parse(vertexArray[j]);
                    float y = Single.Parse(vertexArray[j + 1]);
                    float z = Single.Parse(vertexArray[j + 2]);

                    if (x > this.MaxCoords.X)
                    {
                        this.MaxCoords.X = x;
                    }
                    if (x < this.MinCoords.X)
                    {
                        this.MinCoords.X = x;
                    }

                    if (y > this.MaxCoords.Y)
                    {
                        this.MaxCoords.Y = y;
                    }
                    if (y < this.MinCoords.Y)
                    {
                        this.MinCoords.Y = y;
                    }

                    if (z > this.MaxCoords.Z)
                    {
                        this.MaxCoords.Z = z;
                    }
                    if (z < this.MinCoords.Z)
                    {
                        this.MinCoords.Z = z;
                    }

                    this.Vertices.Last().Add(new Vector3(x, y, z));
                }

                for (int j = 0; j < normalArray.Length; j += 3)
                {
                    this.Normal.Last().Add(new Vector3(Single.Parse(normalArray[j]), Single.Parse(normalArray[j + 1]), Single.Parse(normalArray[j + 2])));
                }

                for (int j = 0; j < texcoordArray.Length; j += 2)
                {
                    Vector2 uv = new Vector2(Single.Parse(texcoordArray[j]), 1 - Single.Parse(texcoordArray[j + 1]));
                    this.TextureCoordinates.Last().Add(uv);
                }

                for (int j = 0; j < colorArray.Length; j += 4)
                {
                    this.VertexColor.Last().Add(new byte[] {
                        (byte)(Single.Parse(colorArray[j]) * 128),
                        (byte)(Single.Parse(colorArray[j + 1]) * 128),
                        (byte)(Single.Parse(colorArray[j + 2]) * 128),
                        (byte)(Single.Parse(colorArray[j + 3]) * 128)
                    });
                }

                string triangleString = mesh.SelectNodes(@"triangles/p")[0].InnerText;

                string[] triangleArray = Format(triangleString).Split(' ');
                for (int j = 0; j < triangleArray.Length; j += stride)
                {
                    int[] indices = new int[stride];
                    for (int k = 0; k < stride; k++)
                    {
                        indices[k] = int.Parse(triangleArray[j + k]);
                    }

                    this.Triangle.Last().Add(indices);
                }
            }

            var bonesNode = this.Document.SelectNodes(@"//library_visual_scenes/visual_scene//node[@type='JOINT']"); // and not(contains(@name,'mesh'))

            if (bonesNode != null && bonesNode.Count > 0)
            {
                this.Skeleton.Bones           = new Bone[bonesNode.Count];
                this.Skeleton.BonesMatrices   = new Matrix[bonesNode.Count];
                this.Skeleton.BonesReMatrices = new Matrix[bonesNode.Count];

                bonesNode = this.Document.SelectNodes(@"//library_visual_scenes/visual_scene/node[@type='JOINT']");
                for (int i = 0; i < bonesNode.Count; i++)
                {
                    XmlNode bone000 = bonesNode[i];
                    GetBoneNames(bone000);
                    GetBones(bone000);
                    UnwrapSkeleton(bone000, -1);
                }
                ComputeMatrices();
            }

            XmlNodeList skinnings = this.Document.SelectNodes(@"//library_controllers/controller/skin");

            for (int i = 0; i < skinnings.Count; i++)
            {
                var sourceNodes = skinnings[i].SelectNodes("@source");
                if (sourceNodes == null || sourceNodes.Count == 0)
                {
                    continue;
                }
                int geometryIndex = this.GeometryIDs.IndexOf(sourceNodes[0].InnerText.Remove(0, 1));
                if (geometryIndex < 0)
                {
                    continue;
                }

                string   jointID      = skinnings[i].SelectNodes(@"*/input[@semantic='JOINT']/@source")[0].InnerText.Remove(0, 1);
                string[] jointsArray  = Format(skinnings[i].SelectNodes(@"source[@id='" + jointID + "']/Name_array")[0].InnerText).Split(' ');
                string[] skinCounts   = Format(skinnings[i].SelectNodes(@"vertex_weights/vcount")[0].InnerText).Split(' ');
                string[] skins        = Format(skinnings[i].SelectNodes(@"vertex_weights/v")[0].InnerText).Split(' ');
                string[] skinsWeights = Format(skinnings[i].SelectNodes(@"source[contains(@id, 'eights')]/float_array")[0].InnerText).Split(' ');

                int tabIndex = 0;

                for (int j = 0; j < skinCounts.Length; j++)
                {
                    int influenceCount = int.Parse(skinCounts[j]);

                    this.Influences[geometryIndex].Add(new List <float>(0));
                    this.InfluencesIndices[geometryIndex].Add(new List <int>(0));

                    for (int k = 0; k < influenceCount; k++)
                    {
                        int   jointIndex  = int.Parse(skins[tabIndex]);
                        int   weightIndex = int.Parse(skins[tabIndex + 1]);
                        float weight      = Single.Parse(skinsWeights[weightIndex]);

                        string jointName = jointsArray[jointIndex];

                        this.Influences[geometryIndex].Last().Add(weight);
                        this.InfluencesIndices[geometryIndex].Last().Add(BoneNames.IndexOf(jointName));

                        tabIndex += 2;
                    }
                }
            }

            List <string> materialsFnames = new List <string>(0);

            for (int i = 0; i < this.Triangle.Count; i++)
            {
                string currController = "";
                for (int l = 0; l < skinnings.Count; l++)
                {
                    var node = skinnings[l].SelectNodes("@source");
                    if (node != null && node.Count > 0 && node[0].InnerText == "#" + this.GeometryIDs[i])
                    {
                        node = skinnings[l].ParentNode.SelectNodes("@id");
                        if (node != null && node.Count > 0)
                        {
                            currController = node[0].InnerText;
                            break;
                        }
                    }
                }
                string matID = "";
                if (matID.Length == 0)
                {
                    XmlNodeList instanceGeometry = this.Document.SelectNodes("//library_visual_scenes/visual_scene/node/instance_geometry[@url='#" + GeometryIDs[i] + "']//instance_material/@target");
                    if (instanceGeometry != null && instanceGeometry.Count > 0)
                    {
                        matID = instanceGeometry[0].InnerText.Remove(0, 1);
                        if (!materialNames.Contains(matID))
                        {
                            matID = "";
                        }
                    }
                }
                if (matID.Length == 0)
                {
                    XmlNodeList instanceController = this.Document.SelectNodes("//library_visual_scenes/visual_scene/node/instance_controller[@url='#" + currController + "']//instance_material/@target");
                    if (instanceController != null && instanceController.Count > 0)
                    {
                        matID = instanceController[0].InnerText.Remove(0, 1);
                        if (!materialNames.Contains(matID))
                        {
                            matID = "";
                        }
                    }
                }

                if (matID.Length > 0)
                {
                    string fname          = materialFileNames[materialNames.IndexOf(matID)];
                    int    mmaterialIndex = materialsFnames.Count;

                    if (!materialsFnames.Contains(fname))
                    {
                        materialsFnames.Add(fname);
                    }
                    else
                    {
                        mmaterialIndex = materialsFnames.IndexOf(fname);
                    }
                    MaterialIndices.Add(mmaterialIndex);
                }
            }
            this.RenderBuffer = new VertexPositionColorTexture[this.Triangle.Count][];
            for (int i = 0; i < this.RenderBuffer.Length; i++)
            {
                this.RenderBuffer[i] = new VertexPositionColorTexture[this.Triangle[i].Count];
                for (int j = 0; j < this.RenderBuffer[i].Length; j++)
                {
                    this.RenderBuffer[i][j] = new VertexPositionColorTexture();
                }
            }
        }