summaryrefslogtreecommitdiff
path: root/Runtime/mecanim/animation/blendtree.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/mecanim/animation/blendtree.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/mecanim/animation/blendtree.h')
-rw-r--r--Runtime/mecanim/animation/blendtree.h285
1 files changed, 285 insertions, 0 deletions
diff --git a/Runtime/mecanim/animation/blendtree.h b/Runtime/mecanim/animation/blendtree.h
new file mode 100644
index 0000000..ee3f7a5
--- /dev/null
+++ b/Runtime/mecanim/animation/blendtree.h
@@ -0,0 +1,285 @@
+#pragma once
+
+#include "Runtime/mecanim/defs.h"
+#include "Runtime/mecanim/memory.h"
+#include "Runtime/mecanim/types.h"
+#include "Runtime/mecanim/animation/curvedata.h"
+#include "Runtime/mecanim/human/human.h"
+#include "Runtime/mecanim/human/hand.h"
+#include "Runtime/Math/Vector2.h"
+
+#include "Runtime/Serialize/Blobification/offsetptr.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#include "Runtime/Animation/MecanimArraySerialization.h"
+
+namespace mecanim
+{
+
+namespace animation
+{
+ struct MotionNeighborList
+ {
+ DEFINE_GET_TYPESTRING(MotionNeighborList)
+
+ MotionNeighborList() : m_Count(0)
+ {
+ }
+
+ uint32_t m_Count;
+ OffsetPtr<uint32_t> m_NeighborArray;
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ TRANSFER_BLOB_ONLY(m_Count);
+ MANUAL_ARRAY_TRANSFER2(uint32_t, m_NeighborArray, m_Count);
+ }
+ };
+
+ // Constant data for 1D blend node types - thresholds
+ struct Blend1dDataConstant
+ {
+ DEFINE_GET_TYPESTRING(Blend2dDataConstant)
+
+ Blend1dDataConstant() : m_ChildCount(0)
+ {
+ }
+
+ uint32_t m_ChildCount;
+ OffsetPtr<float> m_ChildThresholdArray;
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ TRANSFER_BLOB_ONLY(m_ChildCount);
+ MANUAL_ARRAY_TRANSFER2(float, m_ChildThresholdArray, m_ChildCount);
+ }
+ };
+
+ // Constant data for 2D blend node types - positions plus precomputed data to speed up blending
+ struct Blend2dDataConstant
+ {
+ DEFINE_GET_TYPESTRING(Blend2dDataConstant)
+
+ Blend2dDataConstant() : m_ChildCount(0), m_ChildMagnitudeCount(0), m_ChildPairVectorCount(0), m_ChildPairAvgMagInvCount(0), m_ChildNeighborListCount(0)
+ {
+ }
+
+ uint32_t m_ChildCount;
+ OffsetPtr<Vector2f> m_ChildPositionArray;
+
+ uint32_t m_ChildMagnitudeCount;
+ OffsetPtr<float> m_ChildMagnitudeArray; // Used by type 2
+ uint32_t m_ChildPairVectorCount;
+ OffsetPtr<Vector2f> m_ChildPairVectorArray; // Used by type 2, (3 TODO)
+ uint32_t m_ChildPairAvgMagInvCount;
+ OffsetPtr<float> m_ChildPairAvgMagInvArray; // Used by type 2
+ uint32_t m_ChildNeighborListCount;
+ OffsetPtr<MotionNeighborList> m_ChildNeighborListArray; // Used by type 2, (3 TODO)
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ TRANSFER_BLOB_ONLY(m_ChildCount);
+ MANUAL_ARRAY_TRANSFER2(Vector2f, m_ChildPositionArray, m_ChildCount);
+
+ TRANSFER_BLOB_ONLY(m_ChildMagnitudeCount);
+ MANUAL_ARRAY_TRANSFER2(float, m_ChildMagnitudeArray, m_ChildMagnitudeCount);
+ TRANSFER_BLOB_ONLY(m_ChildPairVectorCount);
+ MANUAL_ARRAY_TRANSFER2(Vector2f, m_ChildPairVectorArray, m_ChildPairVectorCount);
+ TRANSFER_BLOB_ONLY(m_ChildPairAvgMagInvCount);
+ MANUAL_ARRAY_TRANSFER2(float, m_ChildPairAvgMagInvArray, m_ChildPairAvgMagInvCount);
+ TRANSFER_BLOB_ONLY(m_ChildNeighborListCount);
+ MANUAL_ARRAY_TRANSFER2(MotionNeighborList, m_ChildNeighborListArray, m_ChildNeighborListCount);
+ }
+ };
+
+ struct BlendTreeNodeConstant
+ {
+ DEFINE_GET_TYPESTRING(BlendTreeNodeConstant)
+
+ BlendTreeNodeConstant(): m_BlendType(0), m_BlendEventID(-1), m_BlendEventYID(-1), m_ChildCount(0), m_ClipID(-1), m_Duration(0), m_CycleOffset(0), m_Mirror(false)
+ {
+
+ }
+
+ uint32_t m_BlendType;
+
+ uint32_t m_BlendEventID;
+ uint32_t m_BlendEventYID;
+ uint32_t m_ChildCount;
+ OffsetPtr<uint32_t> m_ChildIndices;
+
+ OffsetPtr<Blend1dDataConstant> m_Blend1dData;
+ OffsetPtr<Blend2dDataConstant> m_Blend2dData;
+
+ uint32_t m_ClipID; // assert( m_ClipID != -1 && mClipBlendCount == 0)
+ float m_Duration;
+ float m_CycleOffset;
+ bool m_Mirror;
+
+ // Unity 4.1 introduced 2D blendtrees. The data layout has been changed there.
+ template<class TransferFunction>
+ inline void Transfer_4_0_BackwardsCompatibility (TransferFunction& transfer)
+ {
+ if (transfer.IsOldVersion(1))
+ {
+ if (m_Blend1dData.IsNull())
+ {
+ mecanim::memory::ChainedAllocator* allocator = static_cast<mecanim::memory::ChainedAllocator*> (transfer.GetUserData());
+ m_Blend1dData = allocator->Construct<Blend1dDataConstant>();
+ }
+
+ OffsetPtr<float>& m_ChildThresholdArray = m_Blend1dData->m_ChildThresholdArray;
+ MANUAL_ARRAY_TRANSFER2(float, m_ChildThresholdArray, m_Blend1dData->m_ChildCount);
+ }
+ }
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ transfer.SetVersion(2);
+
+ TRANSFER(m_BlendType);
+ TRANSFER(m_BlendEventID);
+ TRANSFER(m_BlendEventYID);
+
+ TRANSFER_BLOB_ONLY(m_ChildCount);
+ MANUAL_ARRAY_TRANSFER2(uint32_t, m_ChildIndices, m_ChildCount);
+
+ TRANSFER(m_Blend1dData);
+ TRANSFER(m_Blend2dData);
+
+ TRANSFER(m_ClipID);
+ TRANSFER(m_Duration);
+
+ TRANSFER(m_CycleOffset);
+ TRANSFER(m_Mirror);
+ transfer.Align();
+
+ Transfer_4_0_BackwardsCompatibility(transfer);
+
+ }
+ };
+
+ struct BlendTreeConstant
+ {
+ DEFINE_GET_TYPESTRING(BlendTreeConstant)
+
+ BlendTreeConstant () :m_NodeCount(0)
+ {
+ }
+
+ uint32_t m_NodeCount;
+ OffsetPtr< OffsetPtr<BlendTreeNodeConstant> > m_NodeArray;
+
+ OffsetPtr<ValueArrayConstant> m_BlendEventArrayConstant;
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ TRANSFER_BLOB_ONLY(m_NodeCount);
+ MANUAL_ARRAY_TRANSFER2( OffsetPtr<mecanim::animation::BlendTreeNodeConstant>, m_NodeArray, m_NodeCount);
+
+ TRANSFER(m_BlendEventArrayConstant);
+ }
+ };
+
+ struct BlendTreeMemory
+ {
+ DEFINE_GET_TYPESTRING(BlendTreeMemory)
+
+ BlendTreeMemory() : m_NodeCount(0) {}
+
+ uint32_t m_NodeCount;
+ OffsetPtr<float> m_NodeDurationArray;
+
+ template<class TransferFunction>
+ inline void Transfer (TransferFunction& transfer)
+ {
+ TRANSFER_BLOB_ONLY(m_NodeCount);
+ MANUAL_ARRAY_TRANSFER2(float, m_NodeDurationArray, m_NodeCount);
+ }
+ };
+
+ struct BlendTreeInput
+ {
+ BlendTreeInput() : m_BlendValueArray(0)
+ {
+ }
+
+ ValueArray* m_BlendValueArray;
+ };
+
+ struct BlendTreeNodeOutput
+ {
+ BlendTreeNodeOutput() : m_BlendValue(0), m_ID(0), m_Reverse(false), m_Mirror(false), m_CycleOffset(0)
+ {
+
+ }
+
+ float m_BlendValue;
+ uint32_t m_ID;
+ bool m_Reverse;
+ bool m_Mirror;
+ float m_CycleOffset;
+ };
+
+ struct BlendTreeOutput
+ {
+ BlendTreeOutput() : m_Duration(0),
+ m_MaxBlendedClip(0)
+ {}
+
+ BlendTreeNodeOutput* m_OutputBlendArray;
+ uint32_t m_MaxBlendedClip;
+ float m_Duration;
+ };
+
+ struct BlendTreeWorkspace
+ {
+ BlendTreeWorkspace() : m_BlendArray(0), m_TempWeightArray(0), m_TempCropArray(0), m_ChildInputVectorArray(0)
+ {
+
+ }
+
+
+ float* m_BlendArray;
+ float* m_TempWeightArray;
+ int* m_TempCropArray;
+ Vector2f* m_ChildInputVectorArray;
+ };
+
+ void GetWeights (const BlendTreeNodeConstant& nodeConstant, BlendTreeWorkspace &workspace, float* weightArray, float blendValueX, float blendValueY);
+
+ // Overload for creating 1D blend node
+ BlendTreeNodeConstant* CreateBlendTreeNodeConstant(uint32_t blendValueID, uint32_t childCount, uint32_t* childIndices, float* blendTreeThresholdArray, memory::Allocator& alloc);
+ // Overload for creating 2D blend node
+ BlendTreeNodeConstant* CreateBlendTreeNodeConstant(uint32_t blendValueID, uint32_t blendValueYID, int blendType, uint32_t childCount, uint32_t* childIndices, Vector2f* blendTreePositionArray, memory::Allocator& alloc);
+ // Overload for creating leaf blend node
+ BlendTreeNodeConstant* CreateBlendTreeNodeConstant(uint32_t clipID, float duration, bool mirror, float cycle, memory::Allocator& alloc);
+
+ BlendTreeConstant* CreateBlendTreeConstant(BlendTreeNodeConstant** nodeArray, uint32_t nodeCount, memory::Allocator& alloc);
+ BlendTreeConstant* CreateBlendTreeConstant(uint32_t clipID, memory::Allocator& alloc);
+ void DestroyBlendTreeConstant(BlendTreeConstant * constant, memory::Allocator& alloc);
+
+ BlendTreeMemory* CreateBlendTreeMemory(BlendTreeConstant const* constant, memory::Allocator& alloc);
+ void DestroyBlendTreeMemory(BlendTreeMemory *memory, memory::Allocator& alloc);
+
+ BlendTreeInput* CreateBlendTreeInput(BlendTreeConstant const* constant, memory::Allocator& alloc);
+ void DestroyBlendTreeInput(BlendTreeInput * input, memory::Allocator& alloc);
+
+ BlendTreeOutput* CreateBlendTreeOutput(BlendTreeConstant const* constant, uint32_t maxBlendedClip, memory::Allocator& alloc);
+ void DestroyBlendTreeOutput(BlendTreeOutput * output, memory::Allocator& alloc);
+
+ BlendTreeWorkspace* CreateBlendTreeWorkspace(BlendTreeConstant const* constant, memory::Allocator& alloc);
+ void DestroyBlendTreeWorkspace(BlendTreeWorkspace * workspace, memory::Allocator& alloc);
+
+
+ void EvaluateBlendTree(const BlendTreeConstant& constant, const BlendTreeInput &input, const BlendTreeMemory &memory, BlendTreeOutput &output, BlendTreeWorkspace &workspace);
+
+ mecanim::uint32_t GetLeafCount(const BlendTreeConstant& constant);
+ void FillLeafIDArray(const BlendTreeConstant& constant, uint32_t* leafIDArray);
+ mecanim::uint32_t GetMaxBlendCount(const BlendTreeConstant& constant);
+}
+}