summaryrefslogtreecommitdiff
path: root/Runtime/Animation/CalculateAnimatorSkinMatrices.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Animation/CalculateAnimatorSkinMatrices.cpp')
-rw-r--r--Runtime/Animation/CalculateAnimatorSkinMatrices.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/Runtime/Animation/CalculateAnimatorSkinMatrices.cpp b/Runtime/Animation/CalculateAnimatorSkinMatrices.cpp
new file mode 100644
index 0000000..4e2091a
--- /dev/null
+++ b/Runtime/Animation/CalculateAnimatorSkinMatrices.cpp
@@ -0,0 +1,85 @@
+#include "UnityPrefix.h"
+
+#include "Runtime/Animation/CalculateAnimatorSkinMatrices.h"
+#include "Runtime/Animation/Avatar.h"
+#include "Runtime/Animation/Animator.h"
+#include "Runtime/Animation/MecanimUtility.h"
+#include "Runtime/Filters/Mesh/MeshSkinning.h"
+#include "Runtime/mecanim/animation/avatar.h"
+#include "Runtime/mecanim/skeleton/skeleton.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Profiler/Profiler.h"
+
+PROFILER_INFORMATION(gMeshSkinningPullMatrices, "MeshSkinning.CalculateSkinningMatrices", kProfilerRender)
+
+void* DoCalculateAnimatorSkinMatrices (void* userData)
+{
+ PROFILER_AUTO(gMeshSkinningPullMatrices, NULL);
+
+ CalculateSkinMatricesTask& task = *static_cast<CalculateSkinMatricesTask*>(userData);
+ const mecanim::skeleton::SkeletonPose* animatedPose =
+ reinterpret_cast<const mecanim::skeleton::SkeletonPose*>(task.skeletonPose);
+
+ for (int i=0; i<task.bindPoseCount; i++)
+ {
+ UInt16 skeletonIndex = task.skeletonIndices[i];
+ xform2unity (animatedPose->m_X[skeletonIndex], task.outPose[i]);
+ }
+
+ MultiplyMatrixArrayWithBase4x4 (&task.rootPose, task.outPose, task.bindPose, task.outPose, task.bindPoseCount);
+ return NULL;
+}
+
+static void CalculateDefaultPoseWorldSpaceMatrices (
+ const Transform& transform,
+ const mecanim::animation::AvatarConstant* avatarConstant,
+ const UInt16* skeletonIndices,
+ Matrix4x4f* outWorldSpaceMatrices,
+ size_t size)
+{
+ // Extract default skeleton pose from avatar and setup root position according to transform.
+ Assert (avatarConstant);
+
+ mecanim::memory::MecanimAllocator tempAlloc (kMemTempAlloc);
+ mecanim::skeleton::SkeletonPose* tempDefaultGPose = mecanim::skeleton::CreateSkeletonPose(avatarConstant->m_AvatarSkeleton.Get(), tempAlloc);
+
+ SkeletonPoseCopy (avatarConstant->m_DefaultPose.Get(), tempDefaultGPose);
+ tempDefaultGPose->m_X[0] = xformFromUnity (transform.GetPosition(), transform.GetRotation(), transform.GetWorldScaleLossy());
+ mecanim::skeleton::SkeletonPoseComputeGlobal (avatarConstant->m_AvatarSkeleton.Get(), tempDefaultGPose, tempDefaultGPose);
+ for (int i=0;i<size;i++)
+ {
+ UInt16 skeletonIndex = skeletonIndices[i];
+ xform2unity (tempDefaultGPose->m_X[skeletonIndex], outWorldSpaceMatrices[i]);
+ }
+
+ mecanim::skeleton::DestroySkeletonPose(tempDefaultGPose, tempAlloc);
+}
+
+bool CalculateWordSpaceMatrices (Animator* animator, const UInt16* skeletonIndices, Matrix4x4f* outWorldSpaceMatrices, size_t size)
+{
+ const mecanim::skeleton::SkeletonPose* animatedPose = animator->GetGlobalSpaceSkeletonPose ();
+
+ if (animatedPose)
+ {
+ for (int i=0;i<size;i++)
+ {
+ UInt16 skeletonIndex = skeletonIndices[i];
+ xform2unity (animatedPose->m_X[skeletonIndex], outWorldSpaceMatrices[i]);
+ }
+ }
+ else
+ {
+ const mecanim::animation::AvatarConstant* avatarConstant = animator->GetAvatarConstant ();
+ if (avatarConstant == NULL)
+ {
+ // Slow code path:
+ Avatar* avatar = animator->GetAvatar ();
+ if (avatar)
+ avatarConstant = avatar->GetAsset ();
+ if (avatarConstant == NULL)
+ return false;
+ }
+ CalculateDefaultPoseWorldSpaceMatrices (animator->GetComponent(Transform), avatarConstant, skeletonIndices, outWorldSpaceMatrices, size);
+ }
+ return true;
+}