static void AddAnimData(ExportSettings settings, AnimBone animBone, IOAnimationTrack track, ControlType ctype, TrackType ttype) { AnimData d = new AnimData(); d.controlType = ctype; d.type = ttype; d.preInfinity = CurveWrapModes[track.PreWrap]; d.postInfinity = CurveWrapModes[track.PostWrap]; //Check if any tangents include weights. d.weighted = track.KeyFrames.Any(x => x is IOKeyFrameHermite && ((IOKeyFrameHermite)x).IsWeighted); bool isAngle = ctype == ControlType.rotate; if (isAngle) { d.output = OutputType.angular; } float value = track.KeyFrames.Count > 0 ? (float)track.KeyFrames[0].Value : 0; bool IsConstant = true; foreach (var key in track.KeyFrames) { if ((float)key.Value != value) { IsConstant = false; break; } } foreach (var key in track.KeyFrames) { AnimKey animKey = new AnimKey() { input = key.Frame + 1, output = isAngle ? GetAngle(settings, (float)key.Value) : (float)key.Value, }; if (key is IOKeyFrameHermite) { animKey.intan = "fixed"; animKey.outtan = "fixed"; animKey.t1 = ((IOKeyFrameHermite)key).TangentSlopeInput; animKey.t2 = ((IOKeyFrameHermite)key).TangentSlopeOutput; animKey.w1 = ((IOKeyFrameHermite)key).TangentWeightInput; animKey.w2 = ((IOKeyFrameHermite)key).TangentWeightOutput; } d.keys.Add(animKey); if (IsConstant) { break; } } if (d.keys.Count > 0) { animBone.atts.Add(d); } }
private static void AddAnimData(AnimBone animBone, SBKeyGroup <float> keys, ControlType ctype, TrackType ttype) { AnimData d = new AnimData(); d.controlType = ctype; d.type = ttype; if (IsAngular(ctype)) { d.output = OutputType.angular; } float value = 0; if (keys.Keys.Count > 0) { value = keys.Keys[0].Value; } bool IsConstant = true; foreach (var key in keys.Keys) { if (key.Value != value) { IsConstant = false; break; } } foreach (var key in keys.Keys) { AnimKey animKey = new AnimKey() { input = key.Frame + 1, output = IsAngular(ctype) ? (MayaSettings.UseRadians ? key.Value : (float)(key.Value * (180 / Math.PI))) : key.Value, }; if (key.InterpolationType == InterpolationType.Hermite) { animKey.intan = "fixed"; animKey.outtan = "fixed"; animKey.t1 = key.InTan; animKey.t2 = key.OutTan; } d.keys.Add(animKey); if (IsConstant) { break; } } if (d.keys.Count > 0) { animBone.atts.Add(d); } }
public static void ExportIOAnimationAsANIM(string fname, SBAnimation animation, SBSkeleton Skeleton, bool ordinal = false) { IO_MayaANIM anim = new IO_MayaANIM(); anim.header.endTime = animation.FrameCount + 1; // get bone order List <SBBone> BonesInOrder = getBoneTreeOrder(Skeleton); if (ordinal) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } foreach (SBBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); // Add Tracks SBTransformAnimation node = null; foreach (var animNode in animation.TransformNodes) { if (animNode.Name.Equals(b.Name)) { node = animNode; break; } } if (node == null) { continue; } AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateX); AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateY); AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateZ); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateX); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateY); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateZ); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleX); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleY); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleZ); } anim.Save(fname); }
private static void AddAnimData(AnimBone animBone, SBKeyGroup <Matrix4> node, ControlType ctype, TrackType ttype) { AnimData d = new AnimData(); d.controlType = ctype; d.type = ttype; foreach (var key in node.Keys) { AnimKey animKey = new AnimKey() { input = key.Frame + 1, output = GetValue(key.Value, ctype, ttype) }; d.keys.Add(animKey); } if (d.keys.Count > 0) { animBone.atts.Add(d); } }
private static void AddAnimData(AnimBone animBone, IOAnimNode node, IOTrackType type, ControlType ctype, TrackType ttype) { AnimData d = new AnimData(); d.controlType = ctype; d.type = ttype; foreach (IOAnimKey key in node.GetKeysForTrack(type)) { AnimKey animKey = new AnimKey() { input = key.Frame + 1, output = key.Value, }; d.keys.Add(animKey); } if (d.keys.Count > 0) { animBone.atts.Add(d); } }
public static SkelAnimation read(string filename, VBN vbn) { StreamReader reader = File.OpenText(filename); string line; bool isHeader = true; string angularUnit, linearUnit, timeUnit; int startTime = 0; int endTime = 0; List <AnimBone> bones = new List <AnimBone>(); AnimBone current; AnimData att = new AnimData(); bool inKeys = false; while ((line = reader.ReadLine()) != null) { string[] args = line.Replace(";", "").TrimStart().Split(' '); if (isHeader) { if (args [0].Equals("anim")) { isHeader = false; } else if (args [0].Equals("angularUnit")) { angularUnit = args [1]; } else if (args [0].Equals("endTime")) { endTime = (int)Math.Ceiling(float.Parse(args [1])); } else if (args [0].Equals("startTime")) { startTime = (int)Math.Ceiling(float.Parse(args [1])); } } if (!isHeader) { if (inKeys) { if (args[0].Equals("}")) { inKeys = false; continue; } AnimKey k = new AnimKey(); att.keys.Add(k); k.input = float.Parse(args [0]); k.output = float.Parse(args [1]); k.intan = (args [2]); k.outtan = (args [3]); if (args.Length > 7 && att.weighted) { k.t1 = float.Parse(args[7]) * (float)(Math.PI / 180f); k.w1 = float.Parse(args[8]); } } if (args [0].Equals("anim")) { inKeys = false; if (args.Length == 5) { //TODO: finish this type // can be name of attribute } if (args.Length == 7) { // see of the bone of this attribute exists current = null; foreach (AnimBone b in bones) { if (b.name.Equals(args [3])) { current = b; break; } } if (current == null) { current = new AnimBone(); bones.Add(current); } current.name = args [3]; att = new AnimData(); att.type = args [2]; current.atts.Add(att); // row child attribute aren't needed here } } if (args [0].Equals("input")) { att.input = args [1]; } if (args [0].Equals("output")) { att.output = args [1]; } if (args [0].Equals("weighted")) { att.weighted = args [1].Equals("1"); } if (args [0].Equals("preInfinity")) { att.preInfinity = args [1]; } if (args [0].Equals("postInfinity")) { att.postInfinity = args [1]; } // begining keys section if (args [0].Contains("keys")) { inKeys = true; } } } SkelAnimation a = new SkelAnimation(); for (int i = 0; i < endTime - startTime + 1; i++) { KeyFrame key = new KeyFrame(); a.addKeyframe(key); foreach (AnimBone b in bones) { KeyNode n = new KeyNode(); n.id = vbn.boneIndex(b.name); if (n.id == -1) { continue; } else { n.hash = vbn.bones[n.id].boneId; } foreach (AnimData d in b.atts) { if (d.type.Contains("translate")) { n.t_type = KeyNode.INTERPOLATED; if (d.type.Contains("X")) { n.t.X = d.getValue(i); } if (d.type.Contains("Y")) { n.t.Y = d.getValue(i); } if (d.type.Contains("Z")) { n.t.Z = d.getValue(i); } } if (d.type.Contains("rotate")) { n.r_type = KeyNode.INTERPOLATED; if (d.type.Contains("X")) { n.r.X = d.getValue(i) * (float)(Math.PI / 180f); } if (d.type.Contains("Y")) { n.r.Y = d.getValue(i) * (float)(Math.PI / 180f); } if (d.type.Contains("Z")) { n.r.Z = d.getValue(i) * (float)(Math.PI / 180f); } } if (d.type.Contains("scale")) { n.s_type = KeyNode.INTERPOLATED; if (d.type.Contains("X")) { n.s.X = d.getValue(i); } if (d.type.Contains("Y")) { n.s.Y = d.getValue(i); } if (d.type.Contains("Z")) { n.s.Z = d.getValue(i); } } } key.addNode(n); } } // keynode rotations need caluclation foreach (KeyFrame f in a.frames) { foreach (KeyNode n in f.nodes) { n.r = VBN.FromEulerAngles(n.r.Z, n.r.Y, n.r.X); } } reader.Close(); return(a); }
public static void ExportIOAnimationAsANIM(string fname, SBAnimation animation, SBSkeleton Skeleton) { IO_MayaANIM anim = new IO_MayaANIM(); anim.header.endTime = animation.FrameCount + 1; if (!MayaSettings.UseRadians) { anim.header.angularUnit = "deg"; } // get bone order List <SBBone> BonesInOrder = getBoneTreeOrder(Skeleton); if (MayaSettings.Maya2015) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } if (MayaSettings.RemoveRedundantFrames) { animation.Optimize(); } foreach (SBBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); // Add Tracks SBTransformAnimation node = null; foreach (var animNode in animation.TransformNodes) { if (animNode.Name.Equals(b.Name)) { node = animNode; break; } } if (node == null) { continue; } //TODO: bake scale for compensate scale... foreach (var track in node.Tracks) { switch (track.Type) { case SBTrackType.TranslateX: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateX); break; case SBTrackType.TranslateY: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateY); break; case SBTrackType.TranslateZ: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateZ); break; case SBTrackType.RotateX: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateX); break; case SBTrackType.RotateY: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateY); break; case SBTrackType.RotateZ: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateZ); break; case SBTrackType.ScaleX: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleX); break; case SBTrackType.ScaleY: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleY); break; case SBTrackType.ScaleZ: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleZ); break; } } } anim.Save(fname); }
public void Open(string fileName) { using (StreamReader r = new StreamReader(new FileStream(fileName, FileMode.Open))) { AnimData currentData = null; while (!r.EndOfStream) { var line = r.ReadLine(); var args = line.Trim().Replace(";", "").Split(' '); switch (args[0]) { case "animVersion": header.animVersion = float.Parse(args[1]); break; case "mayaVersion": header.mayaVersion = args[1]; break; case "timeUnit": header.timeUnit = args[1]; break; case "linearUnit": header.linearUnit = args[1]; break; case "angularUnit": header.angularUnit = args[1]; break; case "startTime": header.startTime = float.Parse(args[1]); break; case "endTime": header.endTime = float.Parse(args[1]); break; case "anim": if (args.Length != 7) { continue; } var currentNode = Bones.Find(e => e.name.Equals(args[3])); if (currentNode == null) { currentNode = new AnimBone(); currentNode.name = args[3]; Bones.Add(currentNode); } currentData = new AnimData(); currentData.controlType = (ControlType)Enum.Parse(typeof(ControlType), args[1].Split('.')[0]); if (currentData.controlType == ControlType.MaxHandle) { currentData = null; break; } currentData.type = (TrackType)Enum.Parse(typeof(TrackType), args[2]); currentNode.atts.Add(currentData); break; case "animData": if (currentData == null) { continue; } string dataLine = r.ReadLine(); while (!dataLine.Contains("}")) { var dataArgs = dataLine.Trim().Replace(";", "").Split(' '); switch (dataArgs[0]) { case "input": currentData.input = (InputType)Enum.Parse(typeof(InputType), dataArgs[1]); break; case "output": currentData.output = (OutputType)Enum.Parse(typeof(OutputType), dataArgs[1]); break; case "weighted": currentData.weighted = dataArgs[1] == "1"; break; case "preInfinity": currentData.preInfinity = (InfinityType)Enum.Parse(typeof(InfinityType), dataArgs[1]); break; case "postInfinity": currentData.postInfinity = (InfinityType)Enum.Parse(typeof(InfinityType), dataArgs[1]); break; case "keys": string keyLine = r.ReadLine(); while (!keyLine.Contains("}")) { var keyArgs = keyLine.Trim().Replace(";", "").Split(' '); var key = new AnimKey() { input = float.Parse(keyArgs[0]), output = float.Parse(keyArgs[1]) }; if (keyArgs.Length >= 7) { key.intan = keyArgs[2]; key.outtan = keyArgs[3]; } if (key.intan == "fixed") { key.t1 = float.Parse(keyArgs[7]); key.w1 = float.Parse(keyArgs[8]); } if (key.outtan == "fixed" && keyArgs.Length > 9) { key.t2 = float.Parse(keyArgs[9]); key.w2 = float.Parse(keyArgs[10]); } currentData.keys.Add(key); keyLine = r.ReadLine(); } break; } dataLine = r.ReadLine(); } break; } } } }
static MayaAnim CreateMayaAnimation(ExportSettings settings, IOAnimation animation, IOSkeleton skeleton) { MayaAnim anim = new MayaAnim(); anim.header.startTime = 0; anim.header.endTime = animation.GetFrameCount(); // get bone order List <IOBone> BonesInOrder = getBoneTreeOrder(skeleton); if (settings.MayaAnim2015) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } foreach (IOBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); var group = animation.Groups.FirstOrDefault(x => x.Name.Equals(b.Name)); if (group == null) { continue; } foreach (var track in group.Tracks) { switch (track.ChannelType) { case IOAnimationTrackType.PositionX: AddAnimData(settings, animBone, track, ControlType.translate, TrackType.translateX); break; case IOAnimationTrackType.PositionY: AddAnimData(settings, animBone, track, ControlType.translate, TrackType.translateY); break; case IOAnimationTrackType.PositionZ: AddAnimData(settings, animBone, track, ControlType.translate, TrackType.translateZ); break; case IOAnimationTrackType.RotationEulerX: AddAnimData(settings, animBone, track, ControlType.rotate, TrackType.rotateX); break; case IOAnimationTrackType.RotationEulerY: AddAnimData(settings, animBone, track, ControlType.rotate, TrackType.rotateY); break; case IOAnimationTrackType.RotationEulerZ: AddAnimData(settings, animBone, track, ControlType.rotate, TrackType.rotateZ); break; case IOAnimationTrackType.ScaleX: AddAnimData(settings, animBone, track, ControlType.scale, TrackType.scaleX); break; case IOAnimationTrackType.ScaleY: AddAnimData(settings, animBone, track, ControlType.scale, TrackType.scaleY); break; case IOAnimationTrackType.ScaleZ: AddAnimData(settings, animBone, track, ControlType.scale, TrackType.scaleZ); break; } } } return(anim); }
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); }