void Skeleton::Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation) { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Skeleton not created"); return; } if (!skeletonA.IsValid()) { NazaraError("Skeleton A is invalid"); return; } if (!skeletonB.IsValid()) { NazaraError("Skeleton B is invalid"); return; } if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) { NazaraError("Skeletons must have the same joint count"); return; } #endif Joint* jointsA = &skeletonA.m_impl->joints[0]; Joint* jointsB = &skeletonB.m_impl->joints[0]; for (std::size_t i = 0; i < m_impl->joints.size(); ++i) m_impl->joints[i].Interpolate(jointsA[i], jointsB[i], interpolation, CoordSys_Local); InvalidateJoints(); }
void Skeleton::Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation, UInt32* indices, UInt32 indiceCount) { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Skeleton not created"); return; } if (!skeletonA.IsValid()) { NazaraError("Skeleton A is invalid"); return; } if (!skeletonB.IsValid()) { NazaraError("Skeleton B is invalid"); return; } if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) { NazaraError("Skeletons must have the same joint count"); return; } #endif const Joint* jointsA = &skeletonA.m_impl->joints[0]; const Joint* jointsB = &skeletonB.m_impl->joints[0]; for (UInt32 i = 0; i < indiceCount; ++i) { UInt32 index = indices[i]; #if NAZARA_UTILITY_SAFE if (index >= m_impl->joints.size()) { NazaraError("Index #" + String::Number(i) + " out of range (" + String::Number(index) + " >= " + String::Number(m_impl->joints.size()) + ')'); return; } #endif m_impl->joints[index].Interpolate(jointsA[index], jointsB[index], interpolation, CoordSys_Local); } InvalidateJoints(); }
//----------------------------------------------------------------------------------- static Skeleton* ImportSkeleton(SceneImport* import, MatrixStack4x4& matrixStack, Skeleton* skeleton, int parentJointIndex, FbxSkeleton* fbxSkeleton, std::map<int, FbxNode*>& nodeToJointIndex) { Skeleton* returnSkeleton = nullptr; if (fbxSkeleton->IsSkeletonRoot()) { //THIS IS NEW SKELETON returnSkeleton = new Skeleton(); import->skeletons.push_back(returnSkeleton); } else { returnSkeleton = skeleton; ASSERT_OR_DIE(returnSkeleton != nullptr, "Return skeleton was null! (This should never happen lol)"); } Matrix4x4 geotransform = GetGeometricTransform(fbxSkeleton->GetNode()); matrixStack.Push(geotransform); Matrix4x4 modelSpace = matrixStack.GetTop(); nodeToJointIndex[returnSkeleton->GetJointCount()] = fbxSkeleton->GetNode(); returnSkeleton->AddJoint(fbxSkeleton->GetNode()->GetName(), parentJointIndex, modelSpace); matrixStack.Pop(); return returnSkeleton; }
void AnimationSystem::LocalPoseCalculation() { // todo: can be easly run in parallel. for( u32 i = 0; i < m_controllers.Count(); ++i ) { AnimController& controller = m_controllers[i]; Skeleton* skeleton = controller.GetSkeleton(); AnimHierarchy* hierarchy = controller.GetHierarchy(); for( u16 j = 0; j < skeleton->GetJointCount(); ++j ) { AnimationClip::JointPose local_pose; controller.GetJointPose( j, local_pose ); AnimTransformation& node = hierarchy->GetNode(j); node.SetTranslation( local_pose.translation ); node.SetScale( local_pose.scale ); node.SetRotation( local_pose.rotation ); node.CalculateLocalTransformation(); } } }