public static List <Bone> GetBoneHierarchy(FBXTreeNode node, FBXFile fbx) { var bones = new List <Bone>(); var modelNodes = node.Children.Where(a => a.Node.Name == "Model"); foreach (var child in modelNodes) { var model = new Model(child.Node, fbx); if (model.ModelType == Model.FBXModelType.LimbNode || (model.ModelType == Model.FBXModelType.None && !model.HasGeometry)) { var children = GetBoneHierarchy(child, fbx); var t = model.LclTranslation; var r = model.LclRotation.ToRadians().QuaternionFromEuler(EulerOrder.XYZ); var s = model.LclScaling; var deformerId = fbx.Connections.Where(a => a.Src == model.Id && fbx.FindChild(a.Dst).Name == "Deformer").FirstOrDefault(); var globalInverseMatrix = new float[] { }.IdentityMatrix(); if (deformerId != null) { var deformer = new Deformer(fbx.FindChild(deformerId.Dst)); } var bone = new Bone() { Id = model.Id.ToString(), Parent = (node.Node != null) ? node.Node.Id.ToString() : "", Children = children.Select(a => a.Id).ToList(), JointMatrix = new float[] { }.MatrixCompose(t, r, s), Name = model.Name }; bone.Keyframes = GetBoneKeyFrames(bone, fbx); bones.Add(bone); bones.AddRange(children); } } return(bones); }
public Animation(FBXFile file, List <string> bones) { var rawNodes = file.GetAnimationCurveNodes(); var rawCurves = file.GetAnimationCurves(); // first: expand AnimationCurveNode into curve nodes var curveNodes = new List <FBXAnimCurveNode>(); foreach (var tempNode in rawNodes) { var fileNode = file.FindChild(tempNode.Id); curveNodes.Add(new FBXAnimCurveNode(fileNode, file, bones)); } // second: gen dict, mapped by internalId var tmp = new Dictionary <long, FBXAnimCurveNode>(); for (var i = 0; i < curveNodes.Count; ++i) { tmp.Add(curveNodes[i].Id, curveNodes[i]); } // third: insert curves into the dict var ac = new List <FBXAnimCurve>(); var max = 0f; foreach (var curve in rawCurves) { ac.Add(curve); max = curve.Length > max ? curve.Length : max; var parentId = file.Connections.Where(a => a.Src == curve.Id).FirstOrDefault().Dst; var axis = file.GetConnectionType(curve.Id, parentId); if (axis.Contains("X")) { axis = "x"; } if (axis.Contains("Y")) { axis = "y"; } if (axis.Contains("Z")) { axis = "z"; } tmp[parentId].Curves.Add(axis, curve); } // forth: foreach (var t in tmp) { var id = t.Value.ContainerBoneId; if (!Curves.ContainsKey(id)) { Curves.Add(id, new Dictionary <string, FBXAnimCurveNode>()); } if (Curves[id].ContainsKey(t.Value.Attr)) { Curves[id][t.Value.Attr] = t.Value; } else { Curves[id].Add(t.Value.Attr, t.Value); } } Length = max; Frames = Length * FPS; }