Created
March 23, 2018 11:26
-
-
Save mafaca/ae05fb84ad851a61a6326aa7a46f5b24 to your computer and use it in GitHub Desktop.
Animation export for US
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static void WriteFBX(string FBXfile, bool allNodes) | |
{ | |
// original code | |
// original write & extract Textures | |
#region write Animation nodes and curves | |
if (exportAnimation) | |
{ | |
for (int i = 0; i < Animations.Count; i++) | |
{ | |
const ulong fbxTimeRate = 46186158000; | |
const string stackPrefix = "96239"; | |
const string layerPrefix = "80190"; | |
const string transPrefix = "19260"; | |
const string rotPrefix = "19480"; | |
const string scalePrefix = "19910"; | |
AssetPreloadData animation = Animations.ElementAt(i); | |
AnimationClip animationClip = AnimationClips.ElementAt(i); | |
List<AnimationClip.Vector3Curve> rotations = new List<AnimationClip.Vector3Curve>(animationClip.RotationCurves.Count); | |
foreach (AnimationClip.QuaternionCurve curve in animationClip.RotationCurves) | |
{ | |
rotations.Add(curve.ToFBXRotation()); | |
} | |
List<AnimationClip.Vector3Curve> translations = new List<AnimationClip.Vector3Curve>(animationClip.PositionCurves.Count); | |
foreach (AnimationClip.Vector3Curve curve in animationClip.PositionCurves) | |
{ | |
translations.Add(curve.ToFBXTranslation()); | |
} | |
List<AnimationClip.Vector3Curve> scales = animationClip.ScaleCurves; | |
float rotDuration = rotations.Max(t => t.Curve.Curve.Max(j => j.Time)); | |
//float rotDuration = 0.0f; | |
float transDuration = translations.Max(t => t.Curve.Curve.Max(j => j.Time)); | |
float scaleDuration = scales.Max(t => t.Curve.Curve.Max(j => j.Time)); | |
float duration = Math.Max(Math.Max(rotDuration, transDuration), scaleDuration); | |
long fbxDuration = (long)(fbxTimeRate * duration); | |
int stackIndex = i + 1; | |
ob.AppendFormat("\n\tAnimationStack: {0}{1}, \"AnimStack::Take {2:000}\", \"\" {{", stackPrefix, animation.uniqueID, stackIndex); | |
ob.Append("\n\t\tProperties70: {"); | |
ob.AppendFormat("\n\t\t\tP: \"LocalStop\", \"KTime\", \"Time\", \"\",{0}", fbxDuration); | |
ob.AppendFormat("\n\t\t\tP: \"ReferenceStop\", \"KTime\", \"Time\", \"\",{0}", fbxDuration); | |
ob.Append("\n\t\t}"); | |
ob.Append("\n\t}"); | |
ob.AppendFormat("\n\tAnimationLayer: {0}{1}, \"AnimLayer::BaseLayer\", \"\" {{", layerPrefix, animation.uniqueID); | |
ob.Append("\n\t}"); | |
cb.AppendFormat("\n\n\t;AnimLayer::BaseLayer, AnimStack::Take {0:000}", stackIndex); | |
cb.AppendFormat("\n\tC: \"OO\",{0}{1},{2}{1}", layerPrefix, animation.uniqueID, stackPrefix); | |
foreach (GameObject limbNode in LimbNodes) | |
{ | |
string fullPath = limbNode.FullPath; | |
string rootName = selectedNode; | |
int index = fullPath.LastIndexOf(rootName, StringComparison.Ordinal); | |
if (index == -1) | |
{ | |
continue; | |
} | |
index += rootName.Length + 1; | |
if (index >= fullPath.Length) | |
{ | |
fullPath = string.Empty; | |
} | |
else | |
{ | |
fullPath = fullPath.Substring(index); | |
fullPath = fullPath.Replace("\\", "/"); | |
} | |
for (int j = 0; j < translations.Count; j++) | |
{ | |
AnimationClip.Vector3Curve trans = translations[j]; | |
if (trans.Path.String == fullPath) | |
{ | |
FBXWriterHelper.WriteAnimCurveNode(ob, cb, transPrefix, j, layerPrefix, animation.uniqueID, | |
"T", "Lcl Translation", | |
limbNode.m_Name, limbNode.uniqueID, trans, null); | |
} | |
} | |
for (int j = 0; j < rotations.Count; j++) | |
{ | |
AnimationClip.Vector3Curve rot = rotations[j]; | |
if (rot.Path.String == fullPath) | |
{ | |
FBXWriterHelper.WriteAnimCurveNode(ob, cb, rotPrefix, j, layerPrefix, animation.uniqueID, | |
"R", "Lcl Rotation", | |
limbNode.m_Name, limbNode.uniqueID, rot, animationClip.RotationCurves[j]); | |
} | |
} | |
for (int j = 0; j < scales.Count; j++) | |
{ | |
AnimationClip.Vector3Curve scale = scales[j]; | |
if (scale.Path.String == fullPath) | |
{ | |
FBXWriterHelper.WriteAnimCurveNode(ob, cb, scalePrefix, j, layerPrefix, animation.uniqueID, | |
"S", "Lcl Scaling", | |
limbNode.m_Name, limbNode.uniqueID, scale, null); | |
} | |
} | |
} | |
} | |
} | |
#endregion | |
// original code | |
} | |
public static class FBXWriterHelper | |
{ | |
public static void WriteAnimCurveNode(StringBuilder ob, StringBuilder cb, string prefix, int index, string layerPrefix, string uniqueID, | |
string subType, string fullSubType, string modelName, string modelId, AnimationClip.Vector3Curve curve, AnimationClip.QuaternionCurve orCurve) | |
{ | |
ob.AppendFormat("\n\tAnimationCurveNode: {0}{1:000}{2}, \"AnimCurveNode::{3}\", \"\" {{", prefix, index, uniqueID, subType); | |
ob.Append("\n\t\tProperties70: {"); | |
ob.AppendFormat("\n\t\t\tP: \"d|X\", \"Number\", \"\", \"A\",{0}", curve.Curve.Curve[0].Value.X); | |
ob.AppendFormat("\n\t\t\tP: \"d|Y\", \"Number\", \"\", \"A\",{0}", curve.Curve.Curve[0].Value.Y); | |
ob.AppendFormat("\n\t\t\tP: \"d|Z\", \"Number\", \"\", \"A\",{0}", curve.Curve.Curve[0].Value.Z); | |
ob.Append("\n\t\t}"); | |
ob.Append("\n\t}"); | |
cb.AppendFormat("\n\n\t;AnimCurveNode::{0}, AnimLayer::BaseLayer", subType); | |
cb.AppendFormat("\n\tC: \"OO\",{0}{1:000}{2},{3}{2}", prefix, index, uniqueID, layerPrefix); | |
cb.AppendFormat("\n\n\t;AnimCurveNode::{0}, Model::{1}", subType, modelName); | |
cb.AppendFormat("\n\tC: \"OP\",{0}{1:000}{2},1{3}, \"{4}\"", prefix, index, uniqueID, modelId, fullSubType); | |
const string curvePrefix = "20079"; | |
int extra = 0; | |
if (subType == "R") | |
{ | |
extra = 1; | |
} | |
else if (subType == "S") | |
{ | |
extra = 2; | |
} | |
WriteAnimCurve(ob, cb, curvePrefix, index, index * 9 + extra * 3, uniqueID, curve, orCurve, 0, "d|X", subType, prefix); | |
WriteAnimCurve(ob, cb, curvePrefix, index, index * 9 + extra * 3 + 1, uniqueID, curve, orCurve, 1, "d|Y", subType, prefix); | |
WriteAnimCurve(ob, cb, curvePrefix, index, index * 9 + extra * 3 + 2, uniqueID, curve, orCurve, 2, "d|Z", subType, prefix); | |
} | |
public static void WriteAnimCurve(StringBuilder ob, StringBuilder cb, string prefix, int nodeIdex, int index, string uniqueID, | |
AnimationClip.Vector3Curve curve, AnimationClip.QuaternionCurve orCurve, int memIndex, string memName, string subType, string nodePrefix) | |
{ | |
const ulong fbxTimeRate = 46186158000; | |
ob.AppendFormat("\n\tAnimationCurve: {0}{1:000}{2}, \"AnimCurve::\", \"\" {{", prefix, index, uniqueID); | |
ob.AppendFormat("\n\t\tDefault: {0}", curve.Curve.Curve[0].Value.GetMember(memIndex)); | |
ob.Append("\n\t\tKeyVer: 4008"); | |
ob.AppendFormat("\n\t\tKeyTime: *{0} {{", curve.Curve.Curve.Count); | |
ob.Append("\n\t\t\ta: "); | |
foreach (AnimationClip.KeyframeTpl<Vector3f> tpl in curve.Curve.Curve) | |
{ | |
ob.AppendFormat("{0},", (long)(tpl.Time * fbxTimeRate)); | |
} | |
ob.Length--; | |
ob.Append("\n\t\t}"); | |
ob.AppendFormat("\n\t\tKeyValueFloat: *{0} {{", curve.Curve.Curve.Count); | |
if (orCurve != null) | |
{ | |
ob.Append("\n\t\t\t;"); | |
foreach (AnimationClip.KeyframeTpl<Quaternionf> tpl in orCurve.Curve.Curve) | |
{ | |
ob.AppendFormat("{0},", UnityUtils.UnityRotationToFBX(tpl.Value).GetMember(memIndex)); | |
} | |
ob.Length--; | |
} | |
ob.Append("\n\t\t\ta: "); | |
foreach (AnimationClip.KeyframeTpl<Vector3f> tpl in curve.Curve.Curve) | |
{ | |
ob.AppendFormat("{0},", tpl.Value.GetMember(memIndex)); | |
} | |
ob.Length--; | |
ob.Append("\n\t\t}"); | |
ob.Append(@" | |
;KeyAttrFlags: Cubic|TangeantTCB | |
;KeyAttrFlags: *1 { | |
; a: 520 | |
;} | |
;KeyAttrFlags: Cubic|TangeantAuto|GenericTimeIndependent|GenericClampProgressive | |
KeyAttrFlags: *1 { | |
a: 24840 | |
} | |
;KeyAttrDataFloat: TCBTension:0, TCBContinuity:0, TCBBias:4.09995e-031 | |
;KeyAttrDataFloat: *4 { | |
; a: 0,0,218434821,0 | |
;}"); | |
ob.AppendFormat("\n\t\tKeyAttrRefCount: *1 {{"); | |
ob.AppendFormat("\n\t\t\ta: {0}", curve.Curve.Curve.Count); | |
ob.Append("\n\t\t}"); | |
ob.Append("\n\t}"); | |
cb.AppendFormat("\n\n\t;AnimCurve::, AnimCurveNode::{0}", subType); | |
cb.AppendFormat("\n\tC: \"OP\",{0}{1:000}{2},{3}{5:000}{2}, \"{4}\"", prefix, index, uniqueID, nodePrefix, memName, nodeIdex); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment