private void LoadAnim(ResU.VisibilityAnim vis) { VisibilityAnimU = vis; FrameCount = vis.FrameCount; Text = vis.Name; if (vis.BaseDataList == null) { vis.BaseDataList = new bool[0]; } if (vis.Names == null) { vis.Names = new string[0]; } BaseValues = vis.BaseDataList; foreach (var name in vis.Names) { BoneNames.Add(name); } for (int curve = 0; curve < vis.Curves.Count; curve++) { Values.Add(CurveHelper.CreateBooleanTrackWiiU(vis.Curves[curve])); } }
private void LoadAnim(VisibilityAnim vis) { VisibilityAnim = vis; FrameCount = vis.FrameCount; Text = vis.Name; if (vis.BaseDataList == null) { vis.BaseDataList = new bool[0]; } if (vis.Names == null) { vis.Names = new string[0]; } BaseValues = vis.BaseDataList; foreach (var name in vis.Names) { BoneNames.Add(name); } for (int curve = 0; curve < vis.Curves.Count; curve++) { var track = CurveHelper.CreateBooleanTrack(vis.Curves[curve]); track.Text = BoneNames[(int)track.AnimDataOffset]; Values.Add(track); } }
private void ExportB1Button_Click(object sender, EventArgs e) { if (BoneNames.Any()) { File.WriteAllLines(modelName + "_bones.txt", BoneNames); MessageBox.Show($"File saved as \"" + modelName + "_bones.txt" + "\" in the program's directory.", $"Success"); } }
public SkinBinding Bake(Dictionary <string, Bone> bones, Dictionary <string, Bone> selfBones) { List <Bone> boneList = BoneNames .Select(name => ResolveName(bones, selfBones, name)) .Select(name => bones[name]).ToList(); return(new SkinBinding(boneList, BoneWeights, FaceGroupToNodeMap)); }
//public void SetIndex(string boneName, int boneIndex) //{ // BoneNames[boneName] = boneIndex; //} /// <summary> /// Gets the bone index for a given bone name. /// </summary> /// <param name="boneName">The name of the bone.</param> /// <returns> /// The bone index, or -1 if no bone with this name exists. /// </returns> public int GetIndex(string boneName) { int boneIndex; if (!BoneNames.TryGetValue(boneName, out boneIndex)) { return(-1); } return(boneIndex); }
public int GetBoneIndexByName(string name) { for (int i = 0; i < BoneNames.Count(); i++) { if (BoneNames[i] == name) { return(i); } } return(-1); }
internal override void Write(BinaryWriterEx bw) { Entries entries; entries.Models = Models.GetEntries(); List <Event> events = Events.GetEntries(); entries.Regions = Regions.GetEntries(); List <Route> routes = Routes.GetEntries(); entries.Parts = Parts.GetEntries(); foreach (Event evt in events) { evt.GetIndices(entries); } foreach (Region region in entries.Regions) { region.GetIndices(entries); } foreach (Part part in entries.Parts) { part.GetIndices(this, entries); } bw.WriteASCII("MSB "); bw.WriteInt32(1); bw.WriteInt32(0x10); bw.WriteBoolean(false); bw.WriteBoolean(false); bw.WriteByte(1); bw.WriteByte(0xFF); Models.Write(bw, entries.Models); bw.FillInt64("NextParamOffset", bw.Position); Events.Write(bw, events); bw.FillInt64("NextParamOffset", bw.Position); Regions.Write(bw, entries.Regions); bw.FillInt64("NextParamOffset", bw.Position); Routes.Write(bw, routes); bw.FillInt64("NextParamOffset", bw.Position); Layers.Write(bw, Layers.GetEntries()); bw.FillInt64("NextParamOffset", bw.Position); Parts.Write(bw, entries.Parts); bw.FillInt64("NextParamOffset", bw.Position); PartsPoses.Write(bw, Layers.GetEntries()); bw.FillInt64("NextParamOffset", bw.Position); BoneNames.Write(bw, Layers.GetEntries()); bw.FillInt64("NextParamOffset", 0); }
public SklData0(SklHeader header, BinaryReader reader) : base(header, reader) { int un = reader.ReadInt16(); int boneCount = reader.ReadInt16(); int boneIndexCount = reader.ReadInt32(); this.Bones = new SklBoneData0[boneCount]; this.bonesStart = reader.ReadInt32(); this.animationStart = reader.ReadInt32(); this.boneIndicesStart = reader.ReadInt32(); this.boneIndicesEnd = reader.ReadInt32(); this.halfayBetweenBoneindicesAndStrings = reader.ReadInt32(); this.boneNamesStart = reader.ReadInt32(); var gap = reader.ReadBytes(20); for (int i = 0; i < boneCount; i++) { Bones[i] = new SklBoneData0(reader); } this.BoneExtra = new SklBoneExtra[boneCount]; for (int i = 0; i < boneCount; i++) { this.BoneExtra[i] = new SklBoneExtra(reader); } reader.BaseStream.Seek(boneNamesStart, SeekOrigin.Begin); for (int i = 0; i < boneCount; i++) { string name = ""; string c = ""; do { c = new string(reader.ReadChars(4)); name += c; }while (c.IndexOf('\0') == -1); BoneNames.Add(name.Substring(0, name.IndexOf('\0'))); } foreach (var item in this.Bones) { item.Name = BoneNames[item.Id]; } }
public void XfbinClose(int xfbinNo) { BoneIDs.Clear(); BoneNames.Clear(); bones1Label.Text = "No bones loaded"; if (xfbinNo == 1) { mesh1Box.Items.Clear(); xfbin1Box.Text = ""; mesh1IndexLabel.Text = ""; group1Label.Text = ""; groups1Label.Text = ""; mat1Label.Text = ""; formatByte1Label.Text = ""; meshCount1 = 0; if (xfbin1Open) { file1Bytes.Clear(); meshList1.Clear(); xfbin1Groups.Clear(); groupsBox.Items.Clear(); } xfbin1Open = false; } else if (xfbinNo == 2) { mesh2Box.Items.Clear(); xfbin2Box.Text = ""; mesh2IndexLabel.Text = ""; group2Label.Text = ""; groups2Label.Text = ""; mat2Label.Text = ""; formatByte2Label.Text = ""; meshCount2 = 0; if (xfbin2Open) { file2Bytes.Clear(); meshList2.Clear(); xfbin2Groups.Clear(); } xfbin2Open = false; nudOpen = false; } }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <summary> /// Initializes the skeleton. /// </summary> /// <param name="boneParents">The bone parents.</param> /// <param name="boneNames">The bone names.</param> /// <param name="bindPosesRelative">The bind poses.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="boneParents"/>, <paramref name="boneNames"/> or /// <paramref name="bindPosesRelative"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// Either the given lists are empty, have different length, or the /// <paramref name="boneParents"/> are invalid (parent bones must come be before their child /// bones). /// </exception> internal void Initialize(IList <int> boneParents, IList <string> boneNames, IList <SrtTransform> bindPosesRelative) { if (boneParents == null) { throw new ArgumentNullException("boneParents"); } if (boneNames == null) { throw new ArgumentNullException("boneNames"); } if (bindPosesRelative == null) { throw new ArgumentNullException("bindPosesRelative"); } var numberOfBones = boneParents.Count; if (numberOfBones == 0) { throw new ArgumentException("boneParents list must not be empty."); } if (boneNames.Count == 0) { throw new ArgumentException("boneNames list must not be empty."); } if (bindPosesRelative.Count == 0) { throw new ArgumentException("bindPosesRelative list must not be empty."); } if (numberOfBones != boneNames.Count || numberOfBones != bindPosesRelative.Count) { throw new ArgumentException("The lists must have the same number of elements."); } // Check if bone parents come before children. This ordering also forbids cycles. for (int index = 0; index < numberOfBones; index++) { var parentIndex = boneParents[index]; if (parentIndex >= index) { throw new ArgumentException("Invalid boneParents list. Parent bones must have a lower index than child bones."); } } // Build list of bone nodes. Bones = new Bone[numberOfBones]; var children = new List <int>(); for (int index = 0; index < numberOfBones; index++) { Bone bone = new Bone(); // Set parent index. int parentIndex = boneParents[index]; if (parentIndex < -1) { parentIndex = -1; } bone.Parent = parentIndex; // Create array of child indices. children.Clear(); for (int childIndex = index + 1; childIndex < numberOfBones; childIndex++) { if (boneParents[childIndex] == index) { children.Add(childIndex); } } if (children.Count > 0) { bone.Children = children.ToArray(); } Bones[index] = bone; } // Initialize bone name/index dictionary. if (BoneNames == null) { BoneNames = new Dictionary <string, int>(numberOfBones); } else { BoneNames.Clear(); } for (int index = 0; index < numberOfBones; index++) { var name = boneNames[index]; if (name != null) { BoneNames[name] = index; } } // Copy relative bind poses. if (BindPosesRelative == null) { BindPosesRelative = new SrtTransform[numberOfBones]; } for (int index = 0; index < numberOfBones; index++) { BindPosesRelative[index] = bindPosesRelative[index]; } // Initialize absolute bind poses (inverse). if (BindPosesAbsoluteInverse == null) { BindPosesAbsoluteInverse = new SrtTransform[numberOfBones]; } // First store the non-inverted BindTransforms in model space. BindPosesAbsoluteInverse[0] = BindPosesRelative[0]; for (int index = 1; index < numberOfBones; index++) { var parentIndex = Bones[index].Parent; //BindPosesAbsoluteInverse[index] = BindPosesAbsoluteInverse[parentIndex] * BindPosesRelative[index]; SrtTransform.Multiply(ref BindPosesAbsoluteInverse[parentIndex], ref BindPosesRelative[index], out BindPosesAbsoluteInverse[index]); } // Invert matrices. for (int index = 0; index < numberOfBones; index++) { BindPosesAbsoluteInverse[index].Invert(); } }
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++; } } }
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(); } } }
/// <summary> /// Gets the index of the bone. /// </summary> public int GetBone(string boneName) { return(BoneNames.IndexOf(boneName)); }
public static bool XfbinOpen(int xfbinNo, string xfbinPath) { byte[] fileBytes = File.ReadAllBytes(xfbinPath); List <NUD> meshList = new List <NUD>(); List <string> Lines = new List <string>(); int meshCount = 0; searchResults = SearchForByte("NDP3", fileBytes, 0, fileBytes.Length, 0); if (!searchResults.Any()) { MessageBox.Show($"Xfbin doesn't contain any meshes. Please select a valid xfbin.", $"Error"); return(false); } // Find the group names + arrange them if (SearchForByte("trall", fileBytes, 0, fileBytes.Length, 1).Any()) { int end = SearchForByte("trall", fileBytes, 0, fileBytes.Length, 1)[0]; string modelName = ""; int t = 0x20; int boneStart = 0; while (t <= 0x20 && t > 0) { modelName = Encoding.Default.GetString(fileBytes, end - t, 0x20); modelName = modelName.Remove(modelName.IndexOf("\0")); if (modelName.Contains("trall")) { for (int n = 0; n <= 0x20; n++) { if (fileBytes[end - t - n] == 0x00) { boneStart = end - t - n + 1; modelName = Encoding.Default.GetString(fileBytes, boneStart, 0x20); modelName = modelName.Remove(modelName.IndexOf("t0 trall")) + "bod1"; // xchr01bod1 n = 0x21; } } t = 0x21; } else { t -= 0x08; } } int groupStart = 0; int x = 0; bool isStorm = false; for (int n = 0; n >= 0; n++) { try { groupStart = SearchForByte(modelName, fileBytes, boneStart - x, 0, 1)[0]; } catch { isStorm = true; modelName = modelName.Remove(4, 2); // hack for nsuns models, ex: xchrbod1 groupStart = SearchForByte(modelName, fileBytes, boneStart - x, 0, 1)[0]; } x = boneStart - groupStart + 1; if (fileBytes[groupStart + modelName.Length] == 0) { n = -2; } } byte[] groupNames = new byte[boneStart - groupStart]; Array.Copy(fileBytes, groupStart, groupNames, 0, boneStart - groupStart); for (int o = 0; o < groupNames.Length; o++) { if (groupNames[o] == 0x00) { groupNames[o] = 0x0A; } } string tx = Encoding.ASCII.GetString(groupNames); Lines = tx.Split('\n').ToList(); Lines.RemoveAt(0); Lines.RemoveAt(Lines.Count - 1); foreach (string s in Lines.ToList()) { if (s.Contains(" ")) { Lines.Remove(s); } else { if (isStorm) { Lines[Lines.IndexOf(s)] = s.Remove(0, modelName.Length - 4); } else { Lines[Lines.IndexOf(s)] = s.Remove(0, modelName.Length + 1); } } } } // Read each mesh in the xfbin for (int i = 0; i < searchResults.Count; i++) { meshList.Add(LoadNud(fileBytes, searchResults[i], true)); meshCount++; } // Set each group name to its byte List <Group> groupBytes = new List <Group>(); foreach (NUD mesh in meshList) { for (int a = 0; a < mesh.GroupCount; a++) { if (!groupBytes.Any(g => g.EndByte == mesh.GroupBytes[a].EndByte)) { groupBytes.Add(mesh.GroupBytes[a]); } } } if (Lines.Any()) { try { foreach (Group g in groupBytes) { g.Name = Lines[groupBytes.IndexOf(g)]; } } catch { } } List <int> BoneIDs3 = BoneIDs; // Set the bone names obtained from the animation file if (BoneNames.Any()) { List <string> names = new List <string>(); for (int b = 0; b < BoneIDs.Last(); b++) { names.Add(BoneNames[b]); } BoneNames = names; } // Dynamically set the properties for each xfbin if (xfbinNo == 1) { xfbin1Open = true; xfbin1Path = xfbinPath; file1Bytes = fileBytes.ToList(); meshCount1 = meshCount; meshList1 = meshList; xfbin1Groups = groupBytes; } else if (xfbinNo == 2) { xfbin2Open = true; xfbin2Path = xfbinPath; file2Bytes = fileBytes.ToList(); meshCount2 = meshCount; meshList2 = meshList; xfbin2Groups = groupBytes; } return(true); }
internal void Read(EndianBinaryReader reader) { int osageNameCount = reader.ReadInt32(); int osageBoneCount = reader.ReadInt32(); reader.SeekCurrent(4); long osageBonesOffset = reader.ReadOffset(); long osageNamesOffset = reader.ReadOffset(); long exBlocksOffset = reader.ReadOffset(); int boneNameCount = reader.ReadInt32(); long boneNamesOffset = reader.ReadOffset(); long exEntriesOffset = reader.ReadOffset(); reader.ReadAtOffset(osageBonesOffset, () => { OsageBones.Capacity = osageBoneCount; for (int i = 0; i < osageBoneCount; i++) { var osageBone = new ExOsageBoneEntry(); osageBone.Read(reader); OsageBones.Add(osageBone); } }); reader.ReadAtOffset(osageNamesOffset, () => { OsageNames.Capacity = osageNameCount; for (int i = 0; i < osageNameCount; i++) { OsageNames.Add(reader.ReadStringOffset(StringBinaryFormat.NullTerminated)); } }); reader.ReadAtOffset(exBlocksOffset, () => { while (true) { string exBlockSignature = reader.ReadStringOffset(StringBinaryFormat.NullTerminated); long exBlockDataOffset = reader.ReadOffset(); if (exBlockDataOffset == 0) { break; } ExBlock exBlock = null; reader.ReadAtOffset(exBlockDataOffset, () => { switch (exBlockSignature) { case "OSG": exBlock = new ExBlockOsage(); break; case "EXP": exBlock = new ExBlockExpression(); break; case "MOT": exBlock = new ExBlockMotion(); break; case "CNS": exBlock = new ExBlockConstraint(); break; default: Debug.WriteLine($"WARNING: Unknown ex-block type {exBlockSignature}"); break; } if (exBlock != null) { exBlock.Read(reader); ExBlocks.Add(exBlock); } }); } }); reader.ReadAtOffset(boneNamesOffset, () => { BoneNames.Capacity = boneNameCount; for (int i = 0; i < boneNameCount; i++) { BoneNames.Add(reader.ReadStringOffset(StringBinaryFormat.NullTerminated)); } }); reader.ReadAtOffset(exEntriesOffset, () => { while (true) { var exEntry = new ExEntry(); exEntry.Read(reader); if (exEntry.Field00 == 0) { break; } Entries.Add(exEntry); } }); }
internal void Read(EndianBinaryReader reader) { int osageNameCount = reader.ReadInt32(); int osageBoneCount = reader.ReadInt32(); reader.SeekCurrent(4); long osageBonesOffset = reader.ReadOffset(); long osageNamesOffset = reader.ReadOffset(); long nodesOffset = reader.ReadOffset(); int boneNameCount = reader.ReadInt32(); long boneNamesOffset = reader.ReadOffset(); long entriesOffset = reader.ReadOffset(); reader.ReadAtOffset(osageBonesOffset, () => { OsageBones.Capacity = osageBoneCount; for (int i = 0; i < osageBoneCount; i++) { var osageBone = new ExOsageBone(); osageBone.Read(reader); OsageBones.Add(osageBone); } }); reader.ReadAtOffset(osageNamesOffset, () => { OsageNames.Capacity = osageNameCount; for (int i = 0; i < osageNameCount; i++) { OsageNames.Add(reader.ReadStringOffset(StringBinaryFormat.NullTerminated)); } }); reader.ReadAtOffset(nodesOffset, () => { while (true) { string nodeSignature = reader.ReadStringOffset(StringBinaryFormat.NullTerminated); long nodeOffset = reader.ReadOffset(); if (nodeOffset == 0) { break; } reader.ReadAtOffset(nodeOffset, () => { if (!ExNode.NodeFactory.TryGetValue(nodeSignature, out var nodeConstructor)) { return; } var node = nodeConstructor(); node.Read(reader); Nodes.Add(node); }); } }); reader.ReadAtOffset(boneNamesOffset, () => { BoneNames.Capacity = boneNameCount; for (int i = 0; i < boneNameCount; i++) { BoneNames.Add(reader.ReadStringOffset(StringBinaryFormat.NullTerminated)); } }); reader.ReadAtOffset(entriesOffset, () => { while (true) { var entry = new ExEntry(); entry.Read(reader); if (entry.Field00 == 0) { break; } Entries.Add(entry); } }); }
public BoneKeyFrameGroup(BoneNames name) { Name = name; }