/// <summary> /// /// </summary> /// <param name="filePath"></param> public static JointAnimManager ImportFromMayaAnim(string filePath) { var mayaFile = new MayaAnim(); mayaFile.Open(filePath); JointAnimManager animation = new JointAnimManager(); animation.FrameCount = mayaFile.header.endTime - mayaFile.header.startTime; // process and encode FOBJ keys foreach (var mNode in mayaFile.Nodes) { AnimNode node = new AnimNode(); //Debug.WriteLine(mNode.name); foreach (var mTrack in mNode.atts) { FOBJ_Player t = new FOBJ_Player(); t.Keys = new List <FOBJKey>(); t.JointTrackType = jointTrackToMayaTrack.FirstOrDefault(e => e.Value == mTrack.type).Key; //Debug.WriteLine("\t" + mTrack.type); var degrees = mayaFile.header.angularUnit == "deg"; var trackUnit = (mTrack.IsAngular() && degrees); for (int i = 0; i < mTrack.keys.Count; i++) { var mKey = mTrack.keys[i]; var mKeyNext = i + 1 < mTrack.keys.Count ? mTrack.keys[i + 1] : mTrack.keys[i]; var k = new FOBJKey(); k.Frame = mKey.input - mayaFile.header.startTime; k.Value = trackUnit ? MathHelper.DegreesToRadians(mKey.output) : mKey.output; switch (mKey.outtan) { case "auto": case "linear": k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN; t.Keys.Add(k); break; case "step": if (mTrack.keys.Count == 1) { k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY; } else { k.InterpolationType = GXInterpolationType.HSD_A_OP_CON; } t.Keys.Add(k); break; case "fixed": case "spline": k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL; k.Tan = AngleToTan(mKey.t1, degrees); if ((mKeyNext.input - mKey.input) <= 1) // optimization { //k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN; t.Keys.Add(k); } else if (mKey.t2 == 0) { k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL0; t.Keys.Add(k); } else if (mKey.t1 != mKey.t2) { t.Keys.Add(k); var slp = new FOBJKey(); slp.Frame = mKeyNext.input - 1; slp.InterpolationType = GXInterpolationType.HSD_A_OP_SLP; slp.Tan = AngleToTan(mKey.t2, degrees); t.Keys.Add(slp); } else { t.Keys.Add(k); } break; default: Console.WriteLine(mKey.outtan + " not supported!"); break; } if (mTrack.keys.Count == 1) { k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY; } //foreach (var key in t.Keys) // Debug.WriteLine($"\t\t{key.Frame} {key.Value}"); } node.Tracks.Add(t); } animation.Nodes.Add(node); } return(animation); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <param name="nodes"></param> public static void ExportToMayaAnim(string filePath, JointAnimManager animation, Dictionary <int, string> boneLabelMap) { using (PropertyDialog d = new PropertyDialog("Maya Settings", MayaSettings)) { if (d.ShowDialog() != DialogResult.OK) { return; } } MayaAnim a = new MayaAnim(); if (!MayaSettings.UseRadians) { a.header.angularUnit = "deg"; } int nodeIndex = 0; int frameCount = 0; foreach (var n in animation.Nodes) { MayaAnim.MayaNode mnode = new MayaAnim.MayaNode(); mnode.name = boneLabelMap.ContainsKey(nodeIndex) ? boneLabelMap[nodeIndex] : "JOBJ_" + nodeIndex; a.Nodes.Add(mnode); foreach (var t in n.Tracks) { if (!jointTrackToMayaTrack.ContainsKey(t.JointTrackType)) { continue; } MayaAnim.MayaTrack mtrack = new MayaAnim.MayaTrack(); mnode.atts.Add(mtrack); mtrack.type = jointTrackToMayaTrack[t.JointTrackType]; if (mtrack.IsAngular()) { mtrack.output = MayaAnim.OutputType.angular; } FOBJAnimState prevState = null; for (int i = 0; i < t.Keys.Count; i++) { // get maximum frame to use as framecount frameCount = (int)Math.Max(frameCount, t.Keys[i].Frame); // get current state at this key frame var state = t.GetState(t.Keys[i].Frame); bool nextSlope = i + 1 < t.Keys.Count && t.Keys[i + 1].InterpolationType == GXInterpolationType.HSD_A_OP_SLP; if (t.Keys[i].InterpolationType == GXInterpolationType.HSD_A_OP_SLP) { continue; } // assuming last frame // if last frame shift frame information over if (t.Keys[i].Frame == state.t1) { state.t0 = state.t1; state.p0 = state.p1; state.d0 = state.d1; //state.op_intrp = state.op; } // generate key with time and value var animkey = new MayaAnim.AnimKey() { input = state.t0, output = state.p0, }; // nothing to do for linear //if (op_intrp == GXInterpolationType.HSD_A_OP_LIN) // set step type for constant and key if (state.op_intrp == GXInterpolationType.HSD_A_OP_CON || state.op_intrp == GXInterpolationType.HSD_A_OP_KEY) { animkey.intan = "auto"; animkey.outtan = "step"; } // set tangents for weighted slopes if (state.op_intrp == GXInterpolationType.HSD_A_OP_SLP || state.op_intrp == GXInterpolationType.HSD_A_OP_SPL0 || state.op_intrp == GXInterpolationType.HSD_A_OP_SPL) { animkey.t1 = state.d0; animkey.t2 = state.d0; if (nextSlope && prevState != null) { animkey.t1 = prevState.d1; } animkey.intan = "spline"; animkey.outtan = "spline"; } prevState = state; animkey.t1 = (float)MathHelper.RadiansToDegrees(Math.Atan(animkey.t1)); animkey.t2 = (float)MathHelper.RadiansToDegrees(Math.Atan(animkey.t2)); if (mtrack.IsAngular() && !MayaSettings.UseRadians) { animkey.output = MathHelper.RadiansToDegrees(animkey.output); animkey.t1 = MathHelper.RadiansToDegrees(animkey.t1); animkey.t2 = MathHelper.RadiansToDegrees(animkey.t2); } // add final key mtrack.keys.Add(animkey); } } nodeIndex++; } // set framecount a.header.endTime = animation.FrameCount; a.header.startTime = 0; // save to file a.Save(filePath); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> public static HSD_FigaTree ImportFromMayaAnim(string filePath, BoneMap jointMap) { var mayaFile = new MayaAnim(); mayaFile.Open(filePath); HSD_FigaTree animation = new HSD_FigaTree(); animation.FrameCount = mayaFile.header.endTime - mayaFile.header.startTime; List <FigaTreeNode> nodes = new List <FigaTreeNode>(); var nodeCount = jointMap == null || jointMap.Count == 0 ? mayaFile.Nodes.Count : Math.Max(mayaFile.Nodes.Count, jointMap.Count); for (int i = 0; i < nodeCount; i++) { nodes.Add(new FigaTreeNode()); } // process and encode FOBJ keys int index = 0; foreach (var mNode in mayaFile.Nodes) { var node = animation.Nodes[index++]; //Debug.WriteLine(mNode.name); if (jointMap != null) { var nodeIndex = jointMap.GetIndex(mNode.name); if (nodeIndex != -1) { node = animation.Nodes[nodeIndex]; } } foreach (var mTrack in mNode.atts) { FOBJ_Player t = new FOBJ_Player(); t.Keys = new List <FOBJKey>(); t.JointTrackType = jointTrackToMayaTrack.FirstOrDefault(e => e.Value == mTrack.type).Key; //Debug.WriteLine("\t" + mTrack.type); var degrees = mayaFile.header.angularUnit == "deg"; var trackUnit = (mTrack.IsAngular() && degrees); for (int i = 0; i < mTrack.keys.Count; i++) { var mKey = mTrack.keys[i]; var mKeyNext = i + 1 < mTrack.keys.Count ? mTrack.keys[i + 1] : mTrack.keys[i]; var k = new FOBJKey(); k.Frame = mKey.input - mayaFile.header.startTime; k.Value = trackUnit ? (float)(mKey.output * Math.PI / 180) : mKey.output; switch (mKey.outtan) { case "auto": case "linear": k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN; t.Keys.Add(k); break; case "step": if (mTrack.keys.Count == 1) { k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY; } else { k.InterpolationType = GXInterpolationType.HSD_A_OP_CON; } t.Keys.Add(k); break; case "fixed": case "spline": k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL; k.Tan = AngleToTan(mKey.t1, degrees); if ((mKeyNext.input - mKey.input) <= 1) // optimization { //k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN; t.Keys.Add(k); } else if (mKey.t2 == 0) { k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL0; t.Keys.Add(k); } else if (mKey.t1 != mKey.t2) { t.Keys.Add(k); var slp = new FOBJKey(); slp.Frame = mKeyNext.input - 1; slp.InterpolationType = GXInterpolationType.HSD_A_OP_SLP; slp.Tan = AngleToTan(mKey.t2, degrees); t.Keys.Add(slp); } else { t.Keys.Add(k); } break; default: Console.WriteLine(mKey.outtan + " not supported!"); break; } if (mTrack.keys.Count == 1) { k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY; } //foreach (var key in t.Keys) // Debug.WriteLine($"\t\t{key.Frame} {key.Value}"); } var track = new HSD_Track(); track.FromFOBJ(t.ToFobj()); node.Tracks.Add(track); } } animation.Nodes = nodes; animation.Type = 1; return(animation); }