static void CheckAnimName(string animName, Boolean patchAnim = false) { string hashName = string.Format("{0:x}", HashUtil.Hash(animName)); string hashFilePath = greyhoundExportFolder + "\\xanims\\xanim_" + hashName + ".seanim"; if (File.Exists(hashFilePath)) { Console.WriteLine("Found asset: {0:x}", animName.PadRight(40) + hashName); File.AppendAllText(greyhoundExportFolder + "\\AnimsFound.txt", hashName + "," + animName + Environment.NewLine); string destFileName = greyhoundExportFolder + "\\xanims\\" + animName + ".seanim"; File.Copy(hashFilePath, destFileName, true); if (patchAnim) { SEAnim seAnim = SEAnim.Read(destFileName); seAnim.AnimType = AnimationType.Absolute; seAnim.AnimationBoneModifiers["tag_weapon"] = AnimationType.Relative; seAnim.AnimationBoneModifiers["tag_weapon_le"] = AnimationType.Relative; seAnim.Write(destFileName, false); } } }
/// <summary> /// Goes through each anim bone and compares it to the joints specified by user /// </summary> private void DoAnimScan() { for (int i = 0; i < file_paths.Count; i++) { outputTextbox.Invoke(new Action(() => outputTextbox.AppendText("Reading " + System.IO.Path.GetFileNameWithoutExtension(file_paths.ElementAt(i)) + " .... \n"))); bool isCorrectAnim = ReadSEanimForJoint(SEAnim.Read(file_paths.ElementAt(i))); if (isCorrectAnim) { if (!System.IO.Directory.Exists(ExportDirectory)) { System.IO.Directory.CreateDirectory(ExportDirectory); } System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(ExportDirectory); System.IO.File.Move(@file_paths.ElementAt(i), ExportDirectory + System.IO.Path.GetFileName(file_paths.ElementAt(i))); file_paths.RemoveAt(i); //Remove the anim , then lower I to make sure to get the last element animList.Invoke(new Action(() => animList.Items.RemoveAt(i--))); //Add file name to the UI list } progressBar.Invoke(new Action(() => progressBar.Increment(1))); //Increments the progress bar to inform the user how long till it's done } System.Windows.Forms.MessageBox.Show("Scan has been completed, anims can be found in \"SEanimations\" "); ScanInProgress = false; }
public static Animation Read(string FileName, STSkeleton skeleton) { Animation anim = new Animation(); var seanim = SEAnim.Read(FileName); anim.FrameCount = seanim.FrameCount; anim.CanLoop = seanim.Looping; foreach (var bone in seanim.Bones) { STBone genericBone = skeleton.GetBone(bone); if (genericBone != null) { var boneAnim = new Animation.KeyNode(bone); boneAnim.RotType = Animation.RotationType.EULER; boneAnim.UseSegmentScaleCompensate = false; anim.Bones.Add(boneAnim); float PositionX = 0; float PositionY = 0; float PositionZ = 0; float RotationX = 0; float RotationY = 0; float RotationZ = 0; float ScaleX = 0; float ScaleY = 0; float ScaleZ = 0; if (seanim.AnimType == AnimationType.Relative) { PositionX = genericBone.position[0]; PositionY = genericBone.position[1]; PositionZ = genericBone.position[2]; RotationX = genericBone.rotation[0]; RotationY = genericBone.rotation[1]; RotationZ = genericBone.rotation[2]; ScaleX = genericBone.scale[0]; ScaleY = genericBone.scale[1]; ScaleZ = genericBone.scale[2]; } System.Console.WriteLine(bone); if (seanim.AnimationPositionKeys.ContainsKey(bone)) { var translationKeys = seanim.AnimationPositionKeys[bone]; foreach (SEAnimFrame animFrame in translationKeys) { System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).X); System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Y); System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Z); boneAnim.XPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + PositionX, Frame = animFrame.Frame, }); boneAnim.YPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + PositionY, Frame = animFrame.Frame, }); boneAnim.ZPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + PositionZ, Frame = animFrame.Frame, }); } } if (seanim.AnimationRotationKeys.ContainsKey(bone)) { var rotationnKeys = seanim.AnimationRotationKeys[bone]; foreach (SEAnimFrame animFrame in rotationnKeys) { var quat = ((SELib.Utilities.Quaternion)animFrame.Data); var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W); System.Console.WriteLine(animFrame.Frame + " R " + euler.X); System.Console.WriteLine(animFrame.Frame + " R " + euler.Y); System.Console.WriteLine(animFrame.Frame + " R " + euler.Z); boneAnim.XROT.Keys.Add(new Animation.KeyFrame() { Value = euler.X + RotationX, Frame = animFrame.Frame, }); boneAnim.YROT.Keys.Add(new Animation.KeyFrame() { Value = euler.Y + RotationY, Frame = animFrame.Frame, }); boneAnim.ZROT.Keys.Add(new Animation.KeyFrame() { Value = euler.Z + RotationZ, Frame = animFrame.Frame, }); } } if (seanim.AnimationScaleKeys.ContainsKey(bone)) { var scaleKeys = seanim.AnimationScaleKeys[bone]; foreach (SEAnimFrame animFrame in scaleKeys) { System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).X); System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Y); System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Z); boneAnim.XSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + ScaleX, Frame = animFrame.Frame, }); boneAnim.YSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + ScaleY, Frame = animFrame.Frame, }); boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + ScaleZ, Frame = animFrame.Frame, }); } } else { boneAnim.XSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); boneAnim.YSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); } } } return(anim); }
/// <summary> /// /// </summary> /// <param name="FileName"></param> /// <param name="skeleton"></param> /// <returns></returns> public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton) { SEAnim anim = SEAnim.Read(FileName); var sbAnim = new SBAnimation(); sbAnim.FrameCount = anim.FrameCount; sbAnim.Name = anim.DeltaTagName; Dictionary <string, SBTransformAnimation> nameToAnim = new Dictionary <string, SBTransformAnimation>(); foreach (var v in anim.AnimationPositionKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Vector2 vc) { a.AddKey(k.Frame, (float)vc.X, SBTrackType.TranslateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Y, SBTrackType.TranslateY, InterpolationType.Linear); } if (k.Data is SELib.Utilities.Vector3 vc3) { a.AddKey(k.Frame, (float)vc3.X, SBTrackType.TranslateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.TranslateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.TranslateZ, InterpolationType.Linear); } } } foreach (var v in anim.AnimationRotationKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Quaternion q) { var euler = Tools.CrossMath.ToEulerAngles(new OpenTK.Quaternion((float)q.X, (float)q.Y, (float)q.Z, (float)q.W).Inverted()); a.AddKey(k.Frame, (float)q.X, SBTrackType.RotateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.Y, SBTrackType.RotateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.Z, SBTrackType.RotateZ, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.W, SBTrackType.RotateW, InterpolationType.Linear); } if (k.Data is SELib.Utilities.Vector3 vc) { a.AddKey(k.Frame, (float)vc.X, SBTrackType.RotateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Y, SBTrackType.RotateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Z, SBTrackType.RotateZ, InterpolationType.Linear); } } } foreach (var v in anim.AnimationScaleKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Vector3 vc3) { a.AddKey(k.Frame, (float)vc3.X, SBTrackType.ScaleX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.ScaleY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.ScaleZ, InterpolationType.Linear); } } } return(sbAnim); }
public void FromSeanim(string FileName) { SEAnim anim = SEAnim.Read(FileName); if (GetResFileU() != null) { SkeletalAnimU = new ResU.SkeletalAnim(); SkeletalAnimU.FrameCount = anim.FrameCount; SkeletalAnimU.FlagsScale = ResU.SkeletalAnimFlagsScale.Maya; SkeletalAnimU.FlagsRotate = ResU.SkeletalAnimFlagsRotate.EulerXYZ; SkeletalAnimU.Loop = anim.Looping; SkeletalAnimU.Name = System.IO.Path.GetFileNameWithoutExtension(FileName); SkeletalAnimU.Path = ""; } else { SkeletalAnim = new SkeletalAnim(); SkeletalAnim.FrameCount = anim.FrameCount; SkeletalAnim.FlagsScale = SkeletalAnimFlagsScale.Maya; SkeletalAnim.FlagsRotate = SkeletalAnimFlagsRotate.EulerXYZ; SkeletalAnim.Loop = anim.Looping; SkeletalAnim.Name = System.IO.Path.GetFileNameWithoutExtension(FileName); SkeletalAnim.Path = ""; } for (int i = 0; i < anim.Bones.Count; i++) { if (GetResFileU() != null) { var BoneAnimU = new ResU.BoneAnim(); BoneAnimU.Name = anim.Bones[i]; SkeletalAnimU.BoneAnims.Add(BoneAnimU); SkeletalAnimU.BindIndices[i] = ushort.MaxValue; bool IsRoot = false; if (!IsRoot) { BoneAnimU.ApplyIdentity = false; BoneAnimU.ApplyRotateTranslateZero = false; BoneAnimU.ApplyRotateZero = false; BoneAnimU.ApplyScaleOne = true; BoneAnimU.ApplyScaleVolumeOne = true; BoneAnimU.ApplyScaleUniform = true; BoneAnimU.ApplySegmentScaleCompensate = true; BoneAnimU.ApplyTranslateZero = false; } else { BoneAnimU.ApplyIdentity = true; BoneAnimU.ApplyRotateTranslateZero = true; BoneAnimU.ApplyRotateZero = true; BoneAnimU.ApplyScaleOne = true; BoneAnimU.ApplyScaleVolumeOne = true; BoneAnimU.ApplyScaleUniform = true; BoneAnimU.ApplySegmentScaleCompensate = false; BoneAnimU.ApplyTranslateZero = true; } } else { var BoneAnim = new BoneAnim(); BoneAnim.Name = anim.Bones[i]; SkeletalAnim.BoneAnims.Add(BoneAnim); SkeletalAnim.BindIndices[i] = ushort.MaxValue; //Set base data and curves var baseData = new BoneAnimData(); if (anim.AnimationPositionKeys.ContainsKey(anim.Bones[i]) && anim.AnimationPositionKeys[anim.Bones[i]].Count > 0) { BoneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; var keys = anim.AnimationPositionKeys[anim.Bones[i]]; var data = (SELib.Utilities.Vector3)keys[0].Data; baseData.Translate = new Syroot.Maths.Vector3F((float)data.X, (float)data.Y, (float)data.Z); if (keys.Count > 1) { AnimCurve curve = new AnimCurve(); BoneAnim.Curves.Add(curve); CreateCurveData(curve, keys); } } if (anim.AnimationRotationKeys.ContainsKey(anim.Bones[i]) && anim.AnimationRotationKeys[anim.Bones[i]].Count > 0) { BoneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; var keys = anim.AnimationPositionKeys[anim.Bones[i]]; var data = (SELib.Utilities.Quaternion)keys[0].Data; baseData.Rotate = new Syroot.Maths.Vector4F((float)data.X, (float)data.Y, (float)data.Z, (float)data.W); if (keys.Count > 1) { AnimCurve curve = new AnimCurve(); BoneAnim.Curves.Add(curve); CreateCurveData(curve, keys); } } if (anim.AnimationScaleKeys.ContainsKey(anim.Bones[i]) && anim.AnimationScaleKeys[anim.Bones[i]].Count > 0) { BoneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; var keys = anim.AnimationPositionKeys[anim.Bones[i]]; var data = (SELib.Utilities.Vector3)keys[0].Data; baseData.Scale = new Syroot.Maths.Vector3F((float)data.X, (float)data.Y, (float)data.Z); if (keys.Count > 1) { AnimCurve curve = new AnimCurve(); BoneAnim.Curves.Add(curve); CreateCurveData(curve, keys); } } //Set transforms bool IsRoot = false; if (!IsRoot) { BoneAnim.ApplyIdentity = false; BoneAnim.ApplyRotateTranslateZero = false; BoneAnim.ApplyRotateZero = false; BoneAnim.ApplyScaleOne = true; BoneAnim.ApplyScaleVolumeOne = true; BoneAnim.ApplyScaleUniform = true; BoneAnim.ApplySegmentScaleCompensate = true; BoneAnim.ApplyTranslateZero = false; } else { BoneAnim.ApplyIdentity = true; BoneAnim.ApplyRotateTranslateZero = true; BoneAnim.ApplyRotateZero = true; BoneAnim.ApplyScaleOne = true; BoneAnim.ApplyScaleVolumeOne = true; BoneAnim.ApplyScaleUniform = true; BoneAnim.ApplySegmentScaleCompensate = false; BoneAnim.ApplyTranslateZero = true; } } } for (int frame = 0; frame < anim.FrameCount; frame++) { } }
static void Main(string[] args) { // SELib Unit Test Console.Title = "SELib Unit Tests"; Console.WriteLine("SELib Unit Tests\n"); Console.WriteLine("- SEAnims\n"); #region SEAnim { // Log Console.Write("-- Test 1 "); // Make it var anim = new SEAnim(); // Add some keys anim.AddTranslationKey("shoulder", 0, 0, 0, 0); anim.AddTranslationKey("shoulder", 5, 1, 1, 1); anim.AddTranslationKey("shoulder", 10, 10, 10, 10); anim.AddTranslationKey("shoulder", 30, 20, 20, 20); anim.AddTranslationKey("shoulder", 40, 30, 30, 30); // Save it anim.Write("test1.seanim"); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 2 "); // Make it var anim = new SEAnim(); // Add some keys anim.AddTranslationKey("shoulder", 0, 0, 0, 0); anim.AddTranslationKey("shoulder", 5, 1, 1, 1); anim.AddTranslationKey("shoulder", 10, 10, 10, 10); anim.AddTranslationKey("shoulder", 30, 20, 20, 20); anim.AddTranslationKey("shoulder", 40, 30, 30, 30); // Add some scale anim.AddScaleKey("shoulder", 0, 1, 1, 1); anim.AddScaleKey("shoulder", 50, 3, 3, 3); // Save it anim.Write("test2.seanim"); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 3 "); // Make it var anim = new SEAnim(); // Add some keys anim.AddTranslationKey("shoulder", 0, 0, 0, 0); anim.AddTranslationKey("shoulder", 5, 1, 1, 1); anim.AddTranslationKey("shoulder", 10, 10, 10, 10); anim.AddTranslationKey("shoulder", 30, 20, 20, 20); anim.AddTranslationKey("shoulder", 40, 30, 30, 30); // Add some scale anim.AddScaleKey("shoulder", 0, 1, 1, 1); anim.AddScaleKey("shoulder", 50, 3, 3, 3); // Add some note anim.AddNoteTrack("hello_world", 3); anim.AddNoteTrack("bye", 50); // Save it anim.Write("test3.seanim"); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 4 "); // Make it var anim = new SEAnim(); // Add some keys anim.AddTranslationKey("shoulder", 0, 0, 0, 0); anim.AddTranslationKey("shoulder", 5, 1, 1, 1); anim.AddTranslationKey("shoulder", 10, 10, 10, 10); anim.AddTranslationKey("shoulder", 30, 20, 20, 20); anim.AddTranslationKey("shoulder", 40, 30, 30, 30); // Add some scale anim.AddScaleKey("shoulder", 0, 1, 1, 1); anim.AddScaleKey("shoulder", 50, 3, 3, 3); // Add some note anim.AddNoteTrack("hello_world", 3); anim.AddNoteTrack("bye", 50); // Save it (Really, we don't need doubles!!) anim.Write("test4.seanim", true); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 5 "); // Make it var anim = new SEAnim(); // Add some keys anim.AddTranslationKey("shoulder", 0, 0, 0, 0); anim.AddTranslationKey("shoulder", 5, 1, 1, 1); anim.AddTranslationKey("shoulder", 10, 10, 10, 10); anim.AddTranslationKey("shoulder", 30, 20, 20, 20); anim.AddTranslationKey("shoulder", 40, 30, 30, 30); // Add some scale anim.AddScaleKey("shoulder", 0, 1, 1, 1); anim.AddScaleKey("shoulder", 50, 3, 3, 3); // Add some rot anim.AddRotationKey("shoulder", 0, 0, 0, 0, 1); anim.AddRotationKey("shoulder", 50, 0.3, 0.2, 0.5, 1); // Random quat for test // Add some note anim.AddNoteTrack("hello_world", 3); anim.AddNoteTrack("bye", 50); // Save it anim.Write("test5.seanim"); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 6 "); // Read from test 5 var anim = SEAnim.Read("test5.seanim"); // Check data System.Diagnostics.Debug.Assert(anim.AnimationNotetracks.Count == 2); System.Diagnostics.Debug.Assert(anim.AnimationPositionKeys.Count == 1); System.Diagnostics.Debug.Assert(anim.AnimationRotationKeys.Count == 1); System.Diagnostics.Debug.Assert(anim.AnimationScaleKeys.Count == 1); System.Diagnostics.Debug.Assert(anim.BoneCount == 1); System.Diagnostics.Debug.Assert(anim.FrameCount == 51); System.Diagnostics.Debug.Assert(anim.FrameRate == 30.0); // Version System.Diagnostics.Debug.Assert(anim.APIVersion == "v1.0.1"); // Check functions System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "shoulder") == false); System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "new_shoulder") == true); // Done Console.WriteLine("DONE!"); } #endregion Console.WriteLine("\n- SEModels\n"); #region SEModel { // Log Console.Write("-- Test 1 "); // Make it var model = new SEModel(); // Add some bones model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One); // Save it model.Write("test1.semodel"); // Done Console.WriteLine("DONE!"); } { // Log Console.Write("-- Test 2 "); // Make it var model = new SEModel(); // Allow globals too model.ModelBoneSupport = ModelBoneSupportTypes.SupportsBoth; // Add some bones model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One); // Save it model.Write("test2.semodel"); // Done Console.WriteLine("DONE!"); } #endregion // Pause Console.Write("\nPress any key to continue..."); Console.ReadKey(); }
/// <summary> /// Print the log to the file /// </summary> /// <param name="File">The file to debug</param> /// <param name="FileOutput">The output log file</param> private static void DebugLOGSEAnim(string File, string FileOutput) { // Load the anim var anim = SEAnim.Read(File); // Load bones var bones = anim.Bones; // Log Console.WriteLine(" Writing log to file..."); // Prepare output using (StreamWriter writeFile = new StreamWriter(FileOutput)) { // Log writeFile.WriteLine("-- SEAnim Debugger Utility --"); writeFile.WriteLine(""); // Output initial info writeFile.WriteLine(" Header:"); // Header data { writeFile.WriteLine(" - Frame count: " + anim.FrameCount); writeFile.WriteLine(" - Frame rate: " + anim.FrameRate); writeFile.WriteLine(" - Animation type: " + anim.AnimType.ToString()); writeFile.WriteLine(" - Bone count: " + anim.BoneCount); writeFile.WriteLine(" - Notetrack count: " + anim.NotificationCount); writeFile.WriteLine(" - Modifiers count: " + anim.AnimationBoneModifiers.Count); // Check for delta if (anim.AnimType == AnimationType.Delta) { // Delta bone must be the first one writeFile.WriteLine(" - Delta tag \"" + anim.DeltaTagName + "\""); } } // Separate and prepare keys by bone writeFile.WriteLine("\n Frames:"); // Output keys foreach (string Bone in anim.Bones) { // Bone header writeFile.WriteLine(" - Bone \"" + Bone + "\" data:"); // Translation header writeFile.Write(" - Translations ["); // Check for translation keys if (anim.AnimationPositionKeys.ContainsKey(Bone)) { // Output translation keys var translationKeys = anim.AnimationPositionKeys[Bone]; // Count writeFile.WriteLine(translationKeys.Count + "]"); // Output values foreach (SEAnimFrame frame in translationKeys) { // Output the vector writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); } } else { // Had no keys writeFile.WriteLine("0]"); } // Rotation header writeFile.Write(" - Rotations ["); // Check for rotation keys if (anim.AnimationRotationKeys.ContainsKey(Bone)) { // Output rotation keys var rotKeys = anim.AnimationRotationKeys[Bone]; // Count writeFile.WriteLine(rotKeys.Count + "]"); // Output values foreach (SEAnimFrame frame in rotKeys) { // Output the quat writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2} {3}", ((Quaternion)frame.Data).X, ((Quaternion)frame.Data).Y, ((Quaternion)frame.Data).Z, ((Quaternion)frame.Data).W); } } else { // Had no keys writeFile.WriteLine("0]"); } // Scales header writeFile.Write(" - Scales ["); // Check for scale keys if (anim.AnimationScaleKeys.ContainsKey(Bone)) { // Output scale keys var scaleKeys = anim.AnimationScaleKeys[Bone]; // Count writeFile.WriteLine(scaleKeys.Count + "]"); // Output values foreach (SEAnimFrame frame in scaleKeys) { // Output the vector writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); } } else { // Had no keys writeFile.WriteLine("0]"); } } // Separate and prepare notes writeFile.WriteLine("\n Notifications:"); // Output notetracks foreach (KeyValuePair <string, List <SEAnimFrame> > Notetrack in anim.AnimationNotetracks) { // Note header writeFile.WriteLine(" - Note \"" + Notetrack.Key + "\" data:"); // Loop and output keys foreach (SEAnimFrame frame in Notetrack.Value) { // Log it writeFile.WriteLine(" [" + frame.Frame + "] plays"); } } } }