public Skeleton(FbxNode rootNode, SceneLoader scene, FbxSkin[] skins, List <AnimationTrackInfo> animationTracks) { Scene = scene; BoneIndexDictionary = new Dictionary <ulong, int>(); Bones = new List <SkeletonBone>(); var skeletonNodeTree = new Dictionary <ulong, bool>(); // [nodeUniqueID] = isSkeleton CheckIsNodeContainsSkeletonRecursive(rootNode, skeletonNodeTree); RootBone = AddNodeToSkeletonRecursive(rootNode, null, skeletonNodeTree, skins); //Temp - Результат вычисления Skeleton до этого места не зависит от текущего SetCurrentAnimationTrack(..) //---------------------------- foreach (var bone in Bones) { bone.AnimTracks = new AnimTrack[animationTracks.Count]; } for (int i = 0; i < animationTracks.Count; i++) { Scene.SetCurrentAnimationTrack(i); foreach (var bone in Bones) { bone.AnimTracks[i] = bone.LoadAnimationTrack(bone.Node, animationTracks[i]); } } //foreach (var bone in Bones) //{ // bone.HasAnimation = bone.GetHasAnimation(); // //if (!bone.HasAnimation) // // bone.NotAnimatedLocalTransform = bone.Node.EvaluateLocalTransform().ToMat4(); //} }
SkeletonBone AddNodeToSkeletonRecursive( FbxNode node, SkeletonBone parentBone, Dictionary <ulong, bool> skeletonNodeTree, FbxSkin[] skins) { if (BoneIndexDictionary.ContainsKey(node.GetUniqueID())) { return(null); } SkeletonBone pBone = new SkeletonBone(node, parentBone, skins, Scene); //pBone.CalculateAnimations(animationTracks); BoneIndexDictionary[node.GetUniqueID()] = Bones.Count; Bones.Add(pBone); for (int i = 0; i < node.GetChildCount(); i++) { FbxNode pChild = node.GetChild(i); if (skeletonNodeTree[pChild.GetUniqueID()]) { var childBone = AddNodeToSkeletonRecursive(pChild, pBone, skeletonNodeTree, skins); if (childBone != null) { pBone.Children.Add(childBone); } } } return(pBone); }
public SkeletonBone(FbxNode boneNode, SkeletonBone parentBone, FbxSkin[] skins, SceneLoader scene) { //this.scene = scene; this.scene = scene; Node = boneNode; ParentBone = parentBone; //animationTrackKeyFrames = new List<HashSet<double>>(); cluster = Skeleton.FindCluster(Node, skins, out skin); //Поиск по всем skins во всех mesh. Можно было бы сделать эффективнее. globalMeshTransform = new FbxAMatrix(); globalMeshTransform.SetIdentity(); geometryOffset = new FbxAMatrix(); geometryOffset.SetIdentity(); if (cluster != null) { FbxNode meshNode = skin.GetGeometry()?.GetNode(); if (meshNode != null) { globalMeshTransform = meshNode.EvaluateGlobalTransform(FbxExtensions.ToFbxTime(-1)); // FbxMath.GetGlobalPosition( meshNode, FbxExtensions.ToFbxTime( -1 ), null ); geometryOffset = FbxMath.GetGeometryOffset(meshNode); } } InitialTransform = GetInitialTransform().ToMatrix4(); //Во внешнем коде надо использовать это значение, т.к. результат GetInitialTransform() может зависеть от установленного AnimationTrack }