public static void ExportIOAnimationAsSMD(string FileName, IOAnimation Animation, RSkeleton Skeleton) { if (Skeleton == null) { return; } StringBuilder o = new StringBuilder(); o.AppendLine("version 1"); //skeleton { o.AppendLine("nodes"); foreach (RBone bone in Skeleton.Bones) { o.AppendLine($"{bone.Id} \"{bone.Name}\" {bone.ParentId}"); } o.AppendLine("end"); } //animation o.AppendLine("skeleton"); { for (int i = 0; i < Animation.FrameCount; i++) { o.AppendLine($"time {i}"); foreach (RBone bone in Skeleton.Bones) { Vector3 Position = bone.Position; Vector3 Rotation = bone.EulerRotation; if (Animation.TryGetNodeByName(bone.Name, out IOAnimNode Node)) { Position = Node.GetPosition(i, Position); Rotation = Tools.CrossMath.ToEulerAngles(Node.GetQuaternionRotation(i, bone.Rotation).Inverted()); } o.AppendLine($"{bone.Id} {Position.X} {Position.Y} {Position.Z} {Rotation.X} {Rotation.Y} {Rotation.Z}"); } } } o.AppendLine("end"); File.WriteAllText(FileName, o.ToString()); }
public static void ExportIOAnimation(string FileName, IOAnimation animData) { SEAnim seOut = new SEAnim(); //init new SEAnim foreach (IOAnimNode node in animData.Nodes) //iterate through each node { for (int i = 0; i < animData.FrameCount; i++) { OpenTK.Vector3 pos = node.GetPosition(i, OpenTK.Vector3.Zero); OpenTK.Quaternion rot = node.GetQuaternionRotation(i, new OpenTK.Quaternion(0, 0, 0, 0)); OpenTK.Vector3 sca = node.GetScaling(i, OpenTK.Vector3.Zero); seOut.AddTranslationKey(node.Name, i, pos.X, pos.Y, pos.Z); seOut.AddRotationKey(node.Name, i, rot.X, rot.Y, rot.Z, rot.W); seOut.AddScaleKey(node.Name, i, sca.X, sca.Y, sca.Z); } } seOut.Write(FileName); //write it! }
public static void ExportIOAnimationAsANIM(string fname, IOAnimation animation, RSkeleton Skeleton, bool ordinal = false) { IO_MayaANIM anim = new IO_MayaANIM(); anim.header.endTime = animation.FrameCount + 1; // get bone order List <RBone> BonesInOrder = getBoneTreeOrder(Skeleton); if (ordinal) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } foreach (RBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); // Add Tracks if (animation.TryGetNodeByName(b.Name, out IOAnimNode ioAnimNode)) { AddAnimData(animBone, ioAnimNode, IOTrackType.POSX, ControlType.translate, TrackType.translateX); AddAnimData(animBone, ioAnimNode, IOTrackType.POSY, ControlType.translate, TrackType.translateY); AddAnimData(animBone, ioAnimNode, IOTrackType.POSZ, ControlType.translate, TrackType.translateZ); // rotation if (animation.RotationType == IORotationType.Euler) { // directly AddAnimData(animBone, ioAnimNode, IOTrackType.ROTX, ControlType.rotate, TrackType.rotateX); AddAnimData(animBone, ioAnimNode, IOTrackType.ROTY, ControlType.rotate, TrackType.rotateY); AddAnimData(animBone, ioAnimNode, IOTrackType.ROTZ, ControlType.rotate, TrackType.rotateZ); } else if (animation.RotationType == IORotationType.Quaternion) { // convert to euler AnimData rx = new AnimData(); rx.controlType = ControlType.rotate; rx.type = TrackType.rotateX; AnimData ry = new AnimData(); ry.controlType = ControlType.rotate; ry.type = TrackType.rotateY; AnimData rz = new AnimData(); rz.controlType = ControlType.rotate; rz.type = TrackType.rotateZ; rx.output = OutputType.angular; ry.output = OutputType.angular; rz.output = OutputType.angular; List <float> KeyFrames = new List <float>(); foreach (IOAnimKey key in ioAnimNode.GetKeysForTrack(IOTrackType.ROTX)) { KeyFrames.Add(key.Frame); } for (int i = 0; i < KeyFrames.Count; i++) { Vector3 EulerAngles = Tools.CrossMath.ToEulerAnglesXYZ(ioAnimNode.GetQuaternionRotation(KeyFrames[i], b.Rotation)); rx.keys.Add(new AnimKey() { input = KeyFrames[i] + 1, output = EulerAngles.X, }); ry.keys.Add(new AnimKey() { input = KeyFrames[i] + 1, output = EulerAngles.Y, }); rz.keys.Add(new AnimKey() { input = KeyFrames[i] + 1, output = EulerAngles.Z, }); } if (rx.keys.Count > 0) { animBone.atts.Add(rx); animBone.atts.Add(ry); animBone.atts.Add(rz); } } // scale AddAnimData(animBone, ioAnimNode, IOTrackType.SCAX, ControlType.scale, TrackType.scaleX); AddAnimData(animBone, ioAnimNode, IOTrackType.SCAY, ControlType.scale, TrackType.scaleY); AddAnimData(animBone, ioAnimNode, IOTrackType.SCAZ, ControlType.scale, TrackType.scaleZ); } } anim.Save(fname); }