diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/mecanim/animation/poseblender.cpp |
Diffstat (limited to 'Runtime/mecanim/animation/poseblender.cpp')
-rw-r--r-- | Runtime/mecanim/animation/poseblender.cpp | 228 |
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); + } + } +} + +} |