summaryrefslogtreecommitdiff
path: root/Runtime/mecanim/animation/poseblender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/mecanim/animation/poseblender.cpp')
-rw-r--r--Runtime/mecanim/animation/poseblender.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/Runtime/mecanim/animation/poseblender.cpp b/Runtime/mecanim/animation/poseblender.cpp
new file mode 100644
index 0000000..ccbdf8f
--- /dev/null
+++ b/Runtime/mecanim/animation/poseblender.cpp
@@ -0,0 +1,228 @@
+#include "UnityPrefix.h"
+#include "Runtime/mecanim/skeleton/skeleton.h"
+
+#include "Runtime/mecanim/graph/plugbinder.h"
+#include "Runtime/mecanim/animation/common.h"
+#include "Runtime/mecanim/animation/poseblender.h"
+
+namespace mecanim
+{
+
+namespace animation
+{
+ namespace
+ {
+ void SetPoseBlenderValue(graph::GraphPlug const* plug, uint32_t index, PoseBlenderInput const* input, graph::EvaluationGraphWorkspace* graphMemory)
+ {
+ float value;
+ plug->ReadData(&value, graphMemory->m_EvaluationInfo);
+ input->m_WeightArray[index] += value;
+ }
+ }
+
+ PoseBlenderConstant* CreatePoseBlenderConstant(skeleton::Skeleton * skeleton, skeleton::SkeletonPose* defaultPose, skeleton::SkeletonPose** arrayPose, uint32_t count, graph::Graph* graph, memory::Allocator& alloc)
+ {
+ PoseBlenderConstant *cst = alloc.Construct<PoseBlenderConstant>();
+
+ cst->m_Skeleton = skeleton;
+ cst->m_SkeletonPoseCount = count;
+
+ cst->m_DefaultSkeletonPose = defaultPose;
+ cst->m_SkeletonPoseArray = alloc.ConstructArray<skeleton::SkeletonPose*>(count);
+ cst->m_PosesID = alloc.ConstructArray<uint32_t>(count);
+ cst->m_HasGraph = graph != 0;
+ cst->m_Graph = graph;
+
+ uint32_t i;
+ for(i=0;i<count;i++)
+ {
+ cst->m_SkeletonPoseArray[i] = arrayPose[i];
+ }
+
+ if(cst->m_HasGraph)
+ {
+ cst->m_ValuesConstant = CreateValueArrayConstant(kFloatType, cst->m_Graph->m_InEdgesCount, alloc);
+ for(i=0;i<cst->m_Graph->m_InEdgesCount;++i)
+ {
+ cst->m_ValuesConstant->m_ValueArray[i].m_ID = cst->m_Graph->m_InEdges[i].m_Binding;
+ }
+ }
+
+ return cst;
+ }
+
+ void DestroyPoseBlenderConstant(PoseBlenderConstant * constant, memory::Allocator& alloc)
+ {
+ if(constant)
+ {
+ alloc.Deallocate(constant->m_PosesID);
+ alloc.Deallocate(constant->m_SkeletonPoseArray);
+ alloc.Deallocate(constant);
+ }
+ }
+
+ void InitializePoseBlenderConstant(PoseBlenderConstant * constant, graph::GraphFactory const& factory, memory::Allocator& alloc)
+ {
+ if(constant->m_Graph)
+ {
+ constant->m_EvaluationGraph = graph::CreateEvaluationGraph(constant->m_Graph, factory, alloc);
+ }
+ }
+
+ void ClearPoseBlenderConstant(PoseBlenderConstant * constant, memory::Allocator& alloc)
+ {
+ if(constant->m_EvaluationGraph)
+ {
+ graph::DestroyEvaluationGraph(constant->m_EvaluationGraph, alloc);
+ constant->m_EvaluationGraph = 0;
+ }
+ }
+
+ PoseBlenderInput* CreatePoseBlenderInput(PoseBlenderConstant const* constant, memory::Allocator& alloc)
+ {
+ PoseBlenderInput *in = alloc.Construct<PoseBlenderInput>();
+
+ if(constant->m_ValuesConstant)
+ {
+ in->m_Values = CreateValueArray(constant->m_ValuesConstant, alloc);
+ }
+ in->m_WeightPoseCount = constant->m_SkeletonPoseCount;
+ in->m_SkeletonPose = skeleton::CreateSkeletonPose(constant->m_Skeleton, alloc);
+ in->m_WeightArray = alloc.ConstructArray<float>(constant->m_SkeletonPoseCount);
+
+ uint32_t i;
+ for(i=0;i<in->m_WeightPoseCount;i++)
+ {
+ in->m_WeightArray[i] = 0.f;
+ }
+
+ return in;
+ }
+
+ void DestroyPoseBlenderInput(PoseBlenderInput * input, memory::Allocator& alloc)
+ {
+ if(input)
+ {
+ skeleton::DestroySkeletonPose(input->m_SkeletonPose, alloc);
+ alloc.Deallocate(input->m_WeightArray);
+ alloc.Deallocate(input);
+ }
+ }
+
+ PoseBlenderWorkspace* CreatePoseBlenderWorkspace(PoseBlenderConstant const* constant, memory::Allocator& alloc)
+ {
+ PoseBlenderWorkspace *ws = alloc.Construct<PoseBlenderWorkspace>();
+ ws->m_SkeletonPose = skeleton::CreateSkeletonPose(constant->m_Skeleton, alloc);
+
+ return ws;
+ }
+ void DestroyPoseBlenderWorkspace(PoseBlenderWorkspace * workspace, memory::Allocator& alloc)
+ {
+ if(workspace)
+ {
+ skeleton::DestroySkeletonPose(workspace->m_SkeletonPose, alloc);
+ alloc.Deallocate(workspace);
+ }
+ }
+
+ PoseBlenderMemory* CreatePoseBlenderMemory(PoseBlenderConstant const* constant, memory::Allocator& alloc)
+ {
+ PoseBlenderMemory* mem = alloc.Construct<PoseBlenderMemory>();
+
+ if(constant->m_EvaluationGraph)
+ {
+ mem->m_GraphWS = graph::CreateEvaluationGraphWorkspace(constant->m_EvaluationGraph, alloc);
+ mem->m_InputPoseBlenderBindingCount = 0;
+ uint32_t i,j;
+ for(i=0;i<constant->m_EvaluationGraph->m_Output->mPlugCount;i++)
+ {
+ graph::GraphPlug const* plug = constant->m_EvaluationGraph->m_Output->mPlugArray[i];
+ for(j=0;j<constant->m_SkeletonPoseCount;j++)
+ {
+ if( plug->m_ID == constant->m_PosesID[j])
+ {
+ mem->m_InputPoseBlenderBindingCount++;
+ }
+ }
+ }
+ if(mem->m_InputPoseBlenderBindingCount)
+ {
+ mem->m_InputPoseBlenderBinding = alloc.ConstructArray<SetPoseBlenderInput2>(mem->m_InputPoseBlenderBindingCount);
+ uint32_t k = 0;
+ for(i=0;i<constant->m_EvaluationGraph->m_Output->mPlugCount;i++)
+ {
+ graph::GraphPlug const* plug = constant->m_EvaluationGraph->m_Output->mPlugArray[i];
+ for(j=0;j<constant->m_SkeletonPoseCount;j++)
+ {
+ if( plug->m_ID == constant->m_PosesID[j])
+ {
+ mem->m_InputPoseBlenderBinding[k++] = bind( SetPoseBlenderValue, plug, j);
+ }
+ }
+ }
+ }
+ }
+
+ return mem;
+ }
+
+ void DestroyPoseBlenderMemory(PoseBlenderMemory* memory, memory::Allocator& alloc)
+ {
+ if(memory)
+ {
+ graph::DestroyEvaluationGraphWorkspace(memory->m_GraphWS, alloc);
+ alloc.Deallocate(memory->m_InputPoseBlenderBinding);
+ alloc.Deallocate(memory);
+ }
+ }
+
+
+ PoseBlenderOutput* CreatePoseBlenderOutput(PoseBlenderConstant const* constant, memory::Allocator& alloc)
+ {
+ PoseBlenderOutput *out = alloc.Construct<PoseBlenderOutput>();
+ out->m_SkeletonPose = skeleton::CreateSkeletonPose(constant->m_Skeleton, alloc);
+
+ return out;
+ }
+
+ void DestroyPoseBlenderOutput(PoseBlenderOutput * output, memory::Allocator& alloc)
+ {
+ if(output)
+ {
+ skeleton::DestroySkeletonPose(output->m_SkeletonPose, alloc);
+ alloc.Deallocate(output);
+ }
+ }
+
+ void EvaluatePoseBlender(PoseBlenderConstant const * constant, PoseBlenderInput const * input, PoseBlenderOutput * output, PoseBlenderMemory* memory, PoseBlenderWorkspace * workspace)
+ {
+ if(constant->m_EvaluationGraph)
+ {
+ memory->m_GraphWS->m_EvaluationInfo.m_EvaluationId++;
+
+ // Value Array is constructed based on graph so they should be sync
+ uint32_t i, count = constant->m_ValuesConstant->m_Count;
+ for(i=0;i<count;i++)
+ {
+ SetPlugValue(&constant->m_EvaluationGraph->m_Input->GetPlug(i), i, input->m_Values, memory->m_GraphWS);
+ }
+
+ count = memory->m_InputPoseBlenderBindingCount;
+ for(i=0;i<count;i++)
+ {
+ memory->m_InputPoseBlenderBinding[i](input, memory->m_GraphWS);
+ }
+ }
+
+ skeleton::SkeletonPoseCopy(input->m_SkeletonPose, output->m_SkeletonPose);
+ uint32_t i;
+ for(i = 0; i < constant->m_SkeletonPoseCount; i++)
+ {
+ skeleton::SkeletonPoseSub(constant->m_SkeletonPoseArray[i], input->m_SkeletonPose, workspace->m_SkeletonPose);
+ skeleton::SkeletonPoseWeight(workspace->m_SkeletonPose, math::float1(input->m_WeightArray[i]), workspace->m_SkeletonPose);
+ skeleton::SkeletonPoseAdd(output->m_SkeletonPose, workspace->m_SkeletonPose, output->m_SkeletonPose);
+ }
+ }
+}
+
+}