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(); } } }
public void SaveData() { if (!IsEdited) //Use original data instead of generic data from editors { return; } if (VisibilityAnimU != null) { VisibilityAnimU.Name = Text; VisibilityAnimU.Names = BoneNames; VisibilityAnimU.Path = ""; } else { VisibilityAnim.Name = Text; VisibilityAnim.Names = BoneNames; VisibilityAnim.Path = ""; VisibilityAnim.FrameCount = FrameCount; VisibilityAnim.BaseDataList = new bool[BoneNames.Count]; int boneIndex = 0; foreach (BooleanKeyGroup value in Values) { if (!value.Constant) { AnimCurve curve = new AnimCurve(); curve.AnimDataOffset = (uint)BoneNames.IndexOf(value.Text); curve.Scale = value.Scale; curve.Offset = value.Offset; curve.KeyType = AnimCurveKeyType.SByte; curve.FrameType = CurveHelper.GetFrameType((uint)FrameCount); curve.CurveType = AnimCurveType.StepBool; if (IsBaked) { curve.CurveType = AnimCurveType.BakedBool; } curve.Delta = value.Delta; curve.EndFrame = value.EndFrame; curve.StartFrame = value.StartFrame; List <bool> KeyBooleans = new List <bool>(); List <float> KeyFrames = new List <float>(); for (int frame = 0; frame < value.Keys.Count; frame++) { bool currentValue = value.Keys[frame].Visible; float currentFrame = value.Keys[frame].Frame; if (frame > 0) { bool previousValue = value.Keys[frame - 1].Visible; if (previousValue != currentValue) { KeyFrames.Add(currentFrame); KeyBooleans.Add(currentValue); } } else { KeyFrames.Add(currentFrame); KeyBooleans.Add(currentValue); VisibilityAnim.BaseDataList[boneIndex] = currentValue; } } curve.KeyStepBoolData = KeyBooleans.ToArray(); for (int frame = 0; frame < FrameCount; frame++) { } } else { //Else for constant types it's only base values } boneIndex++; } } }
/// <summary> /// Gets the index of the bone. /// </summary> public int GetBone(string boneName) { return(BoneNames.IndexOf(boneName)); }