/// <summary> /// /// </summary> /// <param name="document"></param> public FbxHelper(FbxDocument document) { // set document _document = document; // get and store sfbx version var ver = _document.GetNodesByName("FBXVersion"); if (ver.Length > 0) { Version = (int)ver[0].Value; } else { Version = -1; } // get connectors var connections = _document.GetNodesByName("C"); if (connections.Length == 0) { connections = _document.GetNodesByName("Connect"); } // use strings for backwards compatibility foreach (var oo in connections) { if (!Connections.ContainsKey(oo.Properties[1].ToString())) { Connections.Add(oo.Properties[1].ToString(), new List <string>()); } Connections[oo.Properties[1].ToString()].Add(oo.Properties[2].ToString()); } }
/// <summary> /// Gets a list of animations from the fbx animation stack. /// </summary> /// <returns></returns> public List <IOAnimation> GetAnimations() { List <IOAnimation> anims = new List <IOAnimation>(); foreach (var node in _document.GetNodesByName("AnimationStack")) { //Create the animation. IOAnimation currentAnim = LoadAnimationStack(node); anims.Add(currentAnim); //Use the stop amount from the animation properties for the end frame. currentAnim.EndFrame = ConvertTimeUnits((long)node["Properties70"].GetNodesByValue("LocalStop")[0].Properties[4]); //AnimationLayer foreach (var layer in GetChildConnections(node)) { IOAnimation currentGroup = LoadAnimationLayer(node); currentAnim.Groups.Add(currentGroup); //AnimationCurveNode foreach (var curveNode in GetChildConnections(layer)) { //All tracks have the same animated object reference. //Set it per group still. currentGroup.Name = FindAnimatedObject(curveNode); //Only care about the node type. string trackNodeType = curveNode.Properties[NodeDescSize - 2].ToString(); //Go through each AnimationCurve var curves = GetChildConnections(curveNode); for (int i = 0; i < curves.Count; i++) { currentGroup.Tracks.Add(LoadAnimationCurve(curves[i], trackNodeType, i)); } } } } return(anims); }
/// <summary> /// Extracts skeleton information from fbx file /// </summary> /// <returns></returns> public IOSkeleton GetSkeleton() { // search all limb nodes var limbs = _document.GetNodesByName("Model").Where(e => e.Properties.Count >= NodeDescSize && e.Properties[NodeDescSize - 1].ToString().Contains("Limb")); // map the id to the newly create bone Dictionary <string, IOBone> idToBone = new Dictionary <string, IOBone>(); // convert nodes to bones foreach (var l in limbs) { idToBone.Add(l.Value.ToString(), CreateBoneFromNode(l)); } // create io skeleton var skeleton = new IOSkeleton(); // make connections foreach (var v in idToBone) { if (Connections.ContainsKey(v.Key) && Connections[v.Key].Count > 0 && idToBone.ContainsKey(Connections[v.Key][0])) { idToBone[Connections[v.Key][0]].AddChild(v.Value); } else { skeleton.RootBones.Add(v.Value); } } // account for blender's armature node var nullParent = GetBoneParentTransform(); foreach (var skel in skeleton.RootBones) { skel.LocalTransform *= nullParent; } return(skeleton); }