diff options
Diffstat (limited to 'Runtime/mecanim/graph')
-rw-r--r-- | Runtime/mecanim/graph/binarynode.h | 291 | ||||
-rw-r--r-- | Runtime/mecanim/graph/factory.cpp | 172 | ||||
-rw-r--r-- | Runtime/mecanim/graph/factory.h | 35 | ||||
-rw-r--r-- | Runtime/mecanim/graph/genericnode.h | 1093 | ||||
-rw-r--r-- | Runtime/mecanim/graph/graph.cpp | 476 | ||||
-rw-r--r-- | Runtime/mecanim/graph/graph.h | 188 | ||||
-rw-r--r-- | Runtime/mecanim/graph/node.cpp | 11 | ||||
-rw-r--r-- | Runtime/mecanim/graph/node.h | 346 | ||||
-rw-r--r-- | Runtime/mecanim/graph/plug.h | 123 | ||||
-rw-r--r-- | Runtime/mecanim/graph/plugbinder.cpp | 180 | ||||
-rw-r--r-- | Runtime/mecanim/graph/plugbinder.h | 85 | ||||
-rw-r--r-- | Runtime/mecanim/graph/quaternionnode.h | 283 | ||||
-rw-r--r-- | Runtime/mecanim/graph/unarynode.h | 112 | ||||
-rw-r--r-- | Runtime/mecanim/graph/xformnode.h | 348 |
14 files changed, 3743 insertions, 0 deletions
diff --git a/Runtime/mecanim/graph/binarynode.h b/Runtime/mecanim/graph/binarynode.h new file mode 100644 index 0000000..82ff596 --- /dev/null +++ b/Runtime/mecanim/graph/binarynode.h @@ -0,0 +1,291 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/float4.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" + +namespace mecanim +{ + +namespace graph +{ + template <typename TYPE1, typename TYPE2, typename RESULT, typename BinaryPolicies> class BinaryNode : public Node + { + public: + TypePlug<TYPE1> mA; + TypePlug<TYPE2> mB; + + TypePlug<RESULT> mResult; + + BinaryNode() + :mA(true, CRCKey(eA) ), + mB(true,CRCKey(eB)), + mResult(false,CRCKey(eResult)) + { + mA.m_Owner = this; + mB.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~BinaryNode(){} + + virtual uint32_t GetPlugCount()const + { + return 3; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mA; + case 1: return mB; + case 2: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mA; + case 1: return mB; + case 2: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + TYPE1 a; + TYPE2 b; + RESULT result; + + mA.ReadData(&a, arEvaluationInfo); + mB.ReadData(&b, arEvaluationInfo); + + result = BinaryPolicies::template Operation<TYPE1, TYPE2, RESULT>(a, b); + + mResult.WriteData(&result, arEvaluationInfo); + } + }; + + class AdditionOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l+r; } + }; + + class SubstractionOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l-r; } + }; + + class MultiplicationOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l*r; } + }; + + class DivisionOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l/r; } + }; + + class GreaterThanOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l > r; } + }; + class LesserThanOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l < r; } + }; + class GreaterThanOrEqualOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l >= r; } + }; + class LesserThanOrEqualOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l <= r; } + }; + class AndOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l && r; } + }; + class OrOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return l || r; } + }; + class XorOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return ((!l)&&r)||(l&&(!r)); } + }; + + class AdditionFloat : public BinaryNode<float, float, float, AdditionOp> + { + public: + static const eNodeType mId = AdditionFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class AdditionUInt : public BinaryNode<uint32_t, uint32_t, uint32_t,AdditionOp> + { + public: + static const eNodeType mId = AdditionUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class AdditionInt : public BinaryNode<int32_t, int32_t, int32_t, AdditionOp> + { + public: + static const eNodeType mId = AdditionIntId; + virtual eNodeType NodeType(){return mId;} + }; + class AdditionFloat4 : public BinaryNode<math::float4, math::float4, math::float4, AdditionOp> + { + public: + static const eNodeType mId = AdditionFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class SubstractionFloat : public BinaryNode<float, float, float, SubstractionOp> + { + public: + static const eNodeType mId = SubstractionFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class SubstractionUInt : public BinaryNode<uint32_t, uint32_t, uint32_t, SubstractionOp> + { + public: + static const eNodeType mId = SubstractionUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class SubstractionInt : public BinaryNode<int32_t, int32_t, int32_t, SubstractionOp> + { + public: + static const eNodeType mId = SubstractionIntId; + virtual eNodeType NodeType(){return mId;} + }; + class SubstractionFloat4 : public BinaryNode<math::float4, math::float4, math::float4, SubstractionOp> + { + public: + static const eNodeType mId = SubstractionFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class MultiplicationFloat : public BinaryNode<float, float, float, MultiplicationOp> + { + public: + static const eNodeType mId = MultiplicationFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class MultiplicationUInt : public BinaryNode<uint32_t, uint32_t, uint32_t, MultiplicationOp> + { + public: + static const eNodeType mId = MultiplicationUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MultiplicationInt : public BinaryNode<int32_t, int32_t, int32_t, MultiplicationOp> + { + public: + static const eNodeType mId = MultiplicationIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MultiplicationFloat4 : public BinaryNode<math::float4, math::float4, math::float4, MultiplicationOp> + { + public: + static const eNodeType mId = MultiplicationFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class DivisionFloat : public BinaryNode<float, float, float, DivisionOp> + { + public: + static const eNodeType mId = DivisionFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class DivisionUInt : public BinaryNode<uint32_t, uint32_t, uint32_t, DivisionOp> + { + public: + static const eNodeType mId = DivisionUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class DivisionInt : public BinaryNode<int32_t, int32_t, int32_t, DivisionOp> + { + public: + static const eNodeType mId = DivisionIntId; + virtual eNodeType NodeType(){return mId;} + }; + class DivisionFloat4 : public BinaryNode<math::float4, math::float4, math::float4, DivisionOp> + { + public: + static const eNodeType mId = DivisionFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class GreaterThan : public BinaryNode<float, float, bool, GreaterThanOp> + { + public: + static const eNodeType mId = GreaterThanId; + virtual eNodeType NodeType(){return mId;} + }; + + class LesserThan : public BinaryNode<float, float, bool, LesserThanOp> + { + public: + static const eNodeType mId = LesserThanId; + virtual eNodeType NodeType(){return mId;} + }; + + class GreaterThanOrEqual : public BinaryNode<float, float, bool, GreaterThanOrEqualOp> + { + public: + static const eNodeType mId = GreaterThanOrEqualId; + virtual eNodeType NodeType(){return mId;} + }; + + class LesserThanOrEqual : public BinaryNode<float, float, bool, LesserThanOrEqualOp> + { + public: + static const eNodeType mId = LesserThanOrEqualId; + virtual eNodeType NodeType(){return mId;} + }; + + class And : public BinaryNode<bool, bool, bool, AndOp> + { + public: + static const eNodeType mId = AndId; + virtual eNodeType NodeType(){return mId;} + }; + + class Or : public BinaryNode<bool, bool, bool, OrOp> + { + public: + static const eNodeType mId = OrId; + virtual eNodeType NodeType(){return mId;} + }; + class Xor : public BinaryNode<bool, bool, bool, XorOp> + { + public: + static const eNodeType mId = XorId; + virtual eNodeType NodeType(){return mId;} + }; +} + +}
\ No newline at end of file diff --git a/Runtime/mecanim/graph/factory.cpp b/Runtime/mecanim/graph/factory.cpp new file mode 100644 index 0000000..3efe757 --- /dev/null +++ b/Runtime/mecanim/graph/factory.cpp @@ -0,0 +1,172 @@ +#include "UnityPrefix.h" +#include "Runtime/mecanim/graph/factory.h" + +#include "Runtime/mecanim/graph/unarynode.h" +#include "Runtime/mecanim/graph/binarynode.h" +#include "Runtime/mecanim/graph/genericnode.h" +#include "Runtime/mecanim/graph/xformnode.h" +#include "Runtime/mecanim/graph/quaternionnode.h" + +#define REGISTERNODE(classnode) \ + case classnode::mId: \ + { \ + node = arAlloc.Construct<classnode>(); \ + break; \ + } + +namespace mecanim +{ + +namespace graph +{ + Node* GraphFactory::Create(eNodeType aNodeId, memory::Allocator& arAlloc)const + { + Node* node = 0; + switch(aNodeId) + { + REGISTERNODE(NegationFloat); + REGISTERNODE(NegationInt); + REGISTERNODE(NegationFloat4); + REGISTERNODE(NegationBool); + REGISTERNODE(AdditionFloat); + REGISTERNODE(AdditionUInt); + REGISTERNODE(AdditionInt); + REGISTERNODE(AdditionFloat4); + REGISTERNODE(SubstractionFloat); + REGISTERNODE(SubstractionUInt); + REGISTERNODE(SubstractionInt); + REGISTERNODE(SubstractionFloat4); + REGISTERNODE(MultiplicationFloat); + REGISTERNODE(MultiplicationUInt); + REGISTERNODE(MultiplicationInt); + REGISTERNODE(MultiplicationFloat4); + REGISTERNODE(DivisionFloat); + REGISTERNODE(DivisionUInt); + REGISTERNODE(DivisionInt); + REGISTERNODE(DivisionFloat4); + REGISTERNODE(CondFloat); + REGISTERNODE(CondUInt); + REGISTERNODE(CondInt); + REGISTERNODE(CondFloat4); + REGISTERNODE(AbsFloat); + REGISTERNODE(AbsFloat4); + REGISTERNODE(CrossFloat4); + REGISTERNODE(DegreesFloat); + REGISTERNODE(DegreesFloat4); + REGISTERNODE(DotFloat4); + REGISTERNODE(LengthFloat4); + REGISTERNODE(MaximumFloat); + REGISTERNODE(MaximumUInt); + REGISTERNODE(MaximumInt); + REGISTERNODE(MaximumFloat4); + REGISTERNODE(MinimumFloat); + REGISTERNODE(MinimumUInt); + REGISTERNODE(MinimumInt); + REGISTERNODE(MinimumFloat4); + REGISTERNODE(NormalizeFloat4); + REGISTERNODE(RadiansFloat); + REGISTERNODE(RadiansFloat4); + REGISTERNODE(FloatToFloat4); + REGISTERNODE(Float4ToFloat); + REGISTERNODE(GreaterThan); + REGISTERNODE(LesserThan); + REGISTERNODE(GreaterThanOrEqual); + REGISTERNODE(LesserThanOrEqual); + REGISTERNODE(SmoothStepFloat); + REGISTERNODE(Mux5Float); + REGISTERNODE(Mul5Float); + REGISTERNODE(Sin); + REGISTERNODE(Fmod); + REGISTERNODE(And); + REGISTERNODE(Or); + REGISTERNODE(xformMulInv); + REGISTERNODE(xformIdentity); + REGISTERNODE(xformMulVec); + REGISTERNODE(xformInvMulVec); + REGISTERNODE(xformMul); + REGISTERNODE(xformInvMul); + REGISTERNODE(xformEqual); + REGISTERNODE(xformWeight); + REGISTERNODE(xformAdd); + REGISTERNODE(xformSub); + REGISTERNODE(xformBlend); + REGISTERNODE(quatIdentity); + REGISTERNODE(quatConj); + REGISTERNODE(quatMul); + REGISTERNODE(quatMulVec); + REGISTERNODE(quatLerp); + REGISTERNODE(quatArcRotate); + REGISTERNODE(quatArcRotateX); + REGISTERNODE(quatXcos); + REGISTERNODE(quatYcos); + REGISTERNODE(quatZcos); + REGISTERNODE(quatEulerToQuat); + REGISTERNODE(quatQuatToEuler); + REGISTERNODE(quatProjOnYPlane); + REGISTERNODE(quat2Qtan); + REGISTERNODE(qtan2Quat); + REGISTERNODE(ZYRoll2Quat); + REGISTERNODE(quat2ZYRoll); + REGISTERNODE(RollZY2Quat); + REGISTERNODE(quat2RollZY); + REGISTERNODE(quatWeight); + REGISTERNODE(xformCompose); + REGISTERNODE(xformDecompose); + REGISTERNODE(CondXform); + REGISTERNODE(Rand); + REGISTERNODE(Damp); + REGISTERNODE(xformRefChange); + REGISTERNODE(Xor); + REGISTERNODE(SmoothPulseFloat); + } + return node; + } + + GraphPlug* GraphFactory::Create(ePlugType aPlugType, memory::Allocator& arAlloc)const + { + GraphPlug* plug = 0; + switch(aPlugType) + { + case Float4Id: + { + plug = arAlloc.Construct< TypePlug<math::float4> >(); + break; + } + case Float1Id: + case FloatId: + { + plug = arAlloc.Construct< TypePlug<float> >(); + break; + } + case UInt32Id: + { + plug = arAlloc.Construct< TypePlug<uint32_t> >(); + break; + } + case Int32Id: + { + plug = arAlloc.Construct< TypePlug<int32_t> >(); + break; + } + case BoolId: + { + plug = arAlloc.Construct< TypePlug<bool> >(); + break; + } + case Bool4Id: + { + plug = arAlloc.Construct< TypePlug<math::bool4> >(); + break; + } + case XformId: + { + plug = arAlloc.Construct< TypePlug<math::xform> >(); + break; + } + + } + return plug; + } +} + +} diff --git a/Runtime/mecanim/graph/factory.h b/Runtime/mecanim/graph/factory.h new file mode 100644 index 0000000..d76fcbf --- /dev/null +++ b/Runtime/mecanim/graph/factory.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" + +namespace mecanim +{ + +namespace graph +{ + // This class can be subclassed if you need to create custom node and want to add them to the list of + // instanciable node + class GraphFactory + { + public: + virtual Node* Create(eNodeType aNodeId, memory::Allocator& arAlloc)const; + virtual GraphPlug* Create(ePlugType aPlugType, memory::Allocator& arAlloc)const; + }; + + template <typename TYPE> TYPE* Create(GraphFactory const& arFactory, memory::Allocator& arAlloc) + { + return static_cast<TYPE*>(arFactory.Create(TYPE::mId, arAlloc)); + } +} + +}
\ No newline at end of file diff --git a/Runtime/mecanim/graph/genericnode.h b/Runtime/mecanim/graph/genericnode.h new file mode 100644 index 0000000..2bc82e7 --- /dev/null +++ b/Runtime/mecanim/graph/genericnode.h @@ -0,0 +1,1093 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include <cstdlib> + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/math.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" + +#include "Runtime/mecanim/graph/unarynode.h" + +#include "Runtime/mecanim/generic/stringtable.h" + +namespace mecanim +{ + +namespace graph +{ + template <typename COND, typename TYPE, typename POLICIES> class CondNode : public Node + { + public: + TypePlug<COND> mCondition; + TypePlug<TYPE> mA; + TypePlug<TYPE> mB; + + TypePlug<TYPE> mResult; + + CondNode() + :mCondition(true,CRCKey(eCondition)), + mA(true, CRCKey(eA)), + mB(true,CRCKey(eB)), + mResult(false,CRCKey(eResult)) + { + mCondition.m_Owner = this; + mA.m_Owner = this; + mB.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~CondNode(){} + + virtual uint32_t GetPlugCount()const + { + return 4; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mCondition; + case 1: return mA; + case 2: return mB; + case 3: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mCondition; + case 1: return mA; + case 2: return mB; + case 3: + default: return mResult; + } + } + + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + TYPE a, b, result; + COND cond; + + mCondition.ReadData(&cond, arEvaluationInfo); + mA.ReadData(&a, arEvaluationInfo); + mB.ReadData(&b, arEvaluationInfo); + + result = POLICIES::template Operation<COND, TYPE>(cond, a, b); + + mResult.WriteData(&result, arEvaluationInfo); + } + }; + + class CondFloatOp + { + public: + template< typename COND, typename TYPE > static TYPE Operation( COND const& p, TYPE const& l, TYPE const& r){ return math::cond(p, l, r); } + }; + class CondUIntOp + { + public: + template< typename COND, typename TYPE > static TYPE Operation( COND const& p, TYPE const& l, TYPE const& r){ return math::cond(p, l, r); } + }; + class CondIntOp + { + public: + template< typename COND, typename TYPE > static TYPE Operation( COND const& p, TYPE const& l, TYPE const& r){ return math::cond(p, l, r); } + }; + class CondFloat4Op + { + public: + template< typename COND, typename TYPE > static math::float4 Operation( bool const& p, math::float4 const& l, math::float4 const& r){ return math::cond(math::bool1(p), l, r); } + }; + class CondXformOp + { + public: + template< typename COND, typename TYPE > static TYPE Operation( COND const& p, TYPE const& l, TYPE const& r){ return math::cond(p, l, r); } + }; + + class CondFloat : public CondNode<bool, float, CondFloatOp> + { + public: + static const eNodeType mId = CondFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class CondUInt : public CondNode<bool, uint32_t, CondUIntOp> + { + public: + static const eNodeType mId = CondUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class CondInt : public CondNode<bool, int32_t, CondIntOp> + { + public: + static const eNodeType mId = CondIntId; + virtual eNodeType NodeType(){return mId;} + }; + class CondFloat4 : public CondNode<bool, math::float4, CondFloat4Op> + { + public: + static const eNodeType mId = CondFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + class CondXform : public CondNode<bool, math::xform, CondXformOp> + { + public: + static const eNodeType mId = CondXformId; + virtual eNodeType NodeType(){return mId;} + }; + + template< typename TYPE, typename RESULT > class AbsOp + { + public: + static RESULT Operation( TYPE const& l){ return math::abs(l); } + }; + + class AbsFloat : public UnaryNode<float, float, AbsOp<float, float> > + { + public: + static const eNodeType mId = AbsFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class AbsFloat4 : public UnaryNode<math::float4, math::float4, AbsOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = AbsFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class CrossOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return math::cross(l, r); } + }; + + class CrossFloat4 : public BinaryNode<math::float4, math::float4, math::float4, CrossOp> + { + public: + static const eNodeType mId = CrossFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + template< typename TYPE, typename RESULT > class DegreesOp + { + public: + static RESULT Operation( TYPE const& l){ return math::degrees(l); } + }; + + class DegreesFloat : public UnaryNode<float, float, DegreesOp<float, float> > + { + public: + static const eNodeType mId = DegreesFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class DegreesFloat4 : public UnaryNode<math::float4, math::float4, DegreesOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = DegreesFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class DotOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return float(math::dot(l, r)); } + }; + + class DotFloat4 : public BinaryNode<math::float4, math::float4, float, DotOp> + { + public: + static const eNodeType mId = DotFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + template< typename TYPE, typename RESULT > class LengthOp + { + public: + static RESULT Operation( TYPE const& l){ return float(math::length(l)); } + }; + + class LengthFloat4 : public UnaryNode<math::float4, float, LengthOp<math::float4, float> > + { + public: + static const eNodeType mId = LengthFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class MaximumOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return math::maximum(l, r); } + }; + + class MaximumFloat : public BinaryNode<float, float, float, MaximumOp> + { + public: + static const eNodeType mId = MaximumFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class MaximumUInt : public BinaryNode<uint32_t, uint32_t, uint32_t, MaximumOp> + { + public: + static const eNodeType mId = MaximumUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MaximumInt : public BinaryNode<int32_t, int32_t, int32_t, MaximumOp> + { + public: + static const eNodeType mId = MaximumIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MaximumFloat4 : public BinaryNode<math::float4, math::float4, math::float4, MaximumOp> + { + public: + static const eNodeType mId = MaximumFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class MinimumOp + { + public: + template< typename TYPE1, typename TYPE2, typename RESULT > static RESULT Operation( TYPE1 const& l, TYPE2 const& r){ return math::minimum(l, r); } + }; + + class MinimumFloat : public BinaryNode<float, float, float, MinimumOp> + { + public: + static const eNodeType mId = MinimumFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class MinimumUInt : public BinaryNode<uint32_t, uint32_t, uint32_t, MinimumOp> + { + public: + static const eNodeType mId = MinimumUIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MinimumInt : public BinaryNode<int32_t, int32_t, int32_t, MinimumOp> + { + public: + static const eNodeType mId = MinimumIntId; + virtual eNodeType NodeType(){return mId;} + }; + class MinimumFloat4 : public BinaryNode<math::float4, math::float4, math::float4, MinimumOp> + { + public: + static const eNodeType mId = MinimumFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + template< typename TYPE, typename RESULT > class NormalizeOp + { + public: + static RESULT Operation( TYPE const& l){ return math::normalize(l); } + }; + + class NormalizeFloat4 : public UnaryNode<math::float4, math::float4, NormalizeOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = NormalizeFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + template< typename TYPE, typename RESULT > class RadiansOp + { + public: + static RESULT Operation( TYPE const& l){ return math::radians(l); } + }; + + class RadiansFloat : public UnaryNode<float, float, RadiansOp<float, float> > + { + public: + static const eNodeType mId = RadiansFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class RadiansFloat4 : public UnaryNode<math::float4, math::float4, RadiansOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = RadiansFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + + class Float4ToFloat : public Node + { + public: + static const eNodeType mId = Float4ToFloatId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<math::float4> mA; + TypePlug<float> mX; + TypePlug<float> mY; + TypePlug<float> mZ; + TypePlug<float> mW; + + Float4ToFloat() + :mA(true, CRCKey(eA)), + mX(false, CRCKey(eX)), + mY(false, CRCKey(eY)), + mZ(false, CRCKey(eZ)), + mW(false, CRCKey(eW)) + { + mA.m_Owner = this; + mX.m_Owner = this; + mY.m_Owner = this; + mZ.m_Owner = this; + mW.m_Owner = this; + } + + virtual ~Float4ToFloat(){} + + virtual uint32_t GetPlugCount()const + { + return 5; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mA; + case 1: return mX; + case 2: return mY; + case 3: return mZ; + case 4: + default: return mW; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mA; + case 1: return mX; + case 2: return mY; + case 3: return mZ; + case 4: + default: return mW; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + math::float4 a; + + mA.ReadData(&a, arEvaluationInfo); + + float ATTRIBUTE_ALIGN(ALIGN4F) b[4]; + + math::store(a, b); + + mX.WriteData(&b[0], arEvaluationInfo); + mY.WriteData(&b[1], arEvaluationInfo); + mZ.WriteData(&b[2], arEvaluationInfo); + mW.WriteData(&b[3], arEvaluationInfo); + } + }; + + class FloatToFloat4 : public Node + { + public: + static const eNodeType mId = FloatToFloat4Id; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mX; + TypePlug<float> mY; + TypePlug<float> mZ; + TypePlug<float> mW; + + TypePlug<math::float4> mResult; + + + FloatToFloat4() + :mX(true,CRCKey(eX)), + mY(true,CRCKey(eY)), + mZ(true,CRCKey(eZ)), + mW(true,CRCKey(eW)), + mResult(false,CRCKey(eResult)) + { + mX.m_Owner = this; + mY.m_Owner = this; + mZ.m_Owner = this; + mW.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~FloatToFloat4(){} + + virtual uint32_t GetPlugCount()const + { + return 5; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mResult; + case 1: return mX; + case 2: return mY; + case 3: return mZ; + case 4: + default: return mW; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mResult; + case 1: return mX; + case 2: return mY; + case 3: return mZ; + case 4: + default: return mW; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float ATTRIBUTE_ALIGN(ALIGN4F) a[4]; + + mX.ReadData(&a[0], arEvaluationInfo); + mY.ReadData(&a[1], arEvaluationInfo); + mZ.ReadData(&a[2], arEvaluationInfo); + mW.ReadData(&a[3], arEvaluationInfo); + + math::float4 b = math::load(a); + mResult.WriteData(&b, arEvaluationInfo); + } + }; + + + class SmoothStepFloat : public Node + { + public: + static const eNodeType mId = SmoothstepFloatId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mMin; + TypePlug<float> mMax; + TypePlug<float> mValue; + TypePlug<float> mResult; + + SmoothStepFloat() + :mMin(true, CRCKey(eMin)), + mMax(true,CRCKey(eMax)), + mValue(true,CRCKey(eValue)), + mResult(false,CRCKey(eResult)) + { + mMin.m_Owner = this; + mMax.m_Owner = this; + mValue.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~SmoothStepFloat(){} + + virtual uint32_t GetPlugCount()const + { + return 4; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mMin; + case 1: return mMax; + case 2: return mValue; + case 3: + default: return mResult; + + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mMin; + case 1: return mMax; + case 2: return mValue; + case 3: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float min, max, value; + + mMin.ReadData(&min, arEvaluationInfo); + mMax.ReadData(&max, arEvaluationInfo); + mValue.ReadData(&value, arEvaluationInfo); + + float ret = math::smoothstep( min, max, value); + + mResult.WriteData(&ret, arEvaluationInfo); + } + }; + + class SmoothPulseFloat : public Node + { + public: + static const eNodeType mId = SmoothPulseFloatId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mMinMin; + TypePlug<float> mMinMax; + TypePlug<float> mMaxMin; + TypePlug<float> mMaxMax; + TypePlug<float> mValue; + TypePlug<float> mResult; + + SmoothPulseFloat(): + mMinMin(true, CRCKey(eMinMin)), + mMinMax(true, CRCKey(eMinMax)), + mMaxMin(true, CRCKey(eMaxMin)), + mMaxMax(true, CRCKey(eMaxMax)), + mValue(true, CRCKey(eValue)), + mResult(false, CRCKey(eResult)) + { + mMinMin.m_Owner = this; + mMinMax.m_Owner = this; + mMaxMin.m_Owner = this; + mMaxMax.m_Owner = this; + mValue.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~SmoothPulseFloat(){} + + virtual uint32_t GetPlugCount()const + { + return 6; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mMinMin; + case 1: return mMinMax; + case 2: return mMaxMin; + case 3: return mMaxMax; + case 4: return mValue; + case 5: + default: return mResult; + + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mMinMin; + case 1: return mMinMax; + case 2: return mMaxMin; + case 3: return mMaxMax; + case 4: return mValue; + case 5: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float minmin, minmax, maxmin, maxmax, value; + + mMinMin.ReadData(&minmin, arEvaluationInfo); + mMinMax.ReadData(&minmax, arEvaluationInfo); + mMaxMin.ReadData(&maxmin, arEvaluationInfo); + mMaxMax.ReadData(&maxmax, arEvaluationInfo); + mValue.ReadData(&value, arEvaluationInfo); + + float ret = math::smoothpulse( minmin, minmax, maxmin, maxmax, value); + + mResult.WriteData(&ret, arEvaluationInfo); + } + }; + + class Mux5Float : public Node + { + public: + static const eNodeType mId = Mux5FloatId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mIn; + TypePlug<float> mRangeA; + TypePlug<float> mRangeB; + TypePlug<float> mRangeC; + TypePlug<float> mRangeD; + TypePlug<float> mRangeE; + TypePlug<float> mWeightA; + TypePlug<float> mWeightB; + TypePlug<float> mWeightC; + TypePlug<float> mWeightD; + TypePlug<float> mWeightE; + + Mux5Float() : mIn(true,CRCKey(eIn)), + mRangeA(true,CRCKey(eRangeA)), + mRangeB(true,CRCKey(eRangeB)), + mRangeC(true,CRCKey(eRangeC)), + mRangeD(true,CRCKey(eRangeD)), + mRangeE(true,CRCKey(eRangeE)), + mWeightA(false,CRCKey(eWeightA)), + mWeightB(false,CRCKey(eWeightB)), + mWeightC(false,CRCKey(eWeightC)), + mWeightD(false,CRCKey(eWeightD)), + mWeightE(false,CRCKey(eWeightE)) + { + mIn.m_Owner = this; + mRangeA.m_Owner = this; + mRangeB.m_Owner = this; + mRangeC.m_Owner = this; + mRangeD.m_Owner = this; + mRangeE.m_Owner = this; + mWeightA.m_Owner = this; + mWeightB.m_Owner = this; + mWeightC.m_Owner = this; + mWeightD.m_Owner = this; + mWeightE.m_Owner = this; + } + + virtual ~Mux5Float(){} + + virtual uint32_t GetPlugCount()const + { + return 11; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mIn; + case 1: return mRangeA; + case 2: return mRangeB; + case 3: return mRangeC; + case 4: return mRangeD; + case 5: return mRangeE; + case 6: return mWeightA; + case 7: return mWeightB; + case 8: return mWeightC; + case 9: return mWeightD; + case 10: + default: return mWeightE; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mIn; + case 1: return mRangeA; + case 2: return mRangeB; + case 3: return mRangeC; + case 4: return mRangeD; + case 5: return mRangeE; + case 6: return mWeightA; + case 7: return mWeightB; + case 8: return mWeightC; + case 9: return mWeightD; + case 10: + default: return mWeightE; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float in; + float r[5]; + float w[5]; + + mIn.ReadData(&in,arEvaluationInfo); + mRangeA.ReadData(&r[0],arEvaluationInfo); + mRangeB.ReadData(&r[1],arEvaluationInfo); + mRangeC.ReadData(&r[2],arEvaluationInfo); + mRangeD.ReadData(&r[3],arEvaluationInfo); + mRangeE.ReadData(&r[4],arEvaluationInfo); + + w[0] = 1.0f; + w[1] = 0.0f; + w[2] = 0.0f; + w[3] = 0.0f; + w[4] = 0.0f; + + if(in > r[0]) + { + w[0] = 0.f; + for(uint32_t i = 0; i < 4; i++) + { + float d = r[i+1] - r[i]; + + if(d > 0.0f) + { + if(in >= r[i] && in <= r[i+1]) + { + w[i] = (d-(in-r[i]))/(r[i+1]-r[i]); + w[i+1] = 1.f-w[i]; + } + } + else + { + break; + } + } + } + + mWeightA.WriteData(&w[0],arEvaluationInfo); + mWeightB.WriteData(&w[1],arEvaluationInfo); + mWeightC.WriteData(&w[2],arEvaluationInfo); + mWeightD.WriteData(&w[3],arEvaluationInfo); + mWeightE.WriteData(&w[4],arEvaluationInfo); + } + }; + + class Mul5Float : public Node + { + public: + static const eNodeType mId = Mul5FloatId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mIn; + TypePlug<float> mA; + TypePlug<float> mB; + TypePlug<float> mC; + TypePlug<float> mD; + TypePlug<float> mE; + TypePlug<float> mOutA; + TypePlug<float> mOutB; + TypePlug<float> mOutC; + TypePlug<float> mOutD; + TypePlug<float> mOutE; + + Mul5Float() : mIn(true,CRCKey(eIn)), + mA(true,CRCKey(eA)), + mB(true,CRCKey(eB)), + mC(true,CRCKey(eC)), + mD(true,CRCKey(eD)), + mE(true,CRCKey(eE)), + mOutA(false,CRCKey(eOutA)), + mOutB(false,CRCKey(eOutB)), + mOutC(false,CRCKey(eOutC)), + mOutD(false,CRCKey(eOutD)), + mOutE(false,CRCKey(eOutE)) + { + mIn.m_Owner = this; + mOutA.m_Owner = this; + mOutB.m_Owner = this; + mOutC.m_Owner = this; + mD.m_Owner = this; + mE.m_Owner = this; + mOutA.m_Owner = this; + mOutB.m_Owner = this; + mOutC.m_Owner = this; + mOutD.m_Owner = this; + mOutE.m_Owner = this; + } + + virtual ~Mul5Float(){} + + virtual uint32_t GetPlugCount()const + { + return 11; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mIn; + case 1: return mA; + case 2: return mB; + case 3: return mC; + case 4: return mD; + case 5: return mE; + case 6: return mOutA; + case 7: return mOutB; + case 8: return mOutC; + case 9: return mOutD; + case 10: + default: return mOutE; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mIn; + case 1: return mA; + case 2: return mB; + case 3: return mC; + case 4: return mD; + case 5: return mE; + case 6: return mOutA; + case 7: return mOutB; + case 8: return mOutC; + case 9: return mOutD; + case 10: + default: return mOutE; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float in; + float i[5]; + float o[5]; + + mIn.ReadData(&in,arEvaluationInfo); + mA.ReadData(&i[0],arEvaluationInfo); + mB.ReadData(&i[1],arEvaluationInfo); + mC.ReadData(&i[2],arEvaluationInfo); + mD.ReadData(&i[3],arEvaluationInfo); + mE.ReadData(&i[4],arEvaluationInfo); + + for(uint32_t iter = 0; iter < 5; iter++) + { + o[iter] = i[iter] * in; + } + + mOutA.WriteData(&o[0],arEvaluationInfo); + mOutB.WriteData(&o[1],arEvaluationInfo); + mOutC.WriteData(&o[2],arEvaluationInfo); + mOutD.WriteData(&o[3],arEvaluationInfo); + mOutE.WriteData(&o[4],arEvaluationInfo); + } + }; + + class Fmod : public Node + { + public: + static const eNodeType mId = FmodId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mNum; + TypePlug<float> mDen; + TypePlug<float> mRem; + + Fmod() : mNum(true,CRCKey(eNum)), mDen(true,CRCKey(eDen)), mRem(false, CRCKey(eRem)) + { + mNum.m_Owner = this; + mDen.m_Owner = this; + mRem.m_Owner = this; + } + + virtual ~Fmod(){} + + virtual uint32_t GetPlugCount()const + { + return 3; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mNum; + case 1: return mDen; + case 2: + default: return mRem; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mNum; + case 1: return mDen; + case 2: + default: return mRem; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float n,d,r; + + mNum.ReadData(&n, arEvaluationInfo); + mDen.ReadData(&d, arEvaluationInfo); + + r = math::fmod(n,d); + + mRem.WriteData(&r,arEvaluationInfo); + } + }; + + class Sin : public Node + { + public: + static const eNodeType mId = SinId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mIn; + TypePlug<float> mOut; + + Sin() : mIn(true,CRCKey(eIn)), mOut(false,CRCKey(eOut)) + { + mIn.m_Owner = this; + mOut.m_Owner = this; + } + + virtual ~Sin(){} + + virtual uint32_t GetPlugCount()const + { + return 2; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mIn; + case 1: + default: return mOut; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mIn; + case 1: + default: return mOut; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float i,o; + + mIn.ReadData(&i, arEvaluationInfo); + + o = math::sin(i); + + mOut.WriteData(&o,arEvaluationInfo); + } + }; + + class Rand : public Node + { + public: + static const eNodeType mId = RandId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mResult; + + Rand() : mResult(false,CRCKey(eResult)) + { + mResult.m_Owner = this; + } + + virtual ~Rand(){} + + virtual uint32_t GetPlugCount()const + { + return 1; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float intpart = static_cast<float>(std::rand()); + float fractpart = (std::rand() % 100) / 100.f; + + float result = intpart+fractpart; + + mResult.WriteData(&result,arEvaluationInfo); + } + }; + + class Damp : public Node + { + public: + static const eNodeType mId = DampId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<float> mDampTime; + TypePlug<float> mValue; + TypePlug<float> mDeltaTime; + TypePlug<float> mPreviousValue; + TypePlug<float> mResult; + + Damp() + :mDampTime(true,CRCKey(eDampTime)), + mValue(true,CRCKey(eValue)), + mDeltaTime(true,CRCKey(eDeltaTime)), + mPreviousValue(true,CRCKey(ePreviousValue)), + mResult(false,CRCKey(eResult)) + { + mDampTime.m_Owner = this; + mValue.m_Owner = this; + mDeltaTime.m_Owner = this; + mPreviousValue.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~Damp(){} + + virtual uint32_t GetPlugCount()const + { + return 5; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mDampTime; + case 1: return mValue; + case 2: return mDeltaTime; + case 3: return mPreviousValue; + case 4: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mDampTime; + case 1: return mValue; + case 2: return mDeltaTime; + case 3: return mPreviousValue; + case 4: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + float dampTime,value,deltaTime,previousValue, result; + + mDampTime.ReadData(&dampTime, arEvaluationInfo); + mValue.ReadData(&value, arEvaluationInfo); + mDeltaTime.ReadData(&deltaTime, arEvaluationInfo); + mPreviousValue.ReadData(&previousValue, arEvaluationInfo); + + result = math::cond(dampTime > 0, previousValue + (value - previousValue) * deltaTime / (dampTime + deltaTime), value); + + mResult.WriteData(&result,arEvaluationInfo); + } + }; + +} + +} diff --git a/Runtime/mecanim/graph/graph.cpp b/Runtime/mecanim/graph/graph.cpp new file mode 100644 index 0000000..4edbec7 --- /dev/null +++ b/Runtime/mecanim/graph/graph.cpp @@ -0,0 +1,476 @@ +#include "UnityPrefix.h" +#include "Runtime/Math/Simd/math.h" +#include "Runtime/mecanim/graph/graph.h" +#include "Runtime/mecanim/graph/factory.h" + +namespace mecanim +{ + +namespace graph +{ + static void AssignPlugId(EvaluationGraph* apGraph) + { + // Assigning id to each graph plug + uint32_t i, id = 0; + for(i=0;i<apGraph->m_NodeCount;i++) + { + Node* node = apGraph->m_NodeArray[i]; + + apGraph->m_Graph.m_Vertices[i].m_Id = node->NodeType(); + apGraph->m_Graph.m_Vertices[i].m_Binding = node->mID; + uint32_t j; + for(j=0;j<node->GetPlugCount();j++) + { + node->GetPlug(j).m_PlugId = id++; + } + } + + for(i=0;i<apGraph->m_Input->GetPlugCount();i++) + { + apGraph->m_Input->GetPlug(i).m_PlugId = id++; + } + + for(i=0;i<apGraph->m_Output->GetPlugCount();i++) + { + apGraph->m_Output->GetPlug(i).m_PlugId = id++; + } + } + + static void AssignPlugOffset(EvaluationGraph* apGraph, memory::Allocator& arAlloc) + { + // assigning value offset for each plug + uint32_t i, offset = 0; + for(i=0;i<apGraph->m_NodeCount;i++) + { + Node* node = apGraph->m_NodeArray[i]; + uint32_t j; + for(j=0;j<node->GetPlugCount();j++) + { + GraphPlug& plug = node->GetPlug(j); + offset = plug.m_Offset = arAlloc.AlignAddress(offset, plug.ValueAlign()); + offset += plug.ValueSize(); + } + } + + for(i=0;i<apGraph->m_Input->GetPlugCount();i++) + { + GraphPlug& plug = apGraph->m_Input->GetPlug(i); + offset = plug.m_Offset = arAlloc.AlignAddress(offset, plug.ValueAlign()); + offset += plug.ValueSize(); + } + + for(i=0;i<apGraph->m_Output->GetPlugCount();i++) + { + GraphPlug& plug = apGraph->m_Output->GetPlug(i); + offset = plug.m_Offset = arAlloc.AlignAddress(offset, plug.ValueAlign()); + offset += plug.ValueSize(); + } + } + + static void ConnectEdges(EvaluationGraph* apGraph) + { + uint32_t i, edgesIt = 0; + for(i=0;i<apGraph->m_NodeCount;i++) + { + Node* node = apGraph->m_NodeArray[i]; + uint32_t j; + for(j=0;j<node->GetPlugCount();j++) + { + GraphPlug* plug = node->GetPlug(j).GetSource(); + if(plug) + { + apGraph->m_Graph.m_Edges[edgesIt].m_SourceId = plug->m_PlugId; + apGraph->m_Graph.m_Edges[edgesIt].m_DestinationId = node->GetPlug(j).m_PlugId; + edgesIt++; + } + } + } + + for(i=0;i<apGraph->m_Output->GetPlugCount();i++) + { + GraphPlug* plug = apGraph->m_Output->mPlugArray[i]->GetSource(); + if(plug) + { + apGraph->m_Graph.m_Edges[edgesIt].m_SourceId = plug->m_PlugId; + apGraph->m_Graph.m_Edges[edgesIt].m_DestinationId = apGraph->m_Output->mPlugArray[i]->m_PlugId; + edgesIt++; + } + } + } + + static EvaluationGraph* CreateGraph(Node** apNodeArray, uint32_t aNodeCount, + GraphPlug** apInputPlugArray, uint32_t aInputPlugCount, + GraphPlug** apOutputPlugArray, uint32_t aOutputPlugCount, + uint32_t aConnectionCount, + Constant** apConstantArray, uint32_t aConstantCount, + memory::Allocator& arAlloc) + { + EvaluationGraph* cst = arAlloc.Construct<EvaluationGraph>(); + + cst->m_NodeCount = aNodeCount; + cst->m_NodeArray = arAlloc.ConstructArray<Node*>(aNodeCount); + + cst->m_Graph.m_VerticesCount = aNodeCount; + cst->m_Graph.m_Vertices = arAlloc.ConstructArray<Vertex>(aNodeCount); + + cst->m_Graph.m_EdgesCount = aConnectionCount; + cst->m_Graph.m_Edges = arAlloc.ConstructArray<Edge>(aConnectionCount); + + cst->m_Graph.m_InEdgesCount = aInputPlugCount; + cst->m_Graph.m_InEdges = arAlloc.ConstructArray<ExternalEdge>(aInputPlugCount); + + cst->m_Graph.m_OutEdgesCount = aOutputPlugCount; + cst->m_Graph.m_OutEdges = arAlloc.ConstructArray<ExternalEdge>(aOutputPlugCount); + + cst->m_Graph.m_ConstantCount = aConstantCount; + cst->m_Graph.m_ConstantEdges = arAlloc.ConstructArray<ConstantEdge>(cst->m_Graph.m_ConstantCount); + + cst->m_Input = arAlloc.Construct<GraphInput>(); + + cst->m_Input->mPlugArray = arAlloc.ConstructArray<GraphPlug*>(aInputPlugCount); + + cst->m_Output = arAlloc.Construct<GraphOutput>(); + + cst->m_Output->mPlugArray = arAlloc.ConstructArray<GraphPlug*>(aOutputPlugCount); + + cst->m_ConstantCount = aConstantCount; + cst->m_ConstantArray = arAlloc.ConstructArray<Constant*>(aConstantCount); + + memcpy(&cst->m_NodeArray[0], &apNodeArray[0], sizeof(Node*)*aNodeCount); + + memcpy(&cst->m_ConstantArray[0], &apConstantArray[0], sizeof(Constant*)*aConstantCount); + + cst->m_Input->mPlugCount = aInputPlugCount; + memcpy(&cst->m_Input->mPlugArray[0], &apInputPlugArray[0], sizeof(GraphPlug*)*aInputPlugCount); + uint32_t i; + for(i=0;i<aInputPlugCount;i++) + { + cst->m_Input->mPlugArray[i]->m_Owner = cst->m_Input; + cst->m_Graph.m_InEdges[i].m_Id = GetPlugType(*apInputPlugArray[i]); + cst->m_Graph.m_InEdges[i].m_Binding = apInputPlugArray[i]->m_ID; + } + + cst->m_Output->mPlugCount = aOutputPlugCount; + memcpy(&cst->m_Output->mPlugArray[0], &apOutputPlugArray[0], sizeof(GraphPlug*)*aOutputPlugCount); + for(i=0;i<aOutputPlugCount;i++) + { + cst->m_Output->mPlugArray[i]->m_Owner = cst->m_Output; + cst->m_Graph.m_OutEdges[i].m_Id = GetPlugType(*apOutputPlugArray[i]); + cst->m_Graph.m_OutEdges[i].m_Binding = apOutputPlugArray[i]->m_ID; + } + + AssignPlugId(cst); + AssignPlugOffset(cst, arAlloc); + + for(i=0;i<aConstantCount;i++) + { + // copy the largest data element + cst->m_Graph.m_ConstantEdges[i].m_FloatValue = cst->m_ConstantArray[i]->m_FloatValue; + cst->m_Graph.m_ConstantEdges[i].m_VectorValue = cst->m_ConstantArray[i]->m_VectorValue; + if(cst->m_ConstantArray[i]->m_Plug) + { + cst->m_Graph.m_ConstantEdges[i].m_Id = cst->m_ConstantArray[i]->m_Plug->m_PlugId; + } + } + + return cst; + } + + EvaluationGraph* CreateEvaluationGraph(Node** apNodeArray, uint32_t aNodeCount, + GraphPlug** apInputPlugArray, uint32_t aInputPlugCount, + GraphPlug** apOutputPlugArray, uint32_t aOutputPlugCount, + Constant** apConstantArray, uint32_t aConstantCount, + memory::Allocator& arAlloc) + { + uint32_t connectionCount = 0; + uint32_t i; + for(i=0;i<aNodeCount;i++) + { + Node* node = apNodeArray[i]; + uint32_t j; + for(j=0;j<node->GetPlugCount();j++) + { + GraphPlug* plug = node->GetPlug(j).GetSource(); + if(plug) + { + connectionCount++; + } + } + } + + for(i=0;i<aOutputPlugCount;i++) + { + GraphPlug* plug = apOutputPlugArray[i]->GetSource(); + if(plug) + { + connectionCount++; + } + } + + EvaluationGraph* cst = CreateGraph(apNodeArray, aNodeCount, apInputPlugArray, aInputPlugCount, apOutputPlugArray, aOutputPlugCount, connectionCount, apConstantArray, aConstantCount, arAlloc); + + ConnectEdges(cst); + + return cst; + } + + static void Connect(Edge const& arEdges, EvaluationGraph& arGraph) + { + GraphPlug *source = 0, *destination = 0; + + uint32_t i, j; + for(i=0;i < arGraph.m_NodeCount && (source == 0 || destination == 0);i++) + { + Node* node = arGraph.m_NodeArray[i]; + for(j=0;j<node->GetPlugCount() && (source == 0 || destination == 0);j++) + { + if(node->GetPlug(j).m_PlugId == arEdges.m_SourceId) + source = &node->GetPlug(j); + if(node->GetPlug(j).m_PlugId == arEdges.m_DestinationId) + destination = &node->GetPlug(j); + } + } + + for(j=0;j<arGraph.m_Input->GetPlugCount() && (source == 0 || destination == 0);j++) + { + if(arGraph.m_Input->GetPlug(j).m_PlugId == arEdges.m_SourceId) + source = &arGraph.m_Input->GetPlug(j); + if(arGraph.m_Input->GetPlug(j).m_PlugId == arEdges.m_DestinationId) + destination = &arGraph.m_Input->GetPlug(j); + } + + + for(j=0;j<arGraph.m_Output->GetPlugCount() && (source == 0 || destination == 0);j++) + { + if(arGraph.m_Output->GetPlug(j).m_PlugId == arEdges.m_SourceId) + source = &arGraph.m_Output->GetPlug(j); + if(arGraph.m_Output->GetPlug(j).m_PlugId == arEdges.m_DestinationId) + destination = &arGraph.m_Output->GetPlug(j); + } + + if(source && destination) + { + destination->m_Source = source; + } + } + + static void Connect(ConstantEdge const& arConstantEdge, Constant& arConstant, EvaluationGraph& arGraph) + { + GraphPlug *plug = 0; + + uint32_t i, j; + for(i=0;i < arGraph.m_NodeCount && plug == 0; i++) + { + Node* node = arGraph.m_NodeArray[i]; + for(j=0;j<node->GetPlugCount() && plug == 0; j++) + { + if(node->GetPlug(j).m_PlugId == arConstantEdge.m_Id) + plug = &node->GetPlug(j); + } + } + + for(j=0;j<arGraph.m_Input->GetPlugCount() && plug == 0; j++) + { + if(arGraph.m_Input->GetPlug(j).m_PlugId == arConstantEdge.m_Id) + plug = &arGraph.m_Input->GetPlug(j); + } + + + for(j=0;j<arGraph.m_Output->GetPlugCount() && plug == 0; j++) + { + if(arGraph.m_Output->GetPlug(j).m_PlugId == arConstantEdge.m_Id) + plug = &arGraph.m_Output->GetPlug(j); + } + + if(plug) + { + arConstant.m_Plug = plug; + } + } + + EvaluationGraph* CreateEvaluationGraph(Graph* apGraph, GraphFactory const& arFactory, memory::Allocator& arAlloc) + { + EvaluationGraph* cst = 0; + uint32_t i; + Node** nodes = arAlloc.ConstructArray<Node*>(apGraph->m_VerticesCount); + GraphPlug** inputPlug = arAlloc.ConstructArray<GraphPlug*>(apGraph->m_InEdgesCount); + GraphPlug** outputPlug = arAlloc.ConstructArray<GraphPlug*>(apGraph->m_OutEdgesCount); + Constant** constants = arAlloc.ConstructArray<Constant*>(apGraph->m_ConstantCount); + + for(i=0;i<apGraph->m_VerticesCount;i++) + { + nodes[i] = arFactory.Create(static_cast<eNodeType>(apGraph->m_Vertices[i].m_Id), arAlloc); + nodes[i]->mID = apGraph->m_Vertices[i].m_Binding; + } + + for(i=0;i<apGraph->m_InEdgesCount;i++) + { + inputPlug[i] = arFactory.Create(static_cast<ePlugType>(apGraph->m_InEdges[i].m_Id), arAlloc); + inputPlug[i]->m_ID = apGraph->m_InEdges[i].m_Binding; + inputPlug[i]->m_Input = false; + } + + for(i=0;i<apGraph->m_OutEdgesCount;i++) + { + outputPlug[i] = arFactory.Create(static_cast<ePlugType>(apGraph->m_OutEdges[i].m_Id), arAlloc); + outputPlug[i]->m_ID = apGraph->m_OutEdges[i].m_Binding; + outputPlug[i]->m_Input = true; + } + + for(i=0;i<apGraph->m_ConstantCount;i++) + { + constants[i] = arAlloc.Construct<Constant>(); + + constants[i]->m_FloatValue = apGraph->m_ConstantEdges[i].m_FloatValue; + constants[i]->m_VectorValue = apGraph->m_ConstantEdges[i].m_VectorValue; + } + + cst = CreateGraph(nodes, apGraph->m_VerticesCount, inputPlug, apGraph->m_InEdgesCount, outputPlug, apGraph->m_OutEdgesCount, apGraph->m_EdgesCount, constants, apGraph->m_ConstantCount, arAlloc); + + for(i=0;i<apGraph->m_EdgesCount;i++) + { + cst->m_Graph.m_Edges[i] = apGraph->m_Edges[i]; + Connect(apGraph->m_Edges[i], *cst); + } + + for(i=0;i<apGraph->m_ConstantCount;i++) + { + cst->m_Graph.m_ConstantEdges[i].m_Id = apGraph->m_ConstantEdges[i].m_Id; + Connect(apGraph->m_ConstantEdges[i], *cst->m_ConstantArray[i], *cst); + } + + arAlloc.Deallocate(nodes); + arAlloc.Deallocate(inputPlug); + arAlloc.Deallocate(outputPlug); + arAlloc.Deallocate(constants); + + return cst; + } + + void DestroyEvaluationGraph(EvaluationGraph* apGraph, memory::Allocator& arAlloc) + { + if(apGraph) + { + uint32_t i; + for(i=0;i<apGraph->m_NodeCount;i++) + { + arAlloc.Deallocate(apGraph->m_NodeArray[i]); + } + arAlloc.Deallocate(apGraph->m_NodeArray); + + for(i=0;i<apGraph->m_Graph.m_InEdgesCount;i++) + { + arAlloc.Deallocate(apGraph->m_Input->mPlugArray[i]); + } + arAlloc.Deallocate(apGraph->m_Input->mPlugArray); + arAlloc.Deallocate(apGraph->m_Input); + + for(i=0;i<apGraph->m_Graph.m_OutEdgesCount;i++) + { + arAlloc.Deallocate(apGraph->m_Output->mPlugArray[i]); + } + arAlloc.Deallocate(apGraph->m_Output->mPlugArray); + arAlloc.Deallocate(apGraph->m_Output); + + for(i=0;i<apGraph->m_ConstantCount;i++) + { + arAlloc.Deallocate(apGraph->m_ConstantArray[i]); + } + arAlloc.Deallocate(apGraph->m_ConstantArray); + + arAlloc.Deallocate(apGraph->m_Graph.m_Vertices); + arAlloc.Deallocate(apGraph->m_Graph.m_Edges); + arAlloc.Deallocate(apGraph->m_Graph.m_InEdges); + arAlloc.Deallocate(apGraph->m_Graph.m_OutEdges); + arAlloc.Deallocate(apGraph->m_Graph.m_ConstantEdges); + + arAlloc.Deallocate(apGraph); + } + } + + EvaluationGraphWorkspace* CreateEvaluationGraphWorkspace(EvaluationGraph* apGraph, memory::Allocator& arAlloc) + { + std::size_t sizePlugDataBlock = 0; + uint32_t i, plugCount = 0; + + for(i=0;i<apGraph->m_NodeCount;i++) + { + Node* node = apGraph->m_NodeArray[i]; + uint32_t j; + for(j=0;j<node->GetPlugCount();j++) + { + plugCount++; + sizePlugDataBlock = arAlloc.AlignAddress(sizePlugDataBlock, node->GetPlug(j).ValueAlign()); + sizePlugDataBlock += node->GetPlug(j).ValueSize(); + } + } + + for(i=0;i<apGraph->m_Input->GetPlugCount();i++) + { + plugCount++; + sizePlugDataBlock = arAlloc.AlignAddress(sizePlugDataBlock, apGraph->m_Input->GetPlug(i).ValueAlign()); + sizePlugDataBlock += apGraph->m_Input->GetPlug(i).ValueSize(); + } + + for(i=0;i<apGraph->m_Output->GetPlugCount();i++) + { + plugCount++; + sizePlugDataBlock = arAlloc.AlignAddress(sizePlugDataBlock, apGraph->m_Output->GetPlug(i).ValueAlign()); + sizePlugDataBlock += apGraph->m_Output->GetPlug(i).ValueSize(); + } + + EvaluationGraphWorkspace* ws = arAlloc.Construct<EvaluationGraphWorkspace>(); + + ws->m_EvaluationInfo.m_DataBlock.m_PlugCount = plugCount; + ws->m_EvaluationInfo.m_DataBlock.m_EvaluationId = arAlloc.ConstructArray<uint32_t>(plugCount); + + ws->m_EvaluationInfo.m_DataBlock.m_Buffer = reinterpret_cast<char*>(arAlloc.Allocate( sizePlugDataBlock, ALIGN4F) ); + ws->m_EvaluationInfo.m_EvaluationId = 0; + + memset(ws->m_EvaluationInfo.m_DataBlock.m_EvaluationId, numeric_limits<uint32_t>::max_value, sizeof(mecanim::uint32_t)*plugCount); + memset(ws->m_EvaluationInfo.m_DataBlock.m_Buffer, 0, sizePlugDataBlock); + + for(i=0;i<apGraph->m_ConstantCount;i++) + { + if(apGraph->m_ConstantArray[i]->m_Plug) + { + ePlugType plugType = GetPlugType(*apGraph->m_ConstantArray[i]->m_Plug); + switch(plugType) + { + case Float4Id: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_VectorValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + case Float1Id: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_VectorValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + case FloatId: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_FloatValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + case UInt32Id: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_UIntValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + case Int32Id: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_IntValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + case BoolId: + ws->m_EvaluationInfo.m_DataBlock.SetData(apGraph->m_ConstantArray[i]->m_BoolValue, apGraph->m_ConstantArray[i]->m_Plug->m_PlugId, apGraph->m_ConstantArray[i]->m_Plug->m_Offset, 0); + break; + } + } + } + + return ws; + } + + void DestroyEvaluationGraphWorkspace(EvaluationGraphWorkspace* apGraphWorkspace, memory::Allocator& arAlloc) + { + if(apGraphWorkspace) + { + arAlloc.Deallocate(apGraphWorkspace->m_EvaluationInfo.m_DataBlock.m_Buffer); + arAlloc.Deallocate(apGraphWorkspace->m_EvaluationInfo.m_DataBlock.m_EvaluationId); + arAlloc.Deallocate(apGraphWorkspace); + } + } +} + +}
\ No newline at end of file diff --git a/Runtime/mecanim/graph/graph.h b/Runtime/mecanim/graph/graph.h new file mode 100644 index 0000000..2c12b4f --- /dev/null +++ b/Runtime/mecanim/graph/graph.h @@ -0,0 +1,188 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" +#include "Runtime/mecanim/bitset.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" +#include "Runtime/mecanim/graph/factory.h" + +#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h" +#include "Runtime/Animation/MecanimArraySerialization.h" + +namespace mecanim +{ + +namespace graph +{ + // If somebody change a node interface, like adding a new plug, he should create a new class instead for his new node + // because some user's file may still use the old node and won't have the data to handle new plug, unexpected behavior + // can result if this rule is not respected + + struct Vertex : public Object + { + DEFINE_GET_TYPESTRING(Vertex) + + DeclareObject(Vertex) + + Vertex():m_Id(numeric_limits<uint32_t>::max_value){} + uint32_t m_Id; + uint32_t m_Binding; + + template<class TransferFunction> + inline void Transfer (TransferFunction& transfer) + { + TRANSFER(m_Id); + TRANSFER(m_Binding); + } + }; + + struct Edge : public Object + { + DEFINE_GET_TYPESTRING(Edge) + + DeclareObject(Edge) + + Edge():m_SourceId(numeric_limits<uint32_t>::max_value),m_DestinationId(numeric_limits<uint32_t>::max_value){} + uint32_t m_SourceId; + uint32_t m_DestinationId; + + template<class TransferFunction> + inline void Transfer (TransferFunction& transfer) + { + TRANSFER(m_SourceId); + TRANSFER(m_DestinationId); + } + }; + + struct ConstantEdge : public Object + { + DEFINE_GET_TYPESTRING(ConstantEdge) + + DeclareObject(ConstantEdge) + + ConstantEdge():m_Id(numeric_limits<uint32_t>::max_value){} + union { + float m_FloatValue; + uint32_t m_UIntValue; + int32_t m_IntValue; + bool m_BoolValue; + }; + math::float4 m_VectorValue; + + uint32_t m_Id; + + template<class TransferFunction> + inline void Transfer (TransferFunction& transfer) + { + TRANSFER(m_Id); + TRANSFER(m_VectorValue); + TRANSFER(m_UIntValue); + } + }; + + struct ExternalEdge : public Object + { + DEFINE_GET_TYPESTRING(ExternalEdge) + + DeclareObject(ExternalEdge) + + ExternalEdge():m_Id(numeric_limits<uint32_t>::max_value), m_Binding(numeric_limits<uint32_t>::max_value){} + uint32_t m_Id; + uint32_t m_Binding; + + template<class TransferFunction> + inline void Transfer (TransferFunction& transfer) + { + TRANSFER(m_Id); + TRANSFER(m_Binding); + } + }; + + struct Graph : public Object + { + DEFINE_GET_TYPESTRING(Graph) + + DeclareObject(Graph) + + Graph() + :m_VerticesCount(0),m_Vertices(0), + m_EdgesCount(0),m_Edges(0), + m_InEdgesCount(0),m_InEdges(0), + m_OutEdgesCount(0),m_OutEdges(0), + m_ConstantCount(0),m_ConstantEdges(0) + {} + + uint32_t m_VerticesCount; + Vertex* m_Vertices; + + uint32_t m_EdgesCount; + Edge* m_Edges; + + uint32_t m_InEdgesCount; + ExternalEdge* m_InEdges; + + uint32_t m_OutEdgesCount; + ExternalEdge* m_OutEdges; + + uint32_t m_ConstantCount; + ConstantEdge* m_ConstantEdges; + + template<class TransferFunction> + inline void Transfer (TransferFunction& transfer) + { + MANUAL_ARRAY_TRANSFER(mecanim::graph::Vertex, m_Vertices, m_VerticesCount); + MANUAL_ARRAY_TRANSFER(mecanim::graph::Edge, m_Edges, m_EdgesCount); + MANUAL_ARRAY_TRANSFER(mecanim::graph::ExternalEdge, m_InEdges, m_InEdgesCount); + MANUAL_ARRAY_TRANSFER(mecanim::graph::ExternalEdge, m_OutEdges, m_OutEdgesCount); + MANUAL_ARRAY_TRANSFER(mecanim::graph::ConstantEdge, m_ConstantEdges, m_ConstantCount); + } + }; + + struct EvaluationGraph + { + public: + EvaluationGraph():m_NodeCount(0),m_NodeArray(0),m_Input(0),m_Output(0),m_ConstantCount(0),m_ConstantArray(0){} + + Graph m_Graph; + + uint32_t m_NodeCount; + Node** m_NodeArray; + + GraphInput* m_Input; + GraphOutput* m_Output; + + uint32_t m_ConstantCount; + Constant** m_ConstantArray; + }; + + struct EvaluationGraphWorkspace + { + public: + EvaluationGraphWorkspace(){} + + EvaluationInfo m_EvaluationInfo; + }; + + EvaluationGraph* CreateEvaluationGraph(Node** apNodeArray, uint32_t aNodeCount, + GraphPlug** apInputPlugArray, uint32_t aInputPlugCount, + GraphPlug** apOutputPlugArray, uint32_t aOutputPlugCount, + Constant** apConstantArray, uint32_t aConstantCount, + memory::Allocator& arAlloc); + + EvaluationGraph* CreateEvaluationGraph(Graph* apGraph, GraphFactory const& arFactory, memory::Allocator& arAlloc); + + void DestroyEvaluationGraph(EvaluationGraph* apGraph, memory::Allocator& arAlloc); + + EvaluationGraphWorkspace* CreateEvaluationGraphWorkspace(EvaluationGraph* apGraph, memory::Allocator& arAlloc); + void DestroyEvaluationGraphWorkspace(EvaluationGraphWorkspace* apGraphWorkspace, memory::Allocator& arAlloc); +} + +} diff --git a/Runtime/mecanim/graph/node.cpp b/Runtime/mecanim/graph/node.cpp new file mode 100644 index 0000000..8e1ead8 --- /dev/null +++ b/Runtime/mecanim/graph/node.cpp @@ -0,0 +1,11 @@ +#include "UnityPrefix.h" +#include "Runtime/mecanim/graph/node.h" + +namespace mecanim +{ + +namespace graph +{ +} + +} diff --git a/Runtime/mecanim/graph/node.h b/Runtime/mecanim/graph/node.h new file mode 100644 index 0000000..7dcea89 --- /dev/null +++ b/Runtime/mecanim/graph/node.h @@ -0,0 +1,346 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" +#include "Runtime/mecanim/generic/stringtable.h" + +#include "Runtime/mecanim/graph/plug.h" + +namespace mecanim +{ + +namespace graph +{ + // If you add a new node id, add it at the end of this list, otherwise you will break + // saved graph asset. + enum eNodeType { + InvalidNodeId, + NegationFloatId, + NegationIntId, + NegationFloat4Id, + AdditionFloatId, + AdditionUIntId, + AdditionIntId, + AdditionFloat4Id, + SubstractionFloatId, + SubstractionUIntId, + SubstractionIntId, + SubstractionFloat4Id, + MultiplicationFloatId, + MultiplicationUIntId, + MultiplicationIntId, + MultiplicationFloat4Id, + DivisionFloatId, + DivisionUIntId, + DivisionIntId, + DivisionFloat4Id, + CondFloatId, + CondUIntId, + CondIntId, + CondFloat4Id, + AbsFloatId, + AbsFloat4Id, + CrossFloat4Id, + DegreesFloatId, + DegreesFloat4Id, + DotFloat4Id, + LengthFloat4Id, + MaximumFloatId, + MaximumUIntId, + MaximumIntId, + MaximumFloat4Id, + MinimumFloatId, + MinimumUIntId, + MinimumIntId, + MinimumFloat4Id, + NormalizeFloat4Id, + RadiansFloatId, + RadiansFloat4Id, + FloatToFloat4Id, + Float4ToFloatId, + GreaterThanId, + LesserThanId, + SmoothstepFloatId, + Mux5FloatId, + Mul5FloatId, + FmodId, + SinId, + AndId, + OrId, + NegationBoolId, + GreaterThanOrEqualId, + LesserThanOrEqualId, + xformMulInvId, + xformIdentityId, + xformMulVecId, + xformInvMulVecId, + xformMulId, + xformInvMulId, + xformEqualId, + xformWeightId, + xformAddId, + xformSubId, + quatIdentityId, + quatConjId, + quatMulId, + quatMulVecId, + quatLerpId, + quatArcRotateId, + quatArcRotateXId, + quatXcosId, + quatYcosId, + quatZcosId, + quatEulerToQuatId, + quatQuatToEulerId, + quatProjOnYPlaneId, + quat2QtanId, + qtan2QuatId, + ZYRoll2QuatId, + quat2ZYRollId, + RollZY2QuatId, + quat2RollZYId, + quatWeightId, + xformComposeId, + xformDecomposeId, + CondXformId, + xformBlendId, + FloatToFloat1Id, // Not used anymore + Float1ToFloatId, // Not used anymore + RandId, + DampId, + xformRefChangeId, + XorId, + SmoothPulseFloatId, + InputId, + OutputId, + LastNodeId + }; + + class Node : public Object + { + public: + uint32_t mID; + + Node(){} + virtual ~Node(){} + + virtual eNodeType NodeType()=0; + virtual void Evaluate(EvaluationInfo& arEvaluationInfo)=0; + + virtual uint32_t GetPlugCount()const=0; + virtual GraphPlug& GetPlug(uint32_t aIndex)=0; + virtual GraphPlug const& GetPlug(uint32_t aIndex)const=0; + }; + + template<typename TYPE> class TypePlug : public GraphPlug + { + public: + typedef TYPE value_type; + typedef TYPE& reference; + typedef TYPE const& const_reference; + typedef TYPE* pointer; + typedef TYPE const* const_pointer; + + TypePlug(){} + TypePlug(bool input, uint32_t id, Node* apOwner=0):GraphPlug(input, id, apOwner){} + + virtual std::size_t ValueSize()const + { + return sizeof(value_type); + } + + virtual std::size_t ValueAlign()const + { + return ALIGN_OF(value_type); + } + + virtual ePlugType PlugType()const + { + return Trait<value_type>::PlugType(); + } + + void ConnectTo(TypePlug& arPlug) + { + m_Source = &arPlug; + } + + bool ReadData(void* apData, EvaluationInfo& arEvaluationInfo)const + { + uint32_t offset = m_Offset; + if(m_Source) + { + offset = m_Source->m_Offset; + if(arEvaluationInfo.m_DataBlock.IsDirty(m_Source->m_PlugId, arEvaluationInfo.m_EvaluationId)) + { + m_Source->m_Owner->Evaluate(arEvaluationInfo); + } + } + + *reinterpret_cast<pointer>(apData) = arEvaluationInfo.m_DataBlock.GetData<value_type>(offset); + + return true; + } + + bool WriteData(void const* apData, EvaluationInfo& arEvaluationInfo)const + { + arEvaluationInfo.m_DataBlock.SetData(*reinterpret_cast<const_pointer>(apData), m_PlugId, m_Offset, arEvaluationInfo.m_EvaluationId); + return true; + } + }; + + + class GraphOutput : public Node + { + public: + uint32_t mPlugCount; + GraphPlug** mPlugArray; + + GraphOutput():mPlugCount(0), mPlugArray(0){} + virtual ~GraphOutput(){} + + virtual eNodeType NodeType(){return OutputId;} + + virtual uint32_t GetPlugCount()const{return mPlugCount;} + virtual GraphPlug& GetPlug(uint32_t aIndex){return *(mPlugArray[aIndex]);} + virtual GraphPlug const& GetPlug(uint32_t aIndex)const{return *(mPlugArray[aIndex]);} + + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo){}; + }; + + class GraphInput : public Node + { + public: + uint32_t mPlugCount; + GraphPlug** mPlugArray; + + GraphInput():mPlugCount(0), mPlugArray(0){} + virtual ~GraphInput(){} + + virtual eNodeType NodeType(){return InputId;} + + virtual uint32_t GetPlugCount()const{return mPlugCount;} + virtual GraphPlug& GetPlug(uint32_t aIndex){return *(mPlugArray[aIndex]);} + virtual GraphPlug const& GetPlug(uint32_t aIndex)const{return *(mPlugArray[aIndex]);} + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo){}; + }; + + template <typename RESULT, typename ResultPolicies> class ResultNode : public Node + { + public: + TypePlug<RESULT> mResult; + + ResultNode() + :mResult(false,CRCKey(eResult)) + { + mResult.m_Owner = this; + } + virtual ~ResultNode(){} + + virtual uint32_t GetPlugCount()const + { + return 1; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + RESULT result = ResultPolicies::template Operation<RESULT>(); + mResult.WriteData(&result, arEvaluationInfo); + } + }; + + template <typename TYPE1, typename TYPE2, typename TYPE3, typename RESULT, typename TernaryPolicies> class TernaryNode : public Node + { + public: + TypePlug<TYPE1> mA; + TypePlug<TYPE2> mB; + TypePlug<TYPE3> mC; + + TypePlug<RESULT> mResult; + + TernaryNode() + :mA(true, CRCKey(eA)), + mB(true,CRCKey(eB)), + mC(true,CRCKey(eC)), + mResult(false,CRCKey(eResult)) + { + mA.m_Owner = this; + mB.m_Owner = this; + mC.m_Owner = this; + mResult.m_Owner = this; + } + + virtual ~TernaryNode(){} + + virtual uint32_t GetPlugCount()const + { + return 4; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mA; + case 1: return mB; + case 2: return mC; + case 3: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mA; + case 1: return mB; + case 2: return mC; + case 3: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + TYPE1 a; + TYPE2 b; + TYPE3 c; + RESULT result; + + mA.ReadData(&a, arEvaluationInfo); + mB.ReadData(&b, arEvaluationInfo); + mC.ReadData(&c, arEvaluationInfo); + + result = TernaryPolicies::template Operation<TYPE1, TYPE2, TYPE3, RESULT>(a, b, c); + + mResult.WriteData(&result, arEvaluationInfo); + } + }; + + + +} + +} diff --git a/Runtime/mecanim/graph/plug.h b/Runtime/mecanim/graph/plug.h new file mode 100644 index 0000000..ce90020 --- /dev/null +++ b/Runtime/mecanim/graph/plug.h @@ -0,0 +1,123 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/float4.h" +#include "Runtime/Math/Simd/xform.h" + +namespace mecanim +{ + +namespace graph +{ + class Node; + + enum ePlugType + { + InvalidPlugId, + Float4Id, + FloatId, + UInt32Id, // Not used anymore + Int32Id, + BoolId, + Float1Id, // Not used anymore + Bool4Id, // Not used anymore + XformId, + LastPlugId + }; + + template<typename T> struct Trait; + + template<> struct Trait<math::float4> { static ePlugType PlugType(){return Float4Id;} }; + template<> struct Trait<float> { static ePlugType PlugType(){return FloatId;} }; + template<> struct Trait<math::float1> { static ePlugType PlugType(){return FloatId;} }; + template<> struct Trait<uint32_t> { static ePlugType PlugType(){return UInt32Id;} }; + template<> struct Trait<int32_t> { static ePlugType PlugType(){return Int32Id;} }; + template<> struct Trait<bool> { static ePlugType PlugType(){return BoolId;} }; + template<> struct Trait<math::bool4> { static ePlugType PlugType(){return Bool4Id;} }; + template<> struct Trait<math::xform> { static ePlugType PlugType(){return XformId;} }; + + class DataBlock + { + public: + uint32_t m_PlugCount; + uint32_t* m_EvaluationId; + char* m_Buffer; + + bool IsDirty(uint32_t aPlugId, uint32_t aEvaluationId)const + { + return m_EvaluationId[aPlugId] != aEvaluationId; + } + template<typename TYPE> TYPE GetData(uint32_t offset)const + { + return *reinterpret_cast<TYPE*>(&m_Buffer[offset]); + } + template<typename TYPE> void SetData(TYPE const& arValue, uint32_t aPlugId, uint32_t offset, uint32_t aEvaluationId) + { + *reinterpret_cast<TYPE*>(&m_Buffer[offset]) = arValue; + m_EvaluationId[aPlugId] = aEvaluationId; + } + }; + + class EvaluationInfo + { + public: + DataBlock m_DataBlock; + uint32_t m_EvaluationId; + }; + + class GraphPlug + { + public: + GraphPlug():m_PlugId(numeric_limits<uint32_t>::max_value),m_Input(false),m_Owner(0),m_Source(0),m_Offset(0){} + GraphPlug(bool input, uint32_t id, Node* owner=0):m_PlugId(numeric_limits<uint32_t>::max_value),m_Input(input),m_Owner(owner),m_Source(0),m_ID(id){} + + virtual ~GraphPlug(){} + + virtual std::size_t ValueSize()const=0; + virtual std::size_t ValueAlign()const=0; + virtual ePlugType PlugType()const=0; + + GraphPlug* GetSource(){return m_Source;} + + virtual bool ReadData(void* apData, EvaluationInfo& arEvaluationInfo)const=0; + virtual bool WriteData(void const* apData, EvaluationInfo& arEvaluationInfo)const=0; + + uint32_t m_PlugId; + bool m_Input; + Node* m_Owner; + GraphPlug* m_Source; + uint32_t m_ID; + uint32_t m_Offset; + }; + + struct Constant + { + Constant():m_Plug(0),m_VectorValue(0),m_FloatValue(0){} + + union { + float m_FloatValue; + uint32_t m_UIntValue; + int32_t m_IntValue; + bool m_BoolValue; + }; + // Cannot put float4 in union because of operator= + math::float4 m_VectorValue; + graph::GraphPlug* m_Plug; + }; + + + STATIC_INLINE ePlugType GetPlugType(GraphPlug const& arPlug) + { + return arPlug.PlugType(); + } +} + +} diff --git a/Runtime/mecanim/graph/plugbinder.cpp b/Runtime/mecanim/graph/plugbinder.cpp new file mode 100644 index 0000000..03ffb30 --- /dev/null +++ b/Runtime/mecanim/graph/plugbinder.cpp @@ -0,0 +1,180 @@ +#include "UnityPrefix.h" +#include "Runtime/mecanim/graph/plugbinder.h" + +namespace mecanim +{ + void InitializeSetPlugBinder3(uint32_t& arCount, SetPlugBinder3 *& arSetPlugBinder3, ValuesList const& arValuesList, graph::EvaluationGraph const* apGraph, memory::Allocator& arAlloc) + { + arCount = 0; + arSetPlugBinder3 = 0; + + uint32_t i; + for(i = 0 ; i < apGraph->m_Input->mPlugCount; i++) + { + graph::GraphPlug& plug = *apGraph->m_Input->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_InValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_InValuesConstant[j], plug.m_ID); + if(index > -1) + { + arCount++; + } + } + } + + if(arCount) + { + arSetPlugBinder3 = arAlloc.ConstructArray<SetPlugBinder3>(arCount); + uint32_t binderCount; + for(i = 0, binderCount = 0; i < apGraph->m_Input->mPlugCount; i++) + { + graph::GraphPlug const* plug = apGraph->m_Input->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_InValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_InValuesConstant[j], plug->m_ID); + if(index > -1) + { + uint32_t valueIndex = static_cast<uint32_t>(index); + arSetPlugBinder3[binderCount++] = bind( SetPlugValueList, plug, j, valueIndex); + } + } + } + } + } + + void InitializeGetPlugBinder3(uint32_t& arCount, + GetPlugBinder3 *& arGetPlugBinder3, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc) + { + arCount = 0; + arGetPlugBinder3 = 0; + + uint32_t i; + for(i = 0 ; i < apGraph->m_Output->mPlugCount; i++) + { + graph::GraphPlug& plug = *apGraph->m_Output->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_OutValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_OutValuesConstant[j], plug.m_ID); + if(index > -1) + { + arCount++; + } + } + } + + if(arCount) + { + arGetPlugBinder3 = arAlloc.ConstructArray<GetPlugBinder3>(arCount); + uint32_t binderCount; + for(i = 0, binderCount = 0; i < apGraph->m_Output->mPlugCount; i++) + { + graph::GraphPlug const* plug = apGraph->m_Output->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_OutValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_OutValuesConstant[j], plug->m_ID); + if(index > -1) + { + uint32_t valueIndex = static_cast<uint32_t>(index); + arGetPlugBinder3[binderCount++] = bind( GetPlugValueList, plug, j, valueIndex); + } + } + } + } + } + + + + void InitializeSetPlugBinder2(uint32_t& arCount, SetPlugBinder2 *& arSetPlugBinder2, ValuesList const& arValuesList, graph::EvaluationGraph const* apGraph, memory::Allocator& arAlloc) + { + arCount = 0; + arSetPlugBinder2 = 0; + + uint32_t i; + for(i = 0 ; i < apGraph->m_Input->mPlugCount; i++) + { + graph::GraphPlug& plug = *apGraph->m_Input->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_InValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_InValuesConstant[j], plug.m_ID); + if(index > -1) + { + arCount++; + } + } + } + + if(arCount) + { + arSetPlugBinder2 = arAlloc.ConstructArray<SetPlugBinder2>(arCount); + uint32_t binderCount; + for(i = 0, binderCount = 0; i < apGraph->m_Input->mPlugCount; i++) + { + graph::GraphPlug const* plug = apGraph->m_Input->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_InValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_InValuesConstant[j], plug->m_ID); + if(index > -1) + { + uint32_t valueIndex = static_cast<uint32_t>(index); + arSetPlugBinder2[binderCount++] = bind( SetPlugValue, plug, valueIndex); + } + } + } + } + } + + void InitializeGetPlugBinder5(uint32_t& arCount, + GetPlugBinder2 *& arGetPlugBinder2, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc) + { + arCount = 0; + arGetPlugBinder2 = 0; + + uint32_t i; + for(i = 0 ; i < apGraph->m_Output->mPlugCount; i++) + { + graph::GraphPlug& plug = *apGraph->m_Output->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_OutValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_OutValuesConstant[j], plug.m_ID); + if(index > -1) + { + arCount++; + } + } + } + + if(arCount) + { + arGetPlugBinder2 = arAlloc.ConstructArray<GetPlugBinder2>(arCount); + uint32_t binderCount; + for(i = 0, binderCount = 0; i < apGraph->m_Output->mPlugCount; i++) + { + graph::GraphPlug const* plug = apGraph->m_Output->mPlugArray[i]; + uint32_t j; + for(j=0;j<arValuesList.m_OutValuesCount;++j) + { + int32_t index = FindValueIndex(arValuesList.m_OutValuesConstant[j], plug->m_ID); + if(index > -1) + { + uint32_t valueIndex = static_cast<uint32_t>(index); + arGetPlugBinder2[binderCount++] = bind( GetPlugValue, plug, valueIndex); + } + } + } + } + } + +} diff --git a/Runtime/mecanim/graph/plugbinder.h b/Runtime/mecanim/graph/plugbinder.h new file mode 100644 index 0000000..f224440 --- /dev/null +++ b/Runtime/mecanim/graph/plugbinder.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/bind.h" +#include "Runtime/mecanim/graph/graph.h" +#include "Runtime/mecanim/generic/valuearray.h" + +namespace mecanim +{ + typedef binder2<function<void (graph::GraphPlug const*, uint32_t, ValueArray const*, graph::EvaluationGraphWorkspace*)>::ptr, + graph::GraphPlug const*, + uint32_t> + SetPlugBinder2; + + typedef binder2<function<void (graph::GraphPlug const*, uint32_t, ValueArray*, graph::EvaluationGraphWorkspace*)>::ptr, + graph::GraphPlug const*, + uint32_t > + GetPlugBinder2; + + typedef binder3<function<void (graph::GraphPlug const*, uint32_t, uint32_t, ValuesList const&, graph::EvaluationGraphWorkspace*)>::ptr, + graph::GraphPlug const*, + uint32_t, + uint32_t> + SetPlugBinder3; + + + typedef binder3<function<void (graph::GraphPlug const*, uint32_t, uint32_t, ValuesList const&, graph::EvaluationGraphWorkspace*)>::ptr, + graph::GraphPlug const*, + uint32_t, + uint32_t> + GetPlugBinder3; + + STATIC_INLINE void SetPlugValue(mecanim::graph::GraphPlug const* plug, mecanim::uint32_t valueIndex, mecanim::ValueArray const* valueArray, mecanim::graph::EvaluationGraphWorkspace* graphWS) + { + char ATTRIBUTE_ALIGN(ALIGN4F) value[48]; + valueArray->m_ValueArray[valueIndex]->ReadData(value); + plug->WriteData( value, graphWS->m_EvaluationInfo); + } + STATIC_INLINE void GetPlugValue(mecanim::graph::GraphPlug const* plug, mecanim::uint32_t valueIndex, mecanim::ValueArray* valueArray, mecanim::graph::EvaluationGraphWorkspace* graphWS) + { + char ATTRIBUTE_ALIGN(ALIGN4F) value[48]; + plug->ReadData( value, graphWS->m_EvaluationInfo); + valueArray->m_ValueArray[valueIndex]->WriteData(value); + } + + STATIC_INLINE void SetPlugValueList(mecanim::graph::GraphPlug const* plug, mecanim::uint32_t listIndex, mecanim::uint32_t valueIndex, ValuesList const& valuesList, mecanim::graph::EvaluationGraphWorkspace* graphWS) + { + char ATTRIBUTE_ALIGN(ALIGN4F) value[48]; + valuesList.m_InValues[listIndex]->m_ValueArray[valueIndex]->ReadData(value); + plug->WriteData( value, graphWS->m_EvaluationInfo); + } + STATIC_INLINE void GetPlugValueList(mecanim::graph::GraphPlug const* plug, mecanim::uint32_t listIndex, mecanim::uint32_t valueIndex, ValuesList const& valuesList, mecanim::graph::EvaluationGraphWorkspace* graphWS) + { + char ATTRIBUTE_ALIGN(ALIGN4F) value[48]; + plug->ReadData( value, graphWS->m_EvaluationInfo); + valuesList.m_OutValues[listIndex]->m_ValueArray[valueIndex]->WriteData(value); + } + + void InitializeSetPlugBinder3(uint32_t& arCount, + SetPlugBinder3 *& arSetPlugBinder3, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc); + + void InitializeGetPlugBinder3(uint32_t& arCount, + GetPlugBinder3 *& arGetPlugBinder3, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc); + + void InitializeSetPlugBinder2(uint32_t& arCount, + SetPlugBinder2 *& arSetPlugBinder2, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc); + + void InitializeGetPlugBinder2(uint32_t& arCount, + GetPlugBinder2 *& arGetPlugBinder2, + ValuesList const& arValuesList, + graph::EvaluationGraph const* apGraph, + memory::Allocator& arAlloc); +}
\ No newline at end of file diff --git a/Runtime/mecanim/graph/quaternionnode.h b/Runtime/mecanim/graph/quaternionnode.h new file mode 100644 index 0000000..19f1f86 --- /dev/null +++ b/Runtime/mecanim/graph/quaternionnode.h @@ -0,0 +1,283 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/math.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" + +#include "Runtime/mecanim/graph/unarynode.h" + +namespace mecanim +{ + +namespace graph +{ + class quatIdentityOp + { + public: + template<typename RESULT> static math::float4 Operation(){ return math::quatIdentity(); } + }; + + class quatIdentity : public ResultNode<math::float4, quatIdentityOp> + { + public: + static const eNodeType mId = quatIdentityId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE, typename RESULT> class quatConjOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatConj(l); } + }; + + class quatConj : public UnaryNode<math::float4, math::float4, quatConjOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatConjId; + virtual eNodeType NodeType(){return mId;} + }; + + class quatMulOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::float4 const& l, math::float4 const& r){ return math::quatMul(l, r); } + }; + + class quatMul : public BinaryNode<math::float4, math::float4, math::float4, quatMulOp> + { + public: + static const eNodeType mId = quatMulId; + virtual eNodeType NodeType(){return mId;} + }; + + class quatMulVecOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::float4 const& l, math::float4 const& r){ return math::quatMulVec(l, r); } + }; + + class quatMulVec : public BinaryNode<math::float4, math::float4, math::float4, quatMulVecOp> + { + public: + static const eNodeType mId = quatMulVecId; + virtual eNodeType NodeType(){return mId;} + }; + + class quatLerpOp + { + public: + template<typename TYPE1, typename TYPE2, typename TYPE3, typename RESULT> static math::float4 Operation( math::float4 const& a, math::float4 const& b, float c){ return math::quatLerp(a, b, math::float1(c)); } + }; + + class quatLerp : public TernaryNode<math::float4, math::float4, float, math::float4, quatLerpOp> + { + public: + static const eNodeType mId = quatLerpId; + virtual eNodeType NodeType(){return mId;} + }; + + class quatArcRotateOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::float4 const& l, math::float4 const& r){ return math::quatArcRotate(l, r); } + }; + + class quatArcRotate : public BinaryNode<math::float4, math::float4, math::float4, quatArcRotateOp> + { + public: + static const eNodeType mId = quatArcRotateId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatArcRotateXOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatArcRotateX(l); } + }; + + class quatArcRotateX : public UnaryNode<math::float4, math::float4, quatArcRotateXOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatArcRotateXId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatXcosOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatXcos(l); } + }; + + class quatXcos : public UnaryNode<math::float4, math::float4, quatXcosOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatXcosId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatYcosOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatYcos(l); } + }; + + class quatYcos : public UnaryNode<math::float4, math::float4, quatYcosOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatYcosId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatZcosOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatZcos(l); } + }; + + class quatZcos : public UnaryNode<math::float4, math::float4, quatZcosOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatZcosId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatEulerToQuatOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatEulerToQuat(l); } + }; + + class quatEulerToQuat : public UnaryNode<math::float4, math::float4, quatEulerToQuatOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatEulerToQuatId; + virtual eNodeType NodeType(){return mId;} + }; + template<typename TYPE1, typename RESULT> class quatQuatToEulerOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatQuatToEuler(l); } + }; + + class quatQuatToEuler : public UnaryNode<math::float4, math::float4, quatQuatToEulerOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatQuatToEulerId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quatProjOnYPlaneOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quatProjOnYPlane(l); } + }; + + class quatProjOnYPlane : public UnaryNode<math::float4, math::float4, quatProjOnYPlaneOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quatProjOnYPlaneId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quat2QtanOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quat2Qtan(l); } + }; + + class quat2Qtan : public UnaryNode<math::float4, math::float4, quat2QtanOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quat2QtanId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class qtan2QuatOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::qtan2Quat(l); } + }; + + class qtan2Quat : public UnaryNode<math::float4, math::float4, qtan2QuatOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = qtan2QuatId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class ZYRoll2QuatOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::ZYRoll2Quat(l); } + }; + + class ZYRoll2Quat : public UnaryNode<math::float4, math::float4, ZYRoll2QuatOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = ZYRoll2QuatId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quat2ZYRollOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quat2ZYRoll(l); } + }; + + class quat2ZYRoll : public UnaryNode<math::float4, math::float4, quat2ZYRollOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quat2ZYRollId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class RollZY2QuatOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::RollZY2Quat(l); } + }; + + class RollZY2Quat : public UnaryNode<math::float4, math::float4, RollZY2QuatOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = RollZY2QuatId; + virtual eNodeType NodeType(){return mId;} + }; + + template<typename TYPE1, typename RESULT> class quat2RollZYOp + { + public: + static math::float4 Operation( math::float4 const& l){ return math::quat2RollZY(l); } + }; + + class quat2RollZY : public UnaryNode<math::float4, math::float4, quat2RollZYOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = quat2RollZYId; + virtual eNodeType NodeType(){return mId;} + }; + + class quatWeightOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::float4 const& l, float r){ return math::quatWeight(l, math::float1(r)); } + }; + + class quatWeight : public BinaryNode<math::float4, float, math::float4, quatWeightOp> + { + public: + static const eNodeType mId = quatWeightId; + virtual eNodeType NodeType(){return mId;} + }; +} +}
\ No newline at end of file diff --git a/Runtime/mecanim/graph/unarynode.h b/Runtime/mecanim/graph/unarynode.h new file mode 100644 index 0000000..8ed5b82 --- /dev/null +++ b/Runtime/mecanim/graph/unarynode.h @@ -0,0 +1,112 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/float4.h" + +#include "Runtime/mecanim/graph/plug.h" + +namespace mecanim +{ + +namespace graph +{ + template <typename TYPE, typename RESULT, typename UnaryPolicies> class UnaryNode : public Node + { + public: + TypePlug<TYPE> mA; + + TypePlug<RESULT> mResult; + + UnaryNode() + :mA(true,CRCKey(eA)), + mResult(false,CRCKey(eResult)) + { + mA.m_Owner = this; + mResult.m_Owner = this; + } + virtual ~UnaryNode(){} + + virtual uint32_t GetPlugCount()const + { + return 2; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mA; + case 1: + default: return mResult; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mA; + case 1: + default: return mResult; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + TYPE a; + RESULT result; + + mA.ReadData(&a, arEvaluationInfo); + + result = UnaryPolicies::Operation(a); + + mResult.WriteData(&result, arEvaluationInfo); + } + }; + + + template< typename TYPE, typename RESULT > class NegationOp + { + public: + static RESULT Operation( TYPE const& l){ return -l; } + }; + + template<> class NegationOp<bool, bool> + { + public: + static bool Operation(bool const &l) { return !l; } + }; + + class NegationFloat : public UnaryNode<float, float, NegationOp<float, float> > + { + public: + static const eNodeType mId = NegationFloatId; + virtual eNodeType NodeType(){return mId;} + }; + class NegationInt : public UnaryNode<int32_t, int32_t, NegationOp<int32_t, int32_t> > + { + public: + static const eNodeType mId = NegationIntId; + virtual eNodeType NodeType(){return mId;} + }; + class NegationFloat4 : public UnaryNode<math::float4, math::float4, NegationOp<math::float4, math::float4> > + { + public: + static const eNodeType mId = NegationFloat4Id; + virtual eNodeType NodeType(){return mId;} + }; + class NegationBool : public UnaryNode<bool, bool, NegationOp<bool, bool> > + { + public: + static const eNodeType mId = NegationBoolId; + virtual eNodeType NodeType(){return mId;} + }; +} + +} diff --git a/Runtime/mecanim/graph/xformnode.h b/Runtime/mecanim/graph/xformnode.h new file mode 100644 index 0000000..d0abf24 --- /dev/null +++ b/Runtime/mecanim/graph/xformnode.h @@ -0,0 +1,348 @@ +/* + Copyright (c) 7244339 Canada Inc. (Mecanim) + All Rights Reserved. +*/ +#pragma once + +#include "Runtime/mecanim/defs.h" +#include "Runtime/mecanim/memory.h" +#include "Runtime/mecanim/types.h" +#include "Runtime/mecanim/object.h" + +#include "Runtime/Math/Simd/math.h" + +#include "Runtime/mecanim/graph/plug.h" +#include "Runtime/mecanim/graph/node.h" + +#include "Runtime/mecanim/graph/unarynode.h" + +#include "Runtime/mecanim/generic/stringtable.h" + +namespace mecanim +{ + +namespace graph +{ + class IdentityOp + { + public: + template<typename RESULT> static math::xform Operation(){ return math::xformIdentity(); } + }; + + class xformIdentity : public ResultNode<math::xform, IdentityOp> + { + public: + static const eNodeType mId = xformIdentityId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformMulVecOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::xform const& l, math::float4 const& r){ return math::xformMulVec(l, r); } + }; + + class xformMulVec : public BinaryNode<math::xform, math::float4, math::float4, xformMulVecOp> + { + public: + static const eNodeType mId = xformMulVecId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformInvMulVecOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::float4 Operation( math::xform const& l, math::float4 const& r){ return math::xformInvMulVec(l, r); } + }; + + class xformInvMulVec : public BinaryNode<math::xform, math::float4, math::float4, xformInvMulVecOp> + { + public: + static const eNodeType mId = xformInvMulVecId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformMulOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, math::xform const& r){ return math::xformMul(l, r); } + }; + + class xformMul : public BinaryNode<math::xform, math::xform, math::xform, xformMulOp> + { + public: + static const eNodeType mId = xformMulId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformInvMulOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, math::xform const& r){ return math::xformInvMul(l, r); } + }; + + class xformInvMul : public BinaryNode<math::xform, math::xform, math::xform, xformInvMulOp> + { + public: + static const eNodeType mId = xformInvMulId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformMulInvOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, math::xform const& r){ return math::xformMulInv(l, r); } + }; + + class xformMulInv : public BinaryNode<math::xform, math::xform, math::xform, xformMulInvOp> + { + public: + static const eNodeType mId = xformMulInvId; + virtual eNodeType NodeType(){ return mId;} + }; + + class xformEqualOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static bool Operation( math::xform const& l, math::xform const& r){ return l == r; } + }; + + class xformEqual : public BinaryNode<math::xform, math::xform, bool, xformEqualOp> + { + public: + static const eNodeType mId = xformEqualId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformWeightOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, float r){ return math::xformWeight(l, math::float1(r)); } + }; + + class xformWeight : public BinaryNode<math::xform, float, math::xform, xformWeightOp> + { + public: + static const eNodeType mId = xformWeightId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformBlendOp + { + public: + template<typename TYPE1, typename TYPE2, typename TYPE3, typename RESULT> static math::xform Operation( math::xform const& a,math::xform const& b, float const& c){ return math::xformBlend(a,b,math::float1(c)); } + }; + + class xformBlend : public TernaryNode<math::xform, math::xform, float, math::xform, xformBlendOp> + { + public: + static const eNodeType mId = xformBlendId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformAddOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, math::xform const& r){ return math::xformAdd(l, r); } + }; + + class xformAdd : public BinaryNode<math::xform, math::xform, math::xform, xformAddOp> + { + public: + static const eNodeType mId = xformAddId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformSubOp + { + public: + template<typename TYPE1, typename TYPE2, typename RESULT> static math::xform Operation( math::xform const& l, math::xform const& r){ return math::xformSub(l, r); } + }; + + class xformSub : public BinaryNode<math::xform, math::xform, math::xform, xformSubOp> + { + public: + static const eNodeType mId = xformSubId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformComposeOp + { + public: + template<typename TYPE1, typename TYPE2, typename TYPE3, typename RESULT> static math::xform Operation( math::float4 const& t, math::float4 const& q, math::float4 const& s){ return math::xform(t, q, s); } + }; + + class xformCompose : public TernaryNode<math::float4, math::float4, math::float4, math::xform, xformComposeOp> + { + public: + xformCompose() + { + mA.m_ID = CRCKey(eT); + mB.m_ID = CRCKey(eQ); + mC.m_ID = CRCKey(eS); + } + static const eNodeType mId = xformComposeId; + virtual eNodeType NodeType(){return mId;} + }; + + class xformDecompose : public Node + { + public: + static const eNodeType mId = xformDecomposeId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<math::xform> mX; + TypePlug<math::float4> mT; + TypePlug<math::float4> mQ; + TypePlug<math::float4> mS; + + xformDecompose() + :mX(true,CRCKey(eX)), + mT(false,CRCKey(eT)), + mQ(false,CRCKey(eQ)), + mS(false,CRCKey(eS)) + { + mX.m_Owner = this; + mT.m_Owner = this; + mQ.m_Owner = this; + mS.m_Owner = this; + } + + virtual ~xformDecompose(){} + + virtual uint32_t GetPlugCount()const + { + return 4; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mX; + case 1: return mT; + case 2: return mQ; + case 3: + default:return mS; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mX; + case 1: return mT; + case 2: return mQ; + case 3: + default:return mS; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + math::xform x; + + mX.ReadData(&x, arEvaluationInfo); + + mT.WriteData(&x.t, arEvaluationInfo); + mQ.WriteData(&x.q, arEvaluationInfo); + mS.WriteData(&x.s, arEvaluationInfo); + } + }; + + class xformRefChange : public Node + { + public: + static const eNodeType mId = xformRefChangeId; + virtual eNodeType NodeType(){return mId;} + + TypePlug<math::xform> mSrcRefX; + TypePlug<math::xform> mDstRefX; + TypePlug<math::xform> mSrcPivotX; + TypePlug<math::xform> mDstPivotX; + TypePlug<float> mRefWeight; + TypePlug<float> mPivotWeight; + TypePlug<math::xform> mXI; + TypePlug<math::xform> mXO; + + xformRefChange() : mSrcRefX(true,CRCKey(eSrcRefX)), + mDstRefX(true,CRCKey(eDstRefX)), + mSrcPivotX(true,CRCKey(eSrcPivotX)), + mDstPivotX(true,CRCKey(eDstPivotX)), + mRefWeight(true,CRCKey(eRefWeight)), + mPivotWeight(true,CRCKey(ePivotWeight)), + mXI(true,CRCKey(eXI)), + mXO(false,CRCKey(eXO)) + { + mSrcRefX.m_Owner = this; + mDstRefX.m_Owner = this; + mSrcPivotX.m_Owner = this; + mDstPivotX.m_Owner = this; + mRefWeight.m_Owner = this; + mPivotWeight.m_Owner = this; + mXI.m_Owner = this; + mXO.m_Owner = this; + } + + virtual ~xformRefChange(){} + + virtual uint32_t GetPlugCount()const + { + return 8; + } + virtual GraphPlug& GetPlug(uint32_t aIndex) + { + switch(aIndex) + { + case 0: return mSrcRefX; + case 1: return mDstRefX; + case 2: return mSrcPivotX; + case 3: return mDstPivotX; + case 4: return mRefWeight; + case 5: return mPivotWeight; + case 6: return mXI; + case 7: + default: return mXO; + } + } + virtual GraphPlug const& GetPlug(uint32_t aIndex)const + { + switch(aIndex) + { + case 0: return mSrcRefX; + case 1: return mDstRefX; + case 2: return mSrcPivotX; + case 3: return mDstPivotX; + case 4: return mRefWeight; + case 5: return mPivotWeight; + case 6: return mXI; + case 7: + default: return mXO; + } + } + + virtual void Evaluate(EvaluationInfo& arEvaluationInfo) + { + math::xform srcRefX, dstRefX, srcPivotX, dstPivotX, xi, xo; + float rw,pw; + + mSrcRefX.ReadData(&srcRefX, arEvaluationInfo); + mDstRefX.ReadData(&dstRefX, arEvaluationInfo); + mSrcPivotX.ReadData(&srcPivotX, arEvaluationInfo); + mDstPivotX.ReadData(&dstPivotX, arEvaluationInfo); + mRefWeight.ReadData(&rw, arEvaluationInfo); + mPivotWeight.ReadData(&pw, arEvaluationInfo); + mXI.ReadData(&xi,arEvaluationInfo); + + xo = math::xformMul(xi,srcPivotX); + xo = math::xformInvMul(srcRefX,xo); + xo = math::xformWeight(xo,math::float1(1-pw)); + xo = math::xformMul(dstRefX,xo); + xo = math::xformMulInv(xo,dstPivotX); + xo = math::xformBlend(xi,xo,math::float1(rw)); + + mXO.WriteData(&xo, arEvaluationInfo); + } + }; +} + +}
\ No newline at end of file |