BVB Source Codes

CRYENGINE Show ICryMannequin.h Source code

Return Download CRYENGINE: download ICryMannequin.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. //
  4. ////////////////////////////////////////////////////////////////////////////
  5. #ifndef __I_CRY_MANNEQUIN_H__
  6. #define __I_CRY_MANNEQUIN_H__
  7.  
  8. #ifdef CRYACTION_EXPORTS
  9.         #define CRYMANNEQUIN_API DLL_EXPORT
  10. #else
  11.         #define CRYMANNEQUIN_API DLL_IMPORT
  12. #endif
  13.  
  14. #include <CryAnimation/ICryAnimation.h>
  15. #include <CryExtension/ICryUnknown.h>
  16. #include <CryExtension/CryCreateClassInstance.h>
  17. #include <CrySerialization/Forward.h>
  18. #include "ICryMannequinDefs.h"
  19. #include "ICryMannequinProceduralClipFactory.h"
  20.  
  21. #define MannGenCRC CCrc32::ComputeLowercase
  22.  
  23. #include <CryCore/BitFiddling.h>
  24. #include <CryMath/MTPseudoRandom.h>
  25. #include "ICryMannequinTagDefs.h"
  26.  
  27. struct IMannequinEditorManager;
  28. struct IMannequinGameListener;
  29. class CAnimationDatabase;
  30. struct AnimEventInstance;
  31.  
  32. struct IProceduralParams;
  33. DECLARE_SHARED_POINTERS(IProceduralParams);
  34.  
  35. const uint32 MANN_NUMBER_BLEND_CHANNELS = 4;
  36.  
  37. struct SAnimationEntry
  38. {
  39.         SAnimationEntry()
  40.                 :
  41.                 flags(0),
  42.                 playbackSpeed(1.0f),
  43.                 playbackWeight(1.0f),
  44.                 weightList(0)
  45.         {
  46.                 memset(blendChannels, 0, sizeof(float) * MANN_NUMBER_BLEND_CHANNELS);
  47.         }
  48.  
  49.         ILINE bool IsEmpty() const
  50.         {
  51.                 return animRef.IsEmpty();
  52.         }
  53.  
  54.         friend bool operator==(const SAnimationEntry& entryA, const SAnimationEntry& entryB)
  55.         {
  56.                 return (entryA.animRef.crc == entryB.animRef.crc)
  57.                        && (entryA.flags == entryB.flags)
  58.                        && (entryA.playbackSpeed == entryB.playbackSpeed)
  59.                        && (entryA.playbackWeight == entryB.playbackWeight)
  60.                        && (entryA.weightList == entryB.weightList);
  61.         }
  62.  
  63.         SAnimRef animRef;
  64.         uint32   flags;
  65.         float    playbackSpeed;
  66.         float    playbackWeight;
  67.         float    blendChannels[MANN_NUMBER_BLEND_CHANNELS];
  68.         uint8    weightList;
  69. };
  70.  
  71. #define IProceduralParamsComparerDefaultName "ProceduralParamsComparerDefault"
  72. struct IProceduralParamsComparer;
  73. typedef std::shared_ptr<IProceduralParamsComparer> IProceduralParamsComparerPtr;
  74.  
  75. struct IProceduralParamsComparer
  76.         : public ICryUnknown
  77. {
  78.         CRYINTERFACE_DECLARE(IProceduralParamsComparer, 0xdde3edc3dca84794, 0xb71ee1c21047c654);
  79.  
  80.         virtual bool                        Equal(const IProceduralParams& lhs, const IProceduralParams& rhs) const = 0;
  81.  
  82.         static IProceduralParamsComparerPtr CreateDefaultProceduralParamsComparer()
  83.         {
  84.                 IProceduralParamsComparerPtr pProceduralParamsComparer;
  85.                 ::CryCreateClassInstance(IProceduralParamsComparerDefaultName, pProceduralParamsComparer);
  86.                 return pProceduralParamsComparer;
  87.         }
  88. };
  89.  
  90. struct IProceduralParamsEditor
  91. {
  92.         virtual ~IProceduralParamsEditor() {}
  93.  
  94.         struct SEditorCreateTransformGizmoResult
  95.         {
  96.                 bool         createGizmo;   // Specifies if the editor should create a transform gizmo or not. Defaults to false.
  97.                 QuatT        gizmoLocation; // Specifies the initial location of the transform gizmo (Relative to the supplied attachment or joint id, if any).
  98.                 IAttachment* pAttachment;   // If not null, the gizmo's location will be relative to the attachment. Do not specify both an attachment and a jointId.
  99.                 int          jointId;       // If positive, the gizmo's location will be relative to the joint with this Id. Do not specify both an attachment and a jointId.
  100.                 uint32       paramCRC;      // If not 0, the gizmo's location will be relative to the parameter location. Do not specify both an attachment and a jointId.
  101.                 string       helperName;
  102.  
  103.                 SEditorCreateTransformGizmoResult()
  104.                         : createGizmo(false)
  105.                         , gizmoLocation(IDENTITY)
  106.                         , pAttachment(NULL)
  107.                         , jointId(-1)
  108.                         , paramCRC(0)
  109.                 {
  110.                 }
  111.  
  112.                 SEditorCreateTransformGizmoResult(IEntity& entity, const QuatT& location, const uint32 jointOrAttachmentNameCrc, const char* _helperName = NULL)
  113.                         : createGizmo(true)
  114.                         , gizmoLocation(location)
  115.                         , pAttachment(NULL)
  116.                         , jointId(-1)
  117.                         , paramCRC(0)
  118.                         , helperName(_helperName)
  119.                 {
  120.                         ICharacterInstance* const pCharacterInstance = entity.GetCharacter(0);
  121.                         if (pCharacterInstance)
  122.                         {
  123.                                 pAttachment = pCharacterInstance->GetIAttachmentManager()->GetInterfaceByNameCRC(jointOrAttachmentNameCrc);
  124.                                 if (!pAttachment)
  125.                                 {
  126.                                         jointId = pCharacterInstance->GetIDefaultSkeleton().GetJointIDByCRC32(jointOrAttachmentNameCrc);
  127.                                         if (jointId < 0)
  128.                                         {
  129.                                                 paramCRC = jointOrAttachmentNameCrc;
  130.                                         }
  131.                                 }
  132.                         }
  133.                 }
  134.         };
  135.  
  136.         // OnEditorCreateTransformGizmo is an editor callback for when the editor wants to query if/how to create a transformation gizmo in the mannequin viewport and associate it
  137.         // with this instance of a procedural clip's parameters to facilitate editing of locations in space.
  138.         // The return value is SEditorCreateTransformGizmoResult with details of how that locator should be created. See structure for details on the parameters.
  139.         // This function might be called more than once on a specific instance (e.g. When the procedural clip parameters change), but it always refers to the same transform
  140.         // gizmo: At most a single transform gizmo will be created.
  141.         // This function should disappear once there is support for a transform gizmo/location decorators in the serialization framework UI components.
  142.         virtual SEditorCreateTransformGizmoResult OnEditorCreateTransformGizmo(IEntity& entity)
  143.         {
  144.                 return SEditorCreateTransformGizmoResult();
  145.         }
  146.  
  147.         // OnEditorMovedTransformGizmo is an editor callback for when the transform gizmo created after OnEditorCreateTransformGizmo and associated to the current procedural clip is moved.
  148.         // The location in gizmoLocation is relative to the attachment or joint specified in the SEditorCreateTransformGizmoResult returned in the last call to OnEditorCreateTransformGizmo.
  149.         // This function should disappear once there is support for a transform gizmo/location decorators in the serialization framework UI components.
  150.         virtual void OnEditorMovedTransformGizmo(const QuatT& gizmoLocation)
  151.         {
  152.         }
  153.  
  154.         // GetEditorDefaultBlendDuration is called by the editor to know what value to use as the blend duration when creating a procedural clip.
  155.         virtual float GetEditorDefaultBlendDuration() const
  156.         {
  157.                 return 0.3f;
  158.         }
  159. };
  160.  
  161. struct IProceduralParams
  162.         : public IProceduralParamsEditor
  163. {
  164.         virtual ~IProceduralParams() {}
  165.  
  166.         virtual void Serialize(Serialization::IArchive& ar) = 0;
  167.  
  168.         // Important: Calling this function with two IProceduralParams of different types will result in undefined behavior.
  169.         // There is no internal check for this requirement, so the check needs to happen at a higher level.
  170.         bool operator==(const IProceduralParams& rhs) const
  171.         {
  172.                 IProceduralParamsComparerPtr pComparer = IProceduralParamsComparer::CreateDefaultProceduralParamsComparer();
  173.                 if (pComparer)
  174.                 {
  175.                         return pComparer->Equal(*this, rhs);
  176.                 }
  177.                 return false;
  178.         }
  179.  
  180.         template<typename TChar>
  181.         struct StringWrapperImpl
  182.         {
  183.                 StringWrapperImpl()
  184.                 {
  185.                         SetValue(NULL);
  186.                 }
  187.  
  188.                 explicit StringWrapperImpl(const TChar* const s)
  189.                 {
  190.                         SetValue(s);
  191.                 }
  192.  
  193.                 const TChar* c_str() const
  194.                 {
  195.                         return &m_buffer[0];
  196.                 }
  197.  
  198.                 const StringWrapperImpl& operator=(const TChar* const s)
  199.                 {
  200.                         SetValue(s);
  201.                         return *this;
  202.                 }
  203.  
  204.                 const size_t GetLength() const
  205.                 {
  206.                         const size_t bufferSize = m_buffer.size();
  207.                         assert(0 < bufferSize);
  208.                         return bufferSize - 1;
  209.                 }
  210.  
  211.                 const bool IsEmpty() const
  212.                 {
  213.                         return (GetLength() == 0);
  214.                 }
  215.  
  216.         private:
  217.                 void SetValue(const TChar* const s)
  218.                 {
  219.                         m_buffer.clear();
  220.                         if (s)
  221.                         {
  222.                                 const TChar* it = s;
  223.                                 while (*it)
  224.                                 {
  225.                                         m_buffer.push_back(*it);
  226.                                         ++it;
  227.                                 }
  228.                         }
  229.                         m_buffer.push_back(0);
  230.                 }
  231.  
  232.         private:
  233.                 DynArray<TChar> m_buffer;
  234.         };
  235.  
  236.         typedef StringWrapperImpl<char> StringWrapper;
  237.  
  238.         // GetExtraDebugInfo is called to retrieve a string containing extra information about the procedural parameters.
  239.         // This function is called both by the editor and the runtime.
  240.         // The editor may call it to display information on top of tracks in the fragment editor, preview editor, etc.
  241.         // The runtime may call it in debug functions (e.g mn_debug) to display data associated to procedural clips.
  242.         virtual void GetExtraDebugInfo(StringWrapper& extraInfoOut) const
  243.         {
  244.         }
  245. };
  246.  
  247. struct SNoProceduralParams
  248.         : public IProceduralParams
  249. {
  250.         virtual void Serialize(Serialization::IArchive& ar)
  251.         {
  252.         }
  253. };
  254.  
  255. struct SMannParameter
  256. {
  257.         uint32 crc;
  258.         QuatT  value;
  259.  
  260.         SMannParameter()
  261.                 :
  262.                 crc(0),
  263.                 value(IDENTITY)
  264.         {
  265.         }
  266. };
  267.  
  268. typedef DynArray<SMannParameter> TMannParamList;
  269.  
  270. //---------------------------------------------------------------------------------------------------------
  271. // SAnimBlend - Specific blend information for a clip on a layer
  272. //---------------------------------------------------------------------------------------------------------
  273. // ExitTime                             - Time to start the following clip relative to the previous one
  274. //                   -ve values mean to align to the end of the previous clip
  275. // StartTime                    - Time in secs for the following clip to start off advanced to
  276. // Duration                             - Duration of the blend in secs
  277. // flags                                        - Specific playback flags for timeAlignment etc.
  278. // terminal                             - Has this clip been explicitly setup to blend into the next fragment?
  279. //---------------------------------------------------------------------------------------------------------
  280. struct SAnimBlend
  281. {
  282.         SAnimBlend(float _exitTime = 0.0f, float _startTime = 0.0f, float _duration = 0.2f, uint32 _flags = 0)
  283.                 :
  284.                 exitTime(_exitTime),
  285.                 startTime(_startTime),
  286.                 duration(_duration),
  287.                 flags(_flags),
  288.                 terminal(false)
  289.         {
  290.         }
  291.  
  292.         friend bool operator==(const SAnimBlend& entryA, const SAnimBlend& entryB)
  293.         {
  294.                 return (entryA.exitTime == entryB.exitTime)
  295.                        && (entryA.startTime == entryB.startTime)
  296.                        && (entryA.duration == entryB.duration)
  297.                        && (entryA.flags == entryB.flags)
  298.                        && (entryA.terminal == entryB.terminal);
  299.         }
  300.  
  301.         float  exitTime;
  302.         float  startTime;
  303.         float  duration;
  304.         uint32 flags;
  305.         bool   terminal;
  306. };
  307.  
  308. enum EClipType
  309. {
  310.         eCT_Normal,
  311.         eCT_Transition,
  312.         eCT_TransitionOutro,
  313. };
  314.  
  315. //---------------------------------------------------------------------------------------------------------
  316. // SAnimClip - Single animation clip used by the sequencer
  317. //---------------------------------------------------------------------------------------------------------
  318. // blend                                        - Blend data to use for this clip
  319. // animation                    - Pure animation data
  320. // blendPart                    - The fragment part which the blend came from
  321. // part                                         - The fragment part which the animation data came from
  322. //---------------------------------------------------------------------------------------------------------
  323. struct SAnimClip
  324. {
  325.         SAnimClip()
  326.                 : referenceLength(0.0f)
  327.                 , blendPart(0)
  328.                 , part(0)
  329.                 , isVariableLength(false)
  330.         {
  331.         }
  332.  
  333.         friend bool operator==(const SAnimClip& entryA, const SAnimClip& entryB)
  334.         {
  335.                 return (entryA.blend == entryB.blend)
  336.                        && (entryA.animation == entryB.animation)
  337.                        && (entryA.blendPart == entryB.blendPart)
  338.                        && (entryA.part == entryB.part);
  339.         }
  340.  
  341.         SAnimBlend      blend;
  342.         SAnimationEntry animation;
  343.         float           referenceLength;
  344.         uint8           blendPart;
  345.         uint8           part;
  346.         bool            isVariableLength;
  347. };
  348.  
  349. typedef DynArray<SAnimClip> TAnimClipSequence;
  350.  
  351. struct SProceduralEntry
  352. {
  353.         SProceduralEntry()
  354.                 : blendPart(0)
  355.                 , part(0)
  356.         {
  357.         }
  358.  
  359.         static bool ProceduralParamsMatch(const IProceduralParamsPtr& p1, const IProceduralParamsPtr& p2)
  360.         {
  361.                 return ((!p1 && !p2) || (p1 && p2 && *p1 == *p2));
  362.         }
  363.  
  364.         friend bool operator==(const SProceduralEntry& entryA, const SProceduralEntry& entryB)
  365.         {
  366.                 return (entryA.typeNameHash == entryB.typeNameHash)
  367.                        && (entryA.blend == entryB.blend)
  368.                        && (entryA.blendPart == entryB.blendPart)
  369.                        && (entryA.part == entryB.part)
  370.                        && SProceduralEntry::ProceduralParamsMatch(entryA.pProceduralParams, entryB.pProceduralParams);
  371.         }
  372.  
  373.         bool IsNoneType() const
  374.         {
  375.                 return typeNameHash.IsEmpty();
  376.         }
  377.  
  378.         IProceduralClipFactory::THash typeNameHash;
  379.  
  380.         SAnimBlend                    blend;
  381.         uint8                         blendPart;
  382.         uint8                         part;
  383.  
  384.         IProceduralParamsPtr          pProceduralParams;
  385. };
  386.  
  387. typedef DynArray<SProceduralEntry> TProcClipSequence;
  388.  
  389. struct SFragmentData
  390. {
  391.         enum
  392.         {
  393.                 PART_FRAGMENT,
  394.                 PART_TRANSITION1,
  395.                 PART_TRANSITION2,
  396.                 PART_TOTAL
  397.         };
  398.  
  399.         SFragmentData()
  400.                 : isOneShot(false)
  401.                 , blendOutDuration(0.0f)
  402.         {
  403.                 for (uint32 p = 0; p < PART_TOTAL; p++)
  404.                 {
  405.                         duration[p] = 0.0f;
  406.                         transitionType[p] = eCT_Normal;
  407.                 }
  408.         }
  409.  
  410.         float                       blendOutDuration;
  411.         DynArray<TAnimClipSequence> animLayers;
  412.         DynArray<TProcClipSequence> procLayers;
  413.         float                       duration[PART_TOTAL];
  414.         EClipType                   transitionType[PART_TOTAL];
  415.         bool                        isOneShot;
  416. };
  417.  
  418. class CFragment
  419. {
  420. public:
  421.         CFragment() : m_blendOutDuration(0.2f){}
  422.  
  423.         float                       m_blendOutDuration;
  424.         DynArray<TAnimClipSequence> m_animLayers;
  425.         DynArray<TProcClipSequence> m_procLayers;
  426. };
  427.  
  428. // Unique id for SFragmentBlend
  429. struct SFragmentBlendUid
  430. {
  431.         enum
  432.         {
  433.                 INVALID_UID = 0,
  434.         };
  435.  
  436.         enum ENewUid
  437.         {
  438.                 NEW
  439.         };
  440.  
  441.         SFragmentBlendUid()
  442.                 : m_uid(INVALID_UID)
  443.         {
  444.         }
  445.  
  446.         explicit SFragmentBlendUid(ENewUid)
  447.                 : m_uid(GenerateUid())
  448.         {
  449.         }
  450.  
  451.         SFragmentBlendUid(const SFragmentBlendUid& other)
  452.                 : m_uid(other.m_uid)
  453.         {
  454.         }
  455.  
  456.         bool operator==(const SFragmentBlendUid& other) const
  457.         {
  458.                 return m_uid == other.m_uid;
  459.         }
  460.  
  461.         bool operator!=(const SFragmentBlendUid& other) const
  462.         {
  463.                 return m_uid != other.m_uid;
  464.         }
  465.  
  466.         SFragmentBlendUid& operator=(const SFragmentBlendUid& other)
  467.         {
  468.                 m_uid = other.m_uid;
  469.                 return *this;
  470.         }
  471.  
  472.         bool operator<(const SFragmentBlendUid& other) const
  473.         {
  474.                 assert(IsValid());
  475.                 assert(other.IsValid());
  476.                 return m_uid < other.m_uid;
  477.         }
  478.  
  479.         bool IsValid() const
  480.         {
  481.                 return m_uid != INVALID_UID;
  482.         }
  483.  
  484.         void Serialize(XmlNodeRef& xmlNode, bool bLoading)
  485.         {
  486.                 if (bLoading)
  487.                 {
  488.                         xmlNode->getAttr("uid", m_uid);
  489.                 }
  490.                 else
  491.                 {
  492.                         xmlNode->setAttr("uid", m_uid);
  493.                 }
  494.         }
  495.  
  496. private:
  497.         static uint32 GenerateUid()
  498.         {
  499.                 static uint32 lastId = INVALID_UID;
  500.                 static const uint32 bitsNeededToEncodeModule = CompileTimeIntegerLog2_RoundUp<eCryM_Num>::result;
  501.                 return (((uint32)eCryModule) << (32 - bitsNeededToEncodeModule)) + ++lastId;
  502.         }
  503.  
  504. private:
  505.         uint32 m_uid;
  506. };
  507.  
  508. //---------------------------------------------------------------------------------------------------------
  509. // SFragmentBlend - High level blend information
  510. //---------------------------------------------------------------------------------------------------------
  511. // SelectTime                                   - Time value used for selecting the best transition
  512. // StartTime                                    - Time to begin the transition relative to the end of the previous fragment
  513. // EnterTime                                    - Time delta to apply to the following fragment, allows snipping of the start of the entire fragment
  514. // pFragment                                    - Transition fragment: includes additional tween clips and blends into the intial fragment clips.
  515. //                                                                                This is merged onto the front of the following fragment on installation.
  516. // uid                                                          - Unique id
  517. //---------------------------------------------------------------------------------------------------------
  518. struct SFragmentBlend
  519. {
  520.         enum EFlags
  521.         {
  522.                 Cyclic         = BIT(0),
  523.                 CycleLocked    = BIT(1),
  524.                 ExitTransition = BIT(2)
  525.         };
  526.  
  527.         SFragmentBlend()
  528.                 :
  529.                 selectTime(0.0f),
  530.                 startTime(0.0f),
  531.                 enterTime(0.0f),
  532.                 pFragment(NULL),
  533.                 flags(0),
  534.                 uid(SFragmentBlendUid::NEW)
  535.         {
  536.  
  537.         }
  538.  
  539.         bool operator<(const SFragmentBlend& blend) const
  540.         {
  541.                 return selectTime < blend.selectTime;
  542.         }
  543.  
  544.         ILINE const bool IsExitTransition() const
  545.         {
  546.                 return (flags & ExitTransition) != 0;
  547.         }
  548.  
  549.         float             selectTime;
  550.         float             startTime;
  551.         float             enterTime;
  552.         CFragment*        pFragment;
  553.         uint8             flags;
  554.         SFragmentBlendUid uid;
  555. };
  556.  
  557. typedef TTagSortedList<ActionScopes> TTagListActionScope;
  558.  
  559. struct SFragmentDef
  560. {
  561.         enum EFlags
  562.         {
  563.                 PERSISTENT                = BIT(0),
  564.                 AUTO_REINSTALL_BEST_MATCH = BIT(1)
  565.         };
  566.  
  567.         SFragmentDef()
  568.                 : flags(0)
  569.         {
  570.                 scopeMaskList.Insert(SFragTagState(), ACTION_SCOPES_ALL);
  571.         }
  572.  
  573.         TTagListActionScope scopeMaskList;
  574.         uint8               flags;
  575. };
  576.  
  577. struct SScopeDef
  578. {
  579.         SScopeDef()
  580.                 : context(SCOPE_CONTEXT_ID_INVALID)
  581.                 , layer(0)
  582.                 , numLayers(0)
  583.                 , additionalTags(TAG_STATE_EMPTY)
  584.         {
  585.         }
  586.  
  587.         uint32    context;
  588.         uint32    layer;
  589.         uint32    numLayers;
  590.         TagState  additionalTags;
  591.         SScopeRef scopeAlias;
  592. };
  593.  
  594. struct SScopeContextDef
  595. {
  596.         SScopeContextDef()
  597.                 : sharedTags(TAG_STATE_FULL)
  598.                 , additionalTags(TAG_STATE_EMPTY)
  599.         {
  600.         }
  601.  
  602.         TagState sharedTags;
  603.         TagState additionalTags;
  604. };
  605.  
  606. struct SSubContext
  607. {
  608.         ActionScopes scopeMask;
  609.         TagState     additionalTags;
  610. };
  611.  
  612. struct SControllerDef
  613. {
  614.         SControllerDef(const CTagDefinition& tags, const CTagDefinition& fragmentIDs, const CTagDefinition& scopeIDs)
  615.                 :
  616.                 m_tags(tags),
  617.                 m_fragmentIDs(fragmentIDs),
  618.                 m_scopeIDs(scopeIDs)
  619.         {
  620.         }
  621.  
  622.         SControllerDef(const SControllerDef& rhs)
  623.                 : m_filename(rhs.m_filename)
  624.                 , m_tags(rhs.m_tags)
  625.                 , m_fragmentIDs(rhs.m_fragmentIDs)
  626.                 , m_scopeIDs(rhs.m_scopeIDs)
  627.                 , m_subContextIDs(rhs.m_subContextIDs)
  628.                 , m_scopeContexts(rhs.m_scopeContexts)
  629.                 , m_fragmentDef(rhs.m_fragmentDef)
  630.                 , m_scopeDef(rhs.m_scopeDef)
  631.                 , m_scopeContextDef(rhs.m_scopeContextDef)
  632.                 , m_subContext(rhs.m_subContext)
  633.         {
  634.         }
  635.  
  636.         const SFragmentDef& GetFragmentDef(FragmentID fragment) const
  637.         {
  638.                 IF_LIKELY (m_fragmentIDs.IsValidTagID(fragment))
  639.                 {
  640.                         return m_fragmentDef[fragment];
  641.                 }
  642.                 else
  643.                 {
  644.                         CRY_ASSERT(false);
  645.                         return m_fragmentDef[0];
  646.                 }
  647.         }
  648.  
  649.         const CTagDefinition* GetFragmentTagDef(FragmentID fragment) const
  650.         {
  651.                 return m_fragmentIDs.GetSubTagDefinition(fragment);
  652.         }
  653.  
  654.         const ActionScopes GetScopeMask(FragmentID fragID, const SFragTagState& fragTagState, TagID subContext = TAG_ID_INVALID) const
  655.         {
  656.                 ActionScopes scopeMask = ACTION_SCOPES_NONE;
  657.                 IF_LIKELY (m_fragmentIDs.IsValidTagID(fragID))
  658.                 {
  659.                         const CTagDefinition* pFragTagDef = m_fragmentIDs.GetSubTagDefinition(fragID);
  660.                         scopeMask = *m_fragmentDef[fragID].scopeMaskList.GetBestMatch(fragTagState, &m_tags, pFragTagDef);
  661.  
  662.                         if (subContext != TAG_ID_INVALID)
  663.                         {
  664.                                 scopeMask |= m_subContext[subContext].scopeMask;
  665.                         }
  666.                 }
  667.  
  668.                 return scopeMask;
  669.         }
  670.  
  671.         TDefPathString             m_filename;
  672.         const CTagDefinition&      m_tags;
  673.         const CTagDefinition&      m_fragmentIDs;
  674.         const CTagDefinition       m_scopeIDs;
  675.         CTagDefinition             m_subContextIDs;
  676.         CTagDefinition             m_scopeContexts;
  677.  
  678.         DynArray<SFragmentDef>     m_fragmentDef;
  679.         DynArray<SScopeDef>        m_scopeDef;
  680.         DynArray<SScopeContextDef> m_scopeContextDef;
  681.         DynArray<SSubContext>      m_subContext;
  682. };
  683.  
  684. struct SAnimationContext
  685. {
  686.         SAnimationContext(const SControllerDef& _controllerDef)
  687.                 :
  688.                 controllerDef(_controllerDef),
  689.                 state(_controllerDef.m_tags)
  690.         {
  691.                 subStates.resize(_controllerDef.m_subContextIDs.GetNum(), state);
  692.         }
  693.  
  694.         const SControllerDef& controllerDef;
  695.         CTagState             state;
  696.         DynArray<CTagState>   subStates;
  697.         CMTRand_int32         randGenerator;
  698. };
  699.  
  700. struct SMannHistoryItem
  701. {
  702.         SMannHistoryItem()
  703.                 :
  704.                 time(-1.0f),
  705.                 tagState(TAG_STATE_EMPTY),
  706.                 scopeMask(0),
  707.                 fragment(FRAGMENT_ID_INVALID),
  708.                 optionIdx(0),
  709.                 trumpsPrevious(false),
  710.                 type(None)
  711.         {
  712.         }
  713.  
  714.         SMannHistoryItem(ActionScopes _scopeMask, FragmentID _fragment, const TagState& _tagState, uint32 _optionIdx, bool _trumpsPrevious = false)
  715.                 :
  716.                 time(-1.0f),
  717.                 tagState(_tagState),
  718.                 scopeMask(_scopeMask),
  719.                 fragment(_fragment),
  720.                 optionIdx(_optionIdx),
  721.                 trumpsPrevious(_trumpsPrevious),
  722.                 type(Fragment)
  723.         {
  724.         }
  725.         SMannHistoryItem(const TagState& _tagState)
  726.                 :
  727.                 time(-1.0f),
  728.                 tagState(_tagState),
  729.                 scopeMask(0),
  730.                 fragment(FRAGMENT_ID_INVALID),
  731.                 optionIdx(0),
  732.                 trumpsPrevious(false),
  733.                 type(Tag)
  734.         {
  735.         }
  736.  
  737.         enum EType
  738.         {
  739.                 Fragment,
  740.                 Tag,
  741.                 None
  742.         };
  743.         float        time;
  744.         TagState     tagState;
  745.         ActionScopes scopeMask;
  746.         FragmentID   fragment;
  747.         uint32       optionIdx;
  748.         bool         trumpsPrevious;
  749.         uint8        type;
  750. };
  751.  
  752. struct IMannequinListener
  753. {
  754.         virtual ~IMannequinListener(){}
  755.  
  756.         virtual void OnEvent(const SMannHistoryItem& historyItem, const class IActionController& actionController) = 0;
  757. };
  758.  
  759. struct SMannequinErrorReport
  760. {
  761.         SMannequinErrorReport()
  762.                 :
  763.                 errorType(None),
  764.                 fragID(FRAGMENT_ID_INVALID),
  765.                 fragIDTo(FRAGMENT_ID_INVALID),
  766.                 fragOptionID(0)
  767.         {
  768.                 error[0] = '\0';
  769.         }
  770.         enum ErrorType
  771.         {
  772.                 None,
  773.                 Fragment,
  774.                 Blend
  775.         };
  776.  
  777.         char          error[1024];
  778.         ErrorType     errorType;
  779.         FragmentID    fragID;
  780.         SFragTagState tags;
  781.         FragmentID    fragIDTo;
  782.         SFragTagState tagsTo;
  783.         uint32        fragOptionID;
  784. };
  785.  
  786. struct SAnimAssetReport
  787. {
  788.         SAnimAssetReport()
  789.                 :
  790.                 pAnimName(NULL),
  791.                 pAnimPath(NULL),
  792.                 animID(-1),
  793.                 fragID(FRAGMENT_ID_INVALID),
  794.                 fragIDTo(FRAGMENT_ID_INVALID),
  795.                 fragOptionID(0)
  796.         {
  797.         }
  798.  
  799.         const char*   pAnimName;
  800.         const char*   pAnimPath;
  801.         int           animID;
  802.         FragmentID    fragID;
  803.         SFragTagState tags;
  804.         FragmentID    fragIDTo;
  805.         SFragTagState tagsTo;
  806.         uint32        fragOptionID;
  807. };
  808.  
  809. struct SBlendQueryResult
  810. {
  811.         SBlendQueryResult()
  812.                 :
  813.                 fragmentFrom(FRAGMENT_ID_INVALID),
  814.                 fragmentTo(FRAGMENT_ID_INVALID),
  815.                 pFragmentBlend(NULL),
  816.                 blendIdx(0),
  817.                 selectTime(0.0f),
  818.                 duration(0.0f)
  819.         {
  820.         }
  821.  
  822.         FragmentID            fragmentFrom;
  823.         FragmentID            fragmentTo;
  824.         SFragTagState         tagStateFrom;
  825.         SFragTagState         tagStateTo;
  826.         const SFragmentBlend* pFragmentBlend;
  827.         uint32                blendIdx;
  828.         SFragmentBlendUid     blendUid;
  829.         float                 selectTime;
  830.         float                 duration;
  831. };
  832.  
  833. struct SBlendQuery
  834. {
  835.         enum EFlags
  836.         {
  837.                 fromInstalled  = BIT(0),
  838.                 toInstalled    = BIT(1),
  839.                 higherPriority = BIT(2),
  840.                 noTransitions  = BIT(3)
  841.         };
  842.  
  843.         SBlendQuery()
  844.                 :
  845.                 fragmentFrom(FRAGMENT_ID_INVALID),
  846.                 fragmentTo(FRAGMENT_ID_INVALID),
  847.                 additionalTags(TAG_STATE_EMPTY),
  848.                 fragmentTime(0.0f),
  849.                 prevNormalisedTime(0.0f),
  850.                 normalisedTime(0.0f),
  851.                 flags(0)
  852.         {
  853.         }
  854.  
  855.         bool IsFlagSet(uint32 flag) const
  856.         {
  857.                 return (flags & flag) == flag;
  858.         }
  859.         void SetFlag(uint32 flag, bool set)
  860.         {
  861.                 if (set)
  862.                         flags |= flag;
  863.                 else
  864.                         flags &= ~flag;
  865.         }
  866.  
  867.         FragmentID        fragmentFrom;
  868.         FragmentID        fragmentTo;
  869.         SFragTagState     tagStateFrom;
  870.         SFragTagState     tagStateTo;
  871.         TagState          additionalTags;
  872.         float             fragmentTime;
  873.         float             prevNormalisedTime;
  874.         float             normalisedTime;
  875.         uint32            flags;
  876.         SFragmentBlendUid forceBlendUid;
  877. };
  878.  
  879. struct SFragmentQuery
  880. {
  881.         SFragmentQuery(const CTagDefinition& fragDef, FragmentID _fragID = FRAGMENT_ID_INVALID, SFragTagState _tagState = SFragTagState(), TagState _requiredTags = TAG_STATE_EMPTY, uint32 _optionIdx = OPTION_IDX_RANDOM)
  882.                 :
  883.                 fragID(_fragID),
  884.                 tagState(_tagState),
  885.                 requiredTags(_requiredTags),
  886.                 optionIdx(_optionIdx)
  887.         {
  888.                 tagState.globalTags = fragDef.GetUnion(tagState.globalTags, _requiredTags);
  889.         }
  890.  
  891.         SFragmentQuery(FragmentID _fragID = FRAGMENT_ID_INVALID, SFragTagState _tagState = SFragTagState(), uint32 _optionIdx = OPTION_IDX_RANDOM)
  892.                 :
  893.                 fragID(_fragID),
  894.                 tagState(_tagState),
  895.                 requiredTags(TAG_STATE_EMPTY),
  896.                 optionIdx(_optionIdx)
  897.         {
  898.         }
  899.  
  900.         FragmentID    fragID;
  901.         SFragTagState tagState;
  902.         TagState      requiredTags;
  903.         uint32        optionIdx;
  904. };
  905.  
  906. struct SFragmentSelection
  907. {
  908.         SFragmentSelection(SFragTagState _tagState = SFragTagState(), uint32 _optionIdx = OPTION_IDX_RANDOM)
  909.                 :
  910.                 tagState(_tagState),
  911.                 tagSetIdx(TAG_SET_IDX_INVALID),
  912.                 optionIdx(_optionIdx)
  913.         {
  914.         }
  915.  
  916.         SFragTagState tagState;
  917.         uint32        tagSetIdx;
  918.         uint32        optionIdx;
  919. };
  920.  
  921. struct SMiniSubADB
  922. {
  923.         SMiniSubADB()
  924.                 : tags(TAG_STATE_EMPTY)
  925.                 , pFragDef(NULL)
  926.         {
  927.         }
  928.  
  929.         TagState              tags;
  930.         string                filename;
  931.         const CTagDefinition* pFragDef;
  932.  
  933.         typedef DynArray<FragmentID> TFragIDArray;
  934.         TFragIDArray vFragIDs;
  935.  
  936.         typedef DynArray<SMiniSubADB> TSubADBArray;
  937.         TSubADBArray vSubADBs;
  938. };
  939.  
  940. typedef void (* MannErrorCallback)(const SMannequinErrorReport& errorReport, void* _context);
  941. typedef void (* MannAssetCallback)(const SAnimAssetReport& assetReport, void* _context);
  942.  
  943. class IAnimationDatabase
  944. {
  945. public:
  946.         virtual ~IAnimationDatabase() {}
  947.  
  948.         virtual bool        Validate(const struct IAnimationSet* animSet, MannErrorCallback errorCallback = NULL, MannErrorCallback warningCallback = NULL, void* errorCallbackContext = NULL) const = 0;
  949.         virtual void        EnumerateAnimAssets(const IAnimationSet* animSet, MannAssetCallback assetCallback, void* callbackContext) const = 0;
  950.  
  951.         virtual const char* GetFilename() const = 0;
  952.         virtual bool        Query(SFragmentData& outFragmentData, const SFragmentQuery& inFragQuery, SFragmentSelection* outFragSelection = NULL) const = 0;
  953.  
  954.         //-----------------------------------------------------------------
  955.         // Main Query function, expands queried fragment and transition data out into the target fragData buffer
  956.         // Returns the following flags to say which sources are contributing to the data
  957.         // From eSequenceFlags: eSF_Fragment, eSF_TransitionOutro, eSF_Transition
  958.         //-----------------------------------------------------------------
  959.         virtual uint32                Query(SFragmentData& outFragmentData, const SBlendQuery& inBlendQuery, uint32 inOptionIdx, const IAnimationSet* inAnimSet, SFragmentSelection* outFragSelection = NULL) const = 0;
  960.  
  961.         virtual uint32                FindBestMatchingTag(const SFragmentQuery& inFragQuery, SFragTagState* matchingTagState = NULL, uint32* tagSetIdx = NULL) const = 0;
  962.         virtual const CTagDefinition& GetTagDefs() const = 0;
  963.         virtual FragmentID            GetFragmentID(const char* szActionName) const = 0;
  964.         virtual const CTagDefinition& GetFragmentDefs() const = 0;
  965.  
  966.         virtual uint32                GetTotalTagSets(FragmentID fragmentID) const = 0;
  967.         virtual uint32                GetTagSetInfo(FragmentID fragmentID, uint32 tagSetID, SFragTagState& fragTagState) const = 0;
  968.  
  969.         virtual const CFragment*      GetBestEntry(const SFragmentQuery& fragQuery, SFragmentSelection* fragSelection = NULL) const = 0;
  970.         virtual const CFragment*      GetEntry(FragmentID fragmentID, uint32 tagSetID, uint32 optionIdx) const = 0;
  971.  
  972.         virtual void                  FindBestBlends(const SBlendQuery& blendQuery, SBlendQueryResult& result1, SBlendQueryResult& result2) const = 0;
  973.         virtual uint32                GetNumBlends(FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo) const = 0;
  974.         virtual const SFragmentBlend* GetBlend(FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, uint32 blendNum) const = 0;
  975.         virtual const SFragmentBlend* GetBlend(FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, SFragmentBlendUid uid) const = 0;
  976.  
  977.         virtual const char*           FindSubADBFilenameForID(FragmentID fragmentID) const = 0;
  978.         virtual bool                  RemoveSubADBFragmentFilter(FragmentID fragmentID) = 0;
  979.         virtual bool                  AddSubADBFragmentFilter(const string& sADBFileName, FragmentID fragmentID) = 0;
  980.         virtual void                  GetSubADBFragmentFilters(SMiniSubADB::TSubADBArray& outList) const = 0;
  981.  
  982.         virtual bool                  AddSubADBTagFilter(const string& sParentFilename, const string& sADBFileName, const TagState& tag) = 0;
  983.         virtual bool                  MoveSubADBFilter(const string& sADBFileName, const bool bMoveUp) = 0;
  984.         virtual bool                  DeleteSubADBFilter(const string& sADBFileName) = 0;
  985.         virtual bool                  ClearSubADBFilter(const string& sADBFileName) = 0;
  986.  
  987.         virtual void                  QueryUsedTags(const FragmentID fragmentID, const SFragTagState& filter, SFragTagState& usedTags) const = 0;
  988. };
  989.  
  990. class IAnimationDatabaseManager
  991. {
  992. public:
  993.         virtual ~IAnimationDatabaseManager() {}
  994.  
  995.         virtual int                       GetTotalDatabases() const = 0;
  996.         virtual const IAnimationDatabase* GetDatabase(int idx) const = 0;
  997.  
  998.         virtual const IAnimationDatabase* FindDatabase(const uint32 crcFilename) const = 0;
  999.         virtual const IAnimationDatabase* Load(const char* filename) = 0;
  1000.         virtual const SControllerDef*     LoadControllerDef(const char* filename) = 0;
  1001.         virtual const CTagDefinition*     LoadTagDefs(const char* filename, bool isTags) = 0;
  1002.  
  1003.         virtual const SControllerDef*     FindControllerDef(const uint32 crcFilename) const = 0;
  1004.         virtual const SControllerDef*     FindControllerDef(const char* filename) const = 0;
  1005.  
  1006.         virtual const CTagDefinition*     FindTagDef(const uint32 crcFilename) const = 0;
  1007.         virtual const CTagDefinition*     FindTagDef(const char* filename) const = 0;
  1008.  
  1009.         virtual IAnimationDatabase*       Create(const char* filename, const char* defFilename) = 0;
  1010.         virtual CTagDefinition*           CreateTagDefinition(const char* filename) = 0;
  1011.  
  1012.         virtual void                      ReloadAll() = 0;
  1013.         virtual void                      UnloadAll() = 0;
  1014. };
  1015.  
  1016. enum EPriorityComparison
  1017. {
  1018.         Lower,
  1019.         Equal,
  1020.         Higher
  1021. };
  1022.  
  1023. class IActionController;
  1024. class IAction;
  1025. typedef _smart_ptr<IAction> IActionPtr;
  1026. class CAnimation;
  1027. struct SGameObjectEvent;
  1028.  
  1029. class IScope
  1030. {
  1031. public:
  1032.         virtual ~IScope() {}
  1033.  
  1034.         virtual const char*               GetName() = 0;
  1035.         virtual uint32                    GetID() = 0;
  1036.         virtual ICharacterInstance*       GetCharInst() = 0;
  1037.         virtual IActionController&        GetActionController() const = 0;
  1038.         virtual SAnimationContext&        GetContext() const = 0;
  1039.         virtual uint32                    GetContextID() const = 0;
  1040.         virtual const IAnimationDatabase& GetDatabase() const = 0;
  1041.         virtual IEntity&                  GetEntity() const = 0;
  1042.         virtual EntityId                  GetEntityId() const = 0;
  1043.         virtual IAction*                  GetAction() const = 0;
  1044.         virtual bool                      HasDatabase() const = 0;
  1045.  
  1046.         virtual IActionController*        GetEnslavedActionController() const = 0;
  1047.  
  1048.         virtual uint32                    GetTotalLayers() const = 0;
  1049.         virtual uint32                    GetBaseLayer() const = 0;
  1050.  
  1051.         virtual void                      IncrementTime(float timeDelta) = 0;
  1052.  
  1053.         virtual const CAnimation*         GetTopAnim(int layer) const = 0;
  1054.         virtual CAnimation*               GetTopAnim(int layer) = 0;
  1055.  
  1056.         virtual void                      ApplyAnimWeight(uint32 layer, float weight) = 0;
  1057.  
  1058.         virtual bool                      IsDifferent(const FragmentID aaID, const TagState& fragmentTags, const TagID subContext = TAG_ID_INVALID) const = 0;
  1059.         virtual FragmentID                GetLastFragmentID() const = 0;
  1060.         virtual const SFragTagState& GetLastTagState() const = 0;
  1061.         virtual float                CalculateFragmentTimeRemaining() const = 0;
  1062.         virtual float                CalculateFragmentDuration(const CFragment& fragment) const = 0;
  1063.  
  1064.         virtual float                GetFragmentDuration() const = 0;
  1065.         virtual float                GetFragmentTime() const = 0;
  1066.  
  1067.         virtual TagState             GetAdditionalTags() const = 0;
  1068.  
  1069.         virtual void                 _FlushFromEditor() = 0; // needs to be moved into an editor-only interface
  1070.  
  1071.         virtual void                 MuteLayers(uint32 mutedAnimLayerMask, uint32 mutedProcLayerMask) = 0;
  1072.  
  1073.         template<typename PODTYPE>
  1074.         bool GetParam(const char* paramName, PODTYPE& value) const;
  1075.         template<typename PODTYPE>
  1076.         bool GetParam(uint32 paramNameCRC, PODTYPE& value) const;
  1077. };
  1078.  
  1079. enum EActionControllerFlags
  1080. {
  1081.         AC_PausedUpdate  = BIT(0),
  1082.         AC_DebugDraw     = BIT(1),
  1083.         AC_DumpState     = BIT(2),
  1084.         AC_IsInUpdate    = BIT(3),
  1085.         AC_NoTransitions = BIT(4),
  1086. };
  1087.  
  1088. enum EActionFailure
  1089. {
  1090.         AF_QueueFull,
  1091.         AF_InvalidContext,
  1092. };
  1093.  
  1094. class CMannequinParams
  1095. {
  1096. public:
  1097.  
  1098.         void Reset()
  1099.         {
  1100.                 m_paramList.clear();
  1101.         }
  1102.  
  1103.         const SMannParameter* FindParam(const char* paramName) const
  1104.         {
  1105.                 const uint32 crc = CCrc32::ComputeLowercase(paramName);
  1106.                 return FindParam(crc);
  1107.         }
  1108.  
  1109.         const SMannParameter* FindParam(uint32 paramNameCRC) const
  1110.         {
  1111.                 const uint32 numParams = m_paramList.size();
  1112.                 for (uint32 i = 0; i < numParams; i++)
  1113.                 {
  1114.                         const SMannParameter& param = m_paramList[i];
  1115.                         if (param.crc == paramNameCRC)
  1116.                         {
  1117.                                 return &param;
  1118.                         }
  1119.                 }
  1120.  
  1121.                 return NULL;
  1122.         }
  1123.  
  1124.         template<typename PODTYPE>
  1125.         bool GetParam(const char* paramName, PODTYPE& value) const
  1126.         {
  1127.                 const uint32 crc = CCrc32::ComputeLowercase(paramName);
  1128.                 return GetParam(crc, value);
  1129.         }
  1130.  
  1131.         template<typename PODTYPE>
  1132.         bool GetParam(uint32 paramNameCRC, PODTYPE& value) const
  1133.         {
  1134.                 static_assert(sizeof(PODTYPE) <= sizeof(QuatT), "Invalid type size!");
  1135.                 const SMannParameter* pParam = FindParam(paramNameCRC);
  1136.                 if (pParam)
  1137.                 {
  1138.                         value = *alias_cast<const PODTYPE*>(&pParam->value);
  1139.                         return true;
  1140.                 }
  1141.  
  1142.                 return false;
  1143.         }
  1144.  
  1145.         bool RemoveParam(const char* paramName)
  1146.         {
  1147.                 const uint32 crc = CCrc32::ComputeLowercase(paramName);
  1148.                 return RemoveParam(crc);
  1149.         }
  1150.  
  1151.         bool RemoveParam(uint32 paramNameCRC)
  1152.         {
  1153.                 const TMannParamList::iterator iEnd = m_paramList.end();
  1154.                 for (TMannParamList::iterator i = m_paramList.begin(); i != iEnd; ++i)
  1155.                 {
  1156.                         const SMannParameter& param = *i;
  1157.                         if (param.crc == paramNameCRC)
  1158.                         {
  1159.                                 m_paramList.erase(i);
  1160.                                 return true;
  1161.                         }
  1162.                 }
  1163.                 return false;
  1164.         }
  1165.  
  1166.         template<typename PODTYPE>
  1167.         void SetParam(const char* paramName, const PODTYPE& value)
  1168.         {
  1169.                 const uint32 crc = CCrc32::ComputeLowercase(paramName);
  1170.                 SetParam(crc, value);
  1171.         }
  1172.  
  1173.         template<typename PODTYPE>
  1174.         void SetParam(uint32 paramNameCRC, const PODTYPE& value)
  1175.         {
  1176.                 static_assert(sizeof(PODTYPE) <= sizeof(QuatT), "Invalid type size!");
  1177.                 const uint32 numParams = m_paramList.size();
  1178.                 for (uint32 i = 0; i < numParams; i++)
  1179.                 {
  1180.                         SMannParameter& param = m_paramList[i];
  1181.                         if (param.crc == paramNameCRC)
  1182.                         {
  1183.                                 *alias_cast<PODTYPE*>(&param.value) = value;
  1184.                                 return;
  1185.                         }
  1186.                 }
  1187.  
  1188.                 m_paramList.resize(numParams + 1);
  1189.                 SMannParameter& param = m_paramList[numParams];
  1190.                 param.crc = paramNameCRC;
  1191.                 *alias_cast<PODTYPE*>(&param.value) = value;
  1192.         }
  1193.  
  1194. private:
  1195.         TMannParamList m_paramList;
  1196. };
  1197.  
  1198. class IActionController
  1199. {
  1200. public:
  1201.         virtual void OnEvent(const SGameObjectEvent& event) = 0;
  1202.         virtual void OnAnimationEvent(ICharacterInstance* pCharacter, const AnimEventInstance& event) = 0;
  1203.  
  1204.         // Completely resets the state of the action controller
  1205.         virtual void Reset() = 0;
  1206.  
  1207.         // Flushes all currently playing and queued actions
  1208.         virtual void                     Flush() = 0;
  1209.  
  1210.         virtual uint32                   GetTotalScopes() const = 0;
  1211.         virtual void                     SetScopeContext(uint32 scopeContextID, IEntity& entity, ICharacterInstance* pCharacter, const IAnimationDatabase* animDatabase) = 0;
  1212.         virtual void                     ClearScopeContext(uint32 scopeContextID, bool flushAnimations = true) = 0;
  1213.  
  1214.         virtual bool                     IsScopeActive(uint32 scopeID) const = 0;
  1215.         virtual ActionScopes             GetActiveScopeMask() const = 0;
  1216.  
  1217.         virtual IEntity&                 GetEntity() const = 0;
  1218.         virtual EntityId                 GetEntityId() const = 0;
  1219.  
  1220.         virtual IScope*                  GetScope(uint32 scopeID) = 0;
  1221.         virtual const IScope*            GetScope(uint32 scopeID) const = 0;
  1222.  
  1223.         virtual uint32                   GetScopeID(const char* name) const = 0;
  1224.  
  1225.         virtual FragmentID               GetFragID(uint32 crc) const = 0;
  1226.         virtual TagID                    GetGlobalTagID(uint32 crc) const = 0;
  1227.         virtual TagID                    GetFragTagID(FragmentID fragID, uint32 crc) const = 0;
  1228.         virtual const CTagDefinition*    GetTagDefinition(FragmentID fragID) const = 0;
  1229.  
  1230.         virtual void                     Queue(IAction& action, float time = -1.0f) = 0;
  1231.         virtual void                     Requeue(IAction& action) = 0;
  1232.  
  1233.         virtual void                     Update(float timePassed) = 0;
  1234.  
  1235.         virtual SAnimationContext&       GetContext() = 0;
  1236.         virtual const SAnimationContext& GetContext() const = 0;
  1237.  
  1238.         virtual void                     Pause() = 0;
  1239.         enum EResumeFlags
  1240.         {
  1241.                 ERF_RestartAnimations              = BIT(0),
  1242.                 ERF_RestoreLoopingAnimationTime    = BIT(1),
  1243.                 ERF_RestoreNonLoopingAnimationTime = BIT(2),
  1244.  
  1245.                 ERF_Default                        = ERF_RestartAnimations | ERF_RestoreLoopingAnimationTime | ERF_RestoreNonLoopingAnimationTime
  1246.         };
  1247.         virtual void  Resume(uint32 resumeFlags = ERF_Default) = 0;
  1248.  
  1249.         virtual void  SetFlag(EActionControllerFlags flag, bool enable) = 0;
  1250.  
  1251.         virtual void  SetTimeScale(float timeScale) = 0;
  1252.         virtual float GetTimeScale() const = 0;
  1253.  
  1254.         // Only needed for animationgraph?
  1255.         virtual bool                            IsActionPending(uint32 userToken) const = 0;
  1256.  
  1257.         virtual bool                            IsDifferent(const FragmentID fragID, const TagState& fragmentTags, const ActionScopes& scopeMask) const = 0;
  1258.  
  1259.         virtual bool                            CanInstall(const IAction& action, const ActionScopes& scopeMask, float timeStep, float& timeTillInstall) const = 0;
  1260.  
  1261.         virtual bool                            QueryDuration(IAction& action, float& fragmentDuration, float& transitionDuration) const = 0;
  1262.  
  1263.         virtual void                            SetSlaveController(IActionController& target, uint32 targetContext, bool enslave, const IAnimationDatabase* piOptionTargetDatabase) = 0;
  1264.  
  1265.         virtual void                            RegisterListener(IMannequinListener* listener) = 0;
  1266.         virtual void                            UnregisterListener(IMannequinListener* listener) = 0;
  1267.  
  1268.         virtual class IProceduralContext*       FindOrCreateProceduralContext(const char* contextName) = 0;
  1269.         virtual const class IProceduralContext* FindProceduralContext(const char* contextName) const = 0;
  1270.         virtual class IProceduralContext*       FindProceduralContext(const char* contextName) = 0;
  1271.         virtual class IProceduralContext*       CreateProceduralContext(const char* contextName) = 0;
  1272.  
  1273.         virtual QuatT                           ExtractLocalAnimLocation(FragmentID fragID, TagState fragTags, uint32 scopeID, uint32 optionIdx) = 0;
  1274.  
  1275.         virtual void                            Release() = 0;
  1276.  
  1277.         virtual const SMannParameter*           GetParam(const char* paramName) const = 0;
  1278.         virtual const SMannParameter*           GetParam(uint32 paramNameCRC) const = 0;
  1279.         virtual bool                            RemoveParam(const char* paramName) = 0;
  1280.         virtual bool                            RemoveParam(uint32 paramNameCRC) = 0;
  1281.         virtual void                            SetParam(const char* paramName, const SMannParameter& param) = 0;
  1282.         virtual void                            SetParam(const SMannParameter& param) = 0;
  1283.         virtual void                            ResetParams() = 0;
  1284.  
  1285.         template<typename PODTYPE>
  1286.         bool GetParam(const char* paramName, PODTYPE& value) const
  1287.         {
  1288.                 const SMannParameter* pParam = GetParam(paramName);
  1289.                 if (pParam)
  1290.                 {
  1291.                         value = *alias_cast<const PODTYPE*>(&pParam->value);
  1292.                         return true;
  1293.                 }
  1294.                 return false;
  1295.         }
  1296.  
  1297.         template<typename PODTYPE>
  1298.         bool GetParam(uint32 paramNameCRC, PODTYPE& value) const
  1299.         {
  1300.                 const SMannParameter* pParam = GetParam(paramNameCRC);
  1301.                 if (pParam)
  1302.                 {
  1303.                         value = *alias_cast<const PODTYPE*>(&pParam->value);
  1304.                         return true;
  1305.                 }
  1306.                 return false;
  1307.         }
  1308.  
  1309.         template<typename PODTYPE>
  1310.         void SetParam(const char* paramName, const PODTYPE& value)
  1311.         {
  1312.                 SMannParameter param;
  1313.                 param.crc = MannGenCRC(paramName);
  1314.                 *alias_cast<PODTYPE*>(&param.value) = value;
  1315.                 return SetParam(paramName, param);
  1316.         }
  1317.  
  1318.         template<typename PODTYPE>
  1319.         void SetParam(uint32 paramNameCRC, const PODTYPE& value)
  1320.         {
  1321.                 SMannParameter param;
  1322.                 param.crc = paramNameCRC;
  1323.                 *alias_cast<PODTYPE*>(&param.value) = value;
  1324.                 return SetParam(param);
  1325.         }
  1326.  
  1327. protected:
  1328.         virtual ~IActionController() {}
  1329. };
  1330.  
  1331. #define DEFINE_ACTION(name)                                     \
  1332.   virtual const char* GetName() const override { return name; } \
  1333.   virtual void DoDelete() override { delete this; }
  1334.  
  1335. class IAction
  1336. {
  1337. public:
  1338.         friend class CActionController;
  1339.         friend class CActionScope;
  1340.  
  1341.         //---------------------------------------------------------------------------------------------------------
  1342.         // Action Status
  1343.         //---------------------------------------------------------------------------------------------------------
  1344.         // None                                 - Not installed
  1345.         // Pending                      - In the pending action queue
  1346.         // Installed            - Installed on a scope
  1347.         // Exiting                      - Action is finishing up, via an exit transition
  1348.         // Finished                     - Finished. Will be removed from its scope on the the next update
  1349.         //---------------------------------------------------------------------------------------------------------
  1350.         enum EStatus
  1351.         {
  1352.                 None,
  1353.                 Pending,
  1354.                 Installed,
  1355.                 Exiting,
  1356.                 Finished
  1357.         };
  1358.  
  1359.         //---------------------------------------------------------------------------------------------------------
  1360.         // Action Flags
  1361.         //---------------------------------------------------------------------------------------------------------
  1362.         // BlendOut                                                             - Can the action now blend out into a new action?
  1363.         // NoAutoBlendOut                                       - The action should not allow itself to be blended out on completion
  1364.         // Interruptable                                        - The action can be interrupted and so is pushed onto the pending action queue
  1365.         //                                                                                                      rather than deleted
  1366.         // Installing                                                   - This action is in the process of being installed (Enter is not called yet & action is still in the queue)
  1367.         // Requeued                                                             - This action is installed for a requeue on the pending queue
  1368.         // TrumpSelf                                                    - This action should be treated as a higher priority when compared to itself
  1369.         // Transitioning                                        - This action is transitioning in
  1370.         // PlayingFragment                              - This action is playing its core fragment
  1371.         // TransitioningOut                             - This action is transitioning out
  1372.         // TransitionPending                    - This action is going to transition off soon
  1373.         // FragmentIsOneShot                    - This action is a one-shot & so will end itself at the end of the sequence
  1374.         // Stopping                                                             - This action is marked for stopping
  1375.         //---------------------------------------------------------------------------------------------------------
  1376.         enum EFlags
  1377.         {
  1378.                 BlendOut          = BIT(0),
  1379.                 NoAutoBlendOut    = BIT(1),
  1380.                 Interruptable     = BIT(2),
  1381.                 Installing        = BIT(4),
  1382.                 Started           = BIT(5),
  1383.                 Requeued          = BIT(6),
  1384.                 TrumpSelf         = BIT(7),
  1385.                 Transitioning     = BIT(8),
  1386.                 PlayingFragment   = BIT(9),
  1387.                 TransitioningOut  = BIT(10),
  1388.                 TransitionPending = BIT(11),
  1389.                 FragmentIsOneShot = BIT(12),
  1390.                 Stopping          = BIT(13),
  1391.                 PlaybackStateMask = (Transitioning | PlayingFragment | TransitioningOut)
  1392.         };
  1393.  
  1394.         virtual ~IAction()
  1395.         {
  1396. #ifndef _RELEASE
  1397.                 if ((m_flags & Started))
  1398.                 {
  1399.                         __debugbreak();
  1400.                 }
  1401. #endif //_RELEASE
  1402.         }
  1403.  
  1404.         IAction(int priority, FragmentID fragmentID = FRAGMENT_ID_INVALID, const TagState& fragTags = TAG_STATE_EMPTY, uint32 flags = 0, ActionScopes scopeMask = 0, uint32 userToken = 0)
  1405.                 : m_context(NULL)
  1406.                 , m_activeTime(0.0f)
  1407.                 , m_queueTime(-1.0f)
  1408.                 , m_forcedScopeMask(scopeMask)
  1409.                 , m_installedScopeMask(0)
  1410.                 , m_subContext(TAG_ID_INVALID)
  1411.                 , m_priority(priority)
  1412.                 , m_eStatus(None)
  1413.                 , m_flags(flags)
  1414.                 , m_rootScope(NULL)
  1415.                 , m_fragmentID(fragmentID)
  1416.                 , m_fragTags(fragTags)
  1417.                 , m_optionIdx(OPTION_IDX_RANDOM)
  1418.                 , m_userToken(userToken)
  1419.                 , m_refCount(0)
  1420.                 , m_speedBias(1.0f)
  1421.                 , m_animWeight(1.0f)
  1422.         {
  1423.         }
  1424.  
  1425.         void AddRef()
  1426.         {
  1427.                 m_refCount++;
  1428.         }
  1429.         void Release()
  1430.         {
  1431.                 m_refCount--;
  1432.                 if (m_refCount <= 0)
  1433.                 {
  1434.                         CRY_ASSERT((m_flags & Started) == 0);
  1435.  
  1436.                         DoDelete();
  1437.                 }
  1438.         }
  1439.  
  1440.         FragmentID GetFragmentID() const
  1441.         {
  1442.                 return m_fragmentID;
  1443.         }
  1444.         TagState GetFragTagState() const
  1445.         {
  1446.                 return m_fragTags;
  1447.         }
  1448.         uint32 GetOptionIdx() const
  1449.         {
  1450.                 return m_optionIdx;
  1451.         }
  1452.         uint32 GetUserToken() const
  1453.         {
  1454.                 return m_userToken;
  1455.         }
  1456.         int GetPriority() const
  1457.         {
  1458.                 return m_priority;
  1459.         }
  1460.         void SetOptionIdx(uint32 optionIdx)
  1461.         {
  1462.                 m_optionIdx = optionIdx;
  1463.         }
  1464.  
  1465.         bool CanBlendOut(EPriorityComparison priorityComparison) const
  1466.         {
  1467.                 switch (priorityComparison)
  1468.                 {
  1469.                 case Higher:
  1470.                         return true;
  1471.                         break;
  1472.                 case Lower:
  1473.                 case Equal:
  1474.                 default:
  1475.                         return ((m_flags & (FragmentIsOneShot | NoAutoBlendOut)) == FragmentIsOneShot)
  1476.                                || ((m_flags & BlendOut) != 0)
  1477.                                || (m_eStatus == Finished)
  1478.                                || (m_eStatus == Exiting);
  1479.                         break;
  1480.                 }
  1481.         }
  1482.         ActionScopes GetInstalledScopeMask() const
  1483.         {
  1484.                 return m_installedScopeMask;
  1485.         }
  1486.         ActionScopes GetForcedScopeMask() const
  1487.         {
  1488.                 return m_forcedScopeMask;
  1489.         }
  1490.         EStatus GetStatus() const
  1491.         {
  1492.                 return m_eStatus;
  1493.         }
  1494.         const IScope& GetRootScope() const
  1495.         {
  1496.                 CRY_ASSERT_MESSAGE(m_rootScope, "Action not installed or queued into actionStack!");
  1497.                 return *m_rootScope;
  1498.         }
  1499.         IScope& GetRootScope()
  1500.         {
  1501.                 CRY_ASSERT_MESSAGE(m_rootScope, "Action not installed or queued into actionStack!");
  1502.                 return *m_rootScope;
  1503.         }
  1504.         uint32 GetFlags() const
  1505.         {
  1506.                 return m_flags;
  1507.         }
  1508.         bool IsOneShot() const
  1509.         {
  1510.                 return 0 != (m_flags & FragmentIsOneShot);
  1511.         }
  1512.         float GetActiveTime() const
  1513.         {
  1514.                 return m_activeTime;
  1515.         }
  1516.         virtual void Install()
  1517.         {
  1518.                 if (m_eStatus != Finished)
  1519.                 {
  1520.                         m_eStatus = Installed;
  1521.                 }
  1522.                 m_flags &= ~PlaybackStateMask;
  1523.         }
  1524.         virtual void Enter()
  1525.         {
  1526.                 m_flags |= Started;
  1527.         }
  1528.         virtual void Fail(EActionFailure actionFailure)
  1529.         {
  1530.                 m_eStatus = None;
  1531.                 m_flags &= ~Started;
  1532.         }
  1533.         virtual void Exit()
  1534.         {
  1535.                 m_eStatus = None;
  1536.                 m_flags &= ~Started;
  1537.         }
  1538.         virtual EStatus UpdatePending(float timePassed)
  1539.         {
  1540.                 const float oldActiveTime = m_activeTime;
  1541.                 m_activeTime += timePassed;
  1542.  
  1543.                 //--- If we have a passed a limited queue time and have ticked at least once, then exit
  1544.                 if ((m_queueTime >= 0.0f) && (oldActiveTime > 0.0f) && (m_activeTime > m_queueTime))
  1545.                 {
  1546.                         m_eStatus = Finished;
  1547.                 }
  1548.  
  1549.                 return m_eStatus;
  1550.         }
  1551.         virtual EStatus Update(float timePassed)
  1552.         {
  1553.                 m_activeTime += timePassed;
  1554.  
  1555.                 return m_eStatus;
  1556.         }
  1557.  
  1558.         virtual void OnResolveActionInstallations()
  1559.         {
  1560.                 if (m_fragmentID != FRAGMENT_ID_INVALID)
  1561.                 {
  1562.                         const SFragmentDef& fragmentDef = m_context->controllerDef.GetFragmentDef(m_fragmentID);
  1563.                         if ((fragmentDef.flags & SFragmentDef::AUTO_REINSTALL_BEST_MATCH) != 0)
  1564.                         {
  1565.                                 if (IsDifferent(m_fragmentID, m_fragTags))
  1566.                                 {
  1567.                                         SetFragment(m_fragmentID, m_fragTags, m_optionIdx, m_userToken, false);
  1568.                                 }
  1569.                         }
  1570.                 }
  1571.         }
  1572.  
  1573.         bool Interrupt()
  1574.         {
  1575.                 if (IsInstalling() || ((m_flags & Started) == 0))
  1576.                         m_eStatus = None;
  1577.                 else
  1578.                         Exit();
  1579.  
  1580.                 return (m_flags & Interruptable) != 0;
  1581.         }
  1582.  
  1583.         virtual EPriorityComparison ComparePriority(const IAction& actionCurrent) const
  1584.         {
  1585.                 return Equal;
  1586.         }
  1587.  
  1588.         virtual void OnRequestBlendOut(EPriorityComparison priorityComp)
  1589.         {
  1590.         }
  1591.  
  1592.         bool IsDifferent(const FragmentID fragID, const TagState& fragmentTags) const;
  1593.  
  1594.         void SetSpeedBias(float speedBias)
  1595.         {
  1596.                 m_speedBias = speedBias;
  1597.         }
  1598.         float GetSpeedBias() const
  1599.         {
  1600.                 return m_speedBias;
  1601.         }
  1602.  
  1603.         TagID GetSubContext() const
  1604.         {
  1605.                 return m_subContext;
  1606.         }
  1607.         void SetSubContext(const TagID subContext)
  1608.         {
  1609.                 m_subContext = subContext;
  1610.         }
  1611.  
  1612.         void SetAnimWeight(float animWeight)
  1613.         {
  1614.                 m_animWeight = animWeight;
  1615.         }
  1616.         float GetAnimWeight() const
  1617.         {
  1618.                 return m_animWeight;
  1619.         }
  1620.  
  1621.         virtual void OnSequenceFinished(int layer, uint32 scopeId)
  1622.         {
  1623.         }
  1624.  
  1625.         void Stop()
  1626.         {
  1627.                 m_flags |= (BlendOut | Stopping);
  1628.  
  1629.                 const uint32 numSlaves = m_slaveActions.size();
  1630.                 for (uint32 i = 0; i < numSlaves; i++)
  1631.                 {
  1632.                         m_slaveActions[i]->Stop();
  1633.                 }
  1634.         }
  1635.  
  1636.         void ForceFinish()
  1637.         {
  1638.                 m_eStatus = Finished;
  1639.                 m_flags &= ~Interruptable;
  1640.  
  1641.                 ForceFinishSlaveActions();
  1642.         }
  1643.  
  1644.         void ForceFinishSlaveActions()
  1645.         {
  1646.                 const uint32 numSlaves = m_slaveActions.size();
  1647.                 for (uint32 i = 0; i < numSlaves; i++)
  1648.                 {
  1649.                         m_slaveActions[i]->ForceFinish();
  1650.                 }
  1651.         }
  1652.  
  1653.         void BeginInstalling()
  1654.         {
  1655.                 CRY_ASSERT(!IsInstalling());
  1656.                 m_flags |= Installing;
  1657.                 m_flags &= ~(PlayingFragment | Transitioning);
  1658.         }
  1659.         void EndInstalling()
  1660.         {
  1661.                 CRY_ASSERT(IsInstalling());
  1662.                 m_flags &= ~Installing;
  1663.         }
  1664.         bool IsInstalling() const
  1665.         {
  1666.                 return ((m_flags & Installing) != 0);
  1667.         }
  1668.  
  1669.         template<typename PODTYPE>
  1670.         bool GetParam(const char* paramName, PODTYPE& value) const
  1671.         {
  1672.                 if (!m_mannequinParams.GetParam(paramName, value))
  1673.                 {
  1674.                         if (m_rootScope)
  1675.                         {
  1676.                                 const IActionController& actionController = m_rootScope->GetActionController();
  1677.                                 return actionController.GetParam(paramName, value);
  1678.                         }
  1679.                         else
  1680.                         {
  1681.                                 return false;
  1682.                         }
  1683.                 }
  1684.                 return true;
  1685.         }
  1686.  
  1687.         template<typename PODTYPE>
  1688.         bool GetParam(uint32 paramNameCRC, PODTYPE& value) const
  1689.         {
  1690.                 if (!m_mannequinParams.GetParam(paramNameCRC, value))
  1691.                 {
  1692.                         if (m_rootScope)
  1693.                         {
  1694.                                 const IActionController& actionController = m_rootScope->GetActionController();
  1695.                                 return actionController.GetParam(paramNameCRC, value);
  1696.                         }
  1697.                         else
  1698.                         {
  1699.                                 return false;
  1700.                         }
  1701.                 }
  1702.                 return true;
  1703.         }
  1704.  
  1705.         template<typename PODTYPE>
  1706.         void SetParam(const char* paramName, const PODTYPE& value)
  1707.         {
  1708.                 return m_mannequinParams.SetParam(paramName, value);
  1709.         }
  1710.  
  1711.         template<typename PODTYPE>
  1712.         void SetParam(uint32 paramNameCRC, const PODTYPE& value)
  1713.         {
  1714.                 return m_mannequinParams.SetParam(paramNameCRC, value);
  1715.         }
  1716.  
  1717.         void ResetParams()
  1718.         {
  1719.                 m_mannequinParams.Reset();
  1720.         }
  1721.  
  1722.         bool IsTransitioning() const
  1723.         {
  1724.                 return (m_flags & Transitioning) != 0;
  1725.         }
  1726.         bool IsPlayingFragment() const
  1727.         {
  1728.                 return (m_flags & PlayingFragment) != 0;
  1729.         }
  1730.         bool IsTransitioningOut() const
  1731.         {
  1732.                 return (m_flags & TransitioningOut) != 0;
  1733.         }
  1734.  
  1735.         bool IsStarted() const
  1736.         {
  1737.                 return (m_flags & Started) != 0;
  1738.         }
  1739.  
  1740.         virtual IAction*    CreateSlaveAction(FragmentID slaveFragID, const TagState& fragTags, SAnimationContext& context) = 0;
  1741.  
  1742.         virtual void        OnTransitionStarted()                                                            {}
  1743.         virtual void        OnFragmentStarted()                                                              {}
  1744.         virtual void        OnTransitionOutStarted()                                                         {}
  1745.         virtual void        OnInitialise()                                                                   {}
  1746.         virtual void        OnActionFinished()                                                               {}
  1747.  
  1748.         virtual void        OnEvent(const SGameObjectEvent& event)                                           {}
  1749.         virtual void        OnAnimationEvent(ICharacterInstance* pCharacter, const AnimEventInstance& event) {}
  1750.         virtual void        OnActionEvent(const uint32 eventCRC)                                             {}
  1751.  
  1752.         virtual const char* GetName() const = 0;
  1753.         virtual void        DoDelete() = 0;
  1754.  
  1755.         IAction*            GetSlaveAction(uint32 i)
  1756.         {
  1757.                 return m_slaveActions[i].get();
  1758.         }
  1759.         uint32 GetTotalSlaveActions() const
  1760.         {
  1761.                 return m_slaveActions.size();
  1762.         }
  1763.  
  1764. protected:
  1765.  
  1766.         void SetFragment(const FragmentID fragmentID, const TagState& tagState = TAG_STATE_EMPTY, uint32 optionIdx = OPTION_IDX_RANDOM, const uint32 userToken = 0, bool trumpSelf = true)
  1767.         {
  1768.                 m_fragmentID = fragmentID;
  1769.                 m_fragTags = tagState;
  1770.                 m_optionIdx = optionIdx;
  1771.                 m_userToken = userToken;
  1772.                 if (trumpSelf)
  1773.                         m_flags |= TrumpSelf;
  1774.                 else
  1775.                         m_flags &= ~TrumpSelf;
  1776.  
  1777.                 if (m_eStatus == Installed)
  1778.                 {
  1779.                         if ((m_flags & Requeued) == 0)
  1780.                         {
  1781.                                 m_flags |= Requeued;
  1782.  
  1783.                                 IActionController& actionController = m_rootScope->GetActionController();
  1784.  
  1785.                                 actionController.Requeue(*this);
  1786.                         }
  1787.                 }
  1788.         }
  1789.  
  1790.         EPriorityComparison DoComparePriority(const IAction& actionCurrent) const
  1791.         {
  1792.                 if ((&actionCurrent == this) && ((m_flags & TrumpSelf) != 0))
  1793.                 {
  1794.                         return Higher;
  1795.                 }
  1796.                 else if (m_priority > actionCurrent.m_priority)
  1797.                 {
  1798.                         return Higher;
  1799.                 }
  1800.                 else if (m_priority == actionCurrent.m_priority)
  1801.                 {
  1802.                         return ComparePriority(actionCurrent);
  1803.                 }
  1804.                 return Lower;
  1805.         }
  1806.  
  1807.         SAnimationContext* m_context;
  1808.         float              m_activeTime;
  1809.         float              m_queueTime;
  1810.         ActionScopes       m_forcedScopeMask;
  1811.         ActionScopes       m_installedScopeMask;
  1812.         TagID              m_subContext;
  1813.         int                m_priority;
  1814.         EStatus            m_eStatus;
  1815.         uint32             m_flags;
  1816.         IScope*            m_rootScope;
  1817.         FragmentID         m_fragmentID;
  1818.         TagState           m_fragTags;
  1819.         uint32             m_optionIdx;
  1820.         uint32             m_userToken;
  1821.         int                m_refCount;
  1822.         float              m_speedBias;
  1823.         float              m_animWeight;
  1824.  
  1825.         CMannequinParams   m_mannequinParams;
  1826.  
  1827. private:
  1828.         void TransitionStarted()
  1829.         {
  1830.                 m_flags &= ~PlaybackStateMask;
  1831.                 m_flags |= Transitioning;
  1832.  
  1833.                 OnTransitionStarted();
  1834.         }
  1835.  
  1836.         void FragmentStarted()
  1837.         {
  1838.                 m_flags &= ~PlaybackStateMask;
  1839.                 m_flags |= PlayingFragment;
  1840.  
  1841.                 OnFragmentStarted();
  1842.         }
  1843.  
  1844.         void TransitionOutStarted()
  1845.         {
  1846.                 m_flags &= ~PlaybackStateMask;
  1847.                 m_flags |= TransitioningOut;
  1848.  
  1849.                 OnTransitionOutStarted();
  1850.         }
  1851.  
  1852.         void Initialise(SAnimationContext& context)
  1853.         {
  1854.                 m_context = &context;
  1855.                 m_eStatus = Pending;
  1856.                 m_rootScope = NULL;
  1857.                 m_flags &= ~Started;
  1858.  
  1859.                 m_activeTime = 0.0f;
  1860.  
  1861.                 OnInitialise();
  1862.         }
  1863.  
  1864.         DynArray<_smart_ptr<IAction>> m_slaveActions;
  1865. };
  1866.  
  1867. template<class CONTEXT>
  1868. class TAction : public IAction
  1869. {
  1870. public:
  1871.  
  1872.         DEFINE_ACTION("BaseAction");
  1873.  
  1874.         TAction(int priority, FragmentID fragmentID = FRAGMENT_ID_INVALID, const TagState& fragTags = TAG_STATE_EMPTY, uint32 flags = 0, ActionScopes scopeMask = 0, uint32 userToken = 0)
  1875.                 :
  1876.                 IAction(priority, fragmentID, fragTags, flags, scopeMask, userToken)
  1877.         {
  1878.         }
  1879.  
  1880.         virtual IAction* CreateSlaveAction(FragmentID slaveFragID, const TagState& fragTags, SAnimationContext& context) override
  1881.         {
  1882.                 ActionScopes forceScopeMask = (slaveFragID == FRAGMENT_ID_INVALID) ? ACTION_SCOPES_ALL : ACTION_SCOPES_NONE;
  1883.                 return new TAction<CONTEXT>(GetPriority(), slaveFragID, fragTags, 0, forceScopeMask);
  1884.         }
  1885.  
  1886.         CONTEXT& GetContext()
  1887.         {
  1888.                 return *((CONTEXT*)m_context);
  1889.         }
  1890.         const CONTEXT& GetContext() const
  1891.         {
  1892.                 return *((const CONTEXT*)m_context);
  1893.         }
  1894. };
  1895.  
  1896. template<typename PODTYPE>
  1897. bool IScope::GetParam(const char* paramName, PODTYPE& value) const
  1898. {
  1899.         IActionPtr pAction = GetAction();
  1900.         return pAction ? pAction->GetParam(paramName, value) : false;
  1901. }
  1902.  
  1903. template<typename PODTYPE>
  1904. bool IScope::GetParam(uint32 paramNameCRC, PODTYPE& value) const
  1905. {
  1906.         IAction* pAction = GetAction();
  1907.         return pAction ? pAction->GetParam(paramNameCRC, value) : false;
  1908. }
  1909.  
  1910. class CMannequinUserParamsManager;
  1911. struct IProceduralClipFactory;
  1912.  
  1913. struct IMannequin
  1914. {
  1915.         virtual ~IMannequin() {}
  1916.  
  1917.         virtual void                         UnloadAll() = 0;
  1918.         virtual void                         ReloadAll() = 0;
  1919.  
  1920.         virtual IAnimationDatabaseManager&   GetAnimationDatabaseManager() = 0;
  1921.         virtual IActionController*           CreateActionController(IEntity* pEntity, SAnimationContext& context) = 0;
  1922.         virtual IActionController*           FindActionController(const IEntity& entity) = 0;
  1923.         virtual IMannequinEditorManager*     GetMannequinEditorManager() = 0;
  1924.         virtual CMannequinUserParamsManager& GetMannequinUserParamsManager() = 0;
  1925.         virtual IProceduralClipFactory&      GetProceduralClipFactory() = 0;
  1926.  
  1927.         virtual void                         AddMannequinGameListener(IMannequinGameListener* pListener) = 0;
  1928.         virtual void                         RemoveMannequinGameListener(IMannequinGameListener* pListener) = 0;
  1929.         virtual uint32                       GetNumMannequinGameListeners() = 0;
  1930.         virtual IMannequinGameListener*      GetMannequinGameListener(uint32 idx) = 0;
  1931.         // Indicates if the mouse is doing something (select / drag / move / etc...)
  1932.         virtual void                         SetSilentPlaybackMode(bool bSilentPlaybackMode) = 0;
  1933.         virtual bool                         IsSilentPlaybackMode() const = 0;
  1934. };
  1935.  
  1936. bool ILINE IAction::IsDifferent(const FragmentID fragID, const TagState& fragmentTags) const
  1937. {
  1938.         IActionController& actionController = GetRootScope().GetActionController();
  1939.         return actionController.IsDifferent(fragID, fragmentTags, m_installedScopeMask);
  1940. }
  1941.  
  1942. class IProceduralClip;
  1943. DECLARE_SHARED_POINTERS(IProceduralClip);
  1944.  
  1945. class IProceduralClip
  1946. {
  1947. public:
  1948.         IProceduralClip()
  1949.                 :
  1950.                 m_entity(NULL),
  1951.                 m_charInstance(NULL),
  1952.                 m_scope(NULL),
  1953.                 m_action(NULL)
  1954.         {
  1955.         }
  1956.  
  1957.         virtual ~IProceduralClip() {}
  1958.  
  1959.         virtual void Initialise(IEntity& entity, ICharacterInstance& charInstance, IScope& scope, IAction& action)
  1960.         {
  1961.                 m_entity = &entity;
  1962.                 m_charInstance = &charInstance;
  1963.                 m_scope = &scope;
  1964.                 m_action = &action;
  1965.         }
  1966.  
  1967.         virtual void        INTERNAL_OnEnter(float blendTime, float duration, const IProceduralParamsPtr& pProceduralParams) = 0;
  1968.         virtual void        OnFail() {}
  1969.         virtual void        OnExit(float blendTime) = 0;
  1970.         virtual void        Update(float timePassed) = 0;
  1971.         virtual const char* GetContextName() const                            { return NULL; }
  1972.         virtual void        SetContext(class IProceduralContext* procContext) { CRY_ASSERT(0); }
  1973.  
  1974. protected:
  1975.         template<typename PODTYPE>
  1976.         bool GetParam(const char* paramName, PODTYPE& value) const
  1977.         {
  1978.                 CRY_ASSERT(m_action != 0);
  1979.                 return m_action->GetParam(paramName, value);
  1980.         }
  1981.  
  1982.         template<typename PODTYPE>
  1983.         bool GetParam(uint32 paramNameCRC, PODTYPE& value) const
  1984.         {
  1985.                 CRY_ASSERT(m_action != 0);
  1986.                 return m_action->GetParam(paramNameCRC, value);
  1987.         }
  1988.  
  1989.         bool IsRootEntity() const
  1990.         {
  1991.                 CRY_ASSERT(m_action != 0);
  1992.                 return (m_scope == &m_action->GetRootScope()) || (m_scope->GetEntityId() != m_action->GetRootScope().GetEntityId());
  1993.         }
  1994.  
  1995.         void SendActionEvent(const uint32 eventCRC) const
  1996.         {
  1997.                 CRY_ASSERT(m_action != 0);
  1998.  
  1999.                 if (eventCRC != 0 && IsRootEntity())
  2000.                 {
  2001.                         m_action->OnActionEvent(eventCRC);
  2002.                 }
  2003.         }
  2004.  
  2005.         ActionScopes GetActionInstalledScopeMask()
  2006.         {
  2007.                 return m_action->GetInstalledScopeMask();
  2008.         }
  2009.  
  2010. protected:
  2011.         IEntity*            m_entity;
  2012.         ICharacterInstance* m_charInstance;
  2013.         IScope*             m_scope;
  2014.  
  2015. private:
  2016.         IActionPtr m_action;
  2017. };
  2018.  
  2019. #define PROCEDURAL_CONTEXT(className, name, uid1, uid2) \
  2020.   CRYINTERFACE_BEGIN()                                  \
  2021.   CRYINTERFACE_ADD(IProceduralContext)                  \
  2022.   CRYINTERFACE_END()                                    \
  2023.   CRYGENERATE_CLASS(className, name, uid1, uid2)        \
  2024. public:                                                 \
  2025.   static const char* GetContextName() { return name; }
  2026.  
  2027. class IProceduralContext : public ICryUnknown
  2028. {
  2029. public:
  2030.         IProceduralContext()
  2031.                 :
  2032.                 m_entity(NULL),
  2033.                 m_actionController(NULL)
  2034.         {
  2035.         }
  2036.  
  2037.         CRYINTERFACE_DECLARE(IProceduralContext, 0xCC61BC284B5243E0, 0xAAE3950B2A7F7DCB);
  2038.  
  2039.         virtual void Initialise(IEntity& entity, IActionController& actionController)
  2040.         {
  2041.                 m_entity = &entity;
  2042.                 m_actionController = &actionController;
  2043.         }
  2044.  
  2045.         virtual void Update(float timePassed) = 0;
  2046.  
  2047. protected:
  2048.         IEntity*           m_entity;
  2049.         IActionController* m_actionController;
  2050. };
  2051.  
  2052. template<class PARAMS = SNoProceduralParams>
  2053. class TProceduralClip : public IProceduralClip
  2054. {
  2055. public:
  2056.         typedef PARAMS TParamsType;
  2057.  
  2058.         virtual void INTERNAL_OnEnter(float blendTime, float duration, const IProceduralParamsPtr& pProceduralParams)
  2059.         {
  2060.                 CRY_ASSERT(pProceduralParams.get());
  2061.                 m_params = *(static_cast<const PARAMS*>(pProceduralParams.get()));
  2062.                 OnEnter(blendTime, duration, m_params);
  2063.         }
  2064.  
  2065.         ILINE const PARAMS& GetParams() const
  2066.         {
  2067.                 return m_params;
  2068.         }
  2069.  
  2070.         virtual void OnEnter(float blendTime, float duration, const PARAMS& proceduralParams) = 0;
  2071.  
  2072. private:
  2073.         PARAMS m_params;
  2074. };
  2075.  
  2076. template<class CONTEXT, class PARAMS = SNoProceduralParams>
  2077. class TProceduralContextualClip : public TProceduralClip<PARAMS>
  2078. {
  2079. public:
  2080.  
  2081.         virtual const char* GetContextName() const
  2082.         {
  2083.                 return CONTEXT::GetContextName();
  2084.         }
  2085.         virtual void SetContext(class IProceduralContext* procContext)
  2086.         {
  2087.                 m_context = (CONTEXT*)procContext;
  2088.         }
  2089.  
  2090. protected:
  2091.         CONTEXT* m_context;
  2092. };
  2093.  
  2094. //////////////////////////////////////////////////////////////////////////
  2095. // Specify a SFragmentQuery to get all animations cached that are contained in
  2096. // fragments that match the query.
  2097. class CFragmentCache
  2098. {
  2099. public:
  2100.         // This will not precache anything, you must call AddAllAnimsFromAllScopes or AddAnimCRCs.
  2101.         explicit CFragmentCache(const SFragmentQuery& fragmentQuery)
  2102.                 : m_fragmentQuery(fragmentQuery)
  2103.                 , m_numOptions(OPTION_IDX_INVALID)
  2104.         {
  2105.         }
  2106.         // Automatically precaches everything in the actioncontroller that matches the query.
  2107.         CFragmentCache(const SFragmentQuery& fragmentQuery, const IActionController* piActionController)
  2108.                 : m_fragmentQuery(fragmentQuery)
  2109.                 , m_numOptions(OPTION_IDX_INVALID)
  2110.         {
  2111.                 PrecacheAnimsFromAllDatabases(piActionController);
  2112.         }
  2113.         // Copies an existing fragment cache but allows you to update the option - useful for round robins.
  2114.         CFragmentCache(const CFragmentCache& fragmentCache, const IActionController* piActionController, const uint32 optionIdx)
  2115.                 : m_fragmentQuery(fragmentCache.m_fragmentQuery)
  2116.                 , m_numOptions(OPTION_IDX_INVALID)
  2117.         {
  2118.                 m_fragmentQuery.optionIdx = optionIdx;
  2119.  
  2120.                 PrecacheAnimsFromAllDatabases(piActionController);
  2121.         }
  2122.         ~CFragmentCache()
  2123.         {
  2124.                 Release();
  2125.         }
  2126.         void PrecacheAnimsFromAllDatabases(const IActionController* piActionController)
  2127.         {
  2128.                 const uint32 numScopes = piActionController->GetTotalScopes();
  2129.                 for (uint32 i = 0; i < numScopes; ++i)
  2130.                 {
  2131.                         // TODO: We should defend adding the same ADB more than once.
  2132.                         const IScope* piScope = piActionController->GetScope(i);
  2133.                         if (piScope->HasDatabase())
  2134.                         {
  2135.                                 const IAnimationDatabase& animationDB = piScope->GetDatabase();
  2136.                                 PrecacheAnimsFromDatabase(&animationDB, piActionController);
  2137.                         }
  2138.                 }
  2139.         }
  2140.         void PrecacheAnimsFromDatabase(const IAnimationDatabase* pAnimDB, const IActionController* piActionController)
  2141.         {
  2142.                 SFragTagState fragTagStateMatch;
  2143.  
  2144.                 // TODO: this should use Union, see for example CActionScope::FillBlendQuery.
  2145.                 SFragTagState fragTagStateQuery(m_fragmentQuery.tagState.globalTags, m_fragmentQuery.tagState.fragmentTags);
  2146.                 uint32 tagSetID;
  2147.                 const uint32 numOptions = pAnimDB->FindBestMatchingTag(SFragmentQuery(m_fragmentQuery.fragID, fragTagStateQuery), &fragTagStateMatch, &tagSetID);
  2148.  
  2149.                 if ((numOptions > 0))
  2150.                 {
  2151.                         if (m_numOptions == OPTION_IDX_INVALID)
  2152.                         {
  2153.                                 m_numOptions = numOptions;
  2154.                         }
  2155.                         else
  2156.                         {
  2157.                                 m_numOptions = max(m_numOptions, numOptions);
  2158.                         }
  2159.                 }
  2160.  
  2161.                 if (m_numOptions != OPTION_IDX_INVALID)
  2162.                 {
  2163.                         const CTagDefinition* pTagDef = pAnimDB->GetFragmentDefs().GetSubTagDefinition(m_fragmentQuery.fragID);
  2164.                         if (pTagDef && pTagDef->Contains(m_fragmentQuery.tagState.fragmentTags, fragTagStateMatch.fragmentTags))
  2165.                         {
  2166.                                 // TODO: get the charinstance from the scope.
  2167.                                 ICharacterInstance* piCharacterInstance = piActionController->GetEntity().GetCharacter(0);
  2168.                                 const IAnimationSet* piAnimationSet = piCharacterInstance->GetIAnimationSet();
  2169.  
  2170.                                 if (m_fragmentQuery.optionIdx == OPTION_IDX_RANDOM)
  2171.                                 {
  2172.                                         for (uint i = 0; i < m_numOptions; ++i)
  2173.                                         {
  2174.                                                 const CFragment* pFragment = pAnimDB->GetEntry(m_fragmentQuery.fragID, tagSetID, i);
  2175.                                                 if (pFragment)
  2176.                                                 {
  2177.                                                         AddFragment(*pFragment, piAnimationSet);
  2178.                                                 }
  2179.                                         }
  2180.                                 }
  2181.                                 else if (m_fragmentQuery.optionIdx < m_numOptions)
  2182.                                 {
  2183.                                         const CFragment* pFragment = pAnimDB->GetEntry(m_fragmentQuery.fragID, tagSetID, m_fragmentQuery.optionIdx);
  2184.                                         if (pFragment)
  2185.                                         {
  2186.                                                 AddFragment(*pFragment, piAnimationSet);
  2187.                                         }
  2188.                                 }
  2189.                         }
  2190.                 }
  2191.         }
  2192.         void Release()
  2193.         {
  2194.                 m_animsCached.clear();
  2195.                 stl::free_container(m_animsCached);
  2196.         }
  2197.  
  2198.         bool IsLoaded() const
  2199.         {
  2200.                 return(m_animsCached.end() == std::find_if(m_animsCached.begin(), m_animsCached.end(), FPredNotLoaded()));
  2201.         }
  2202.  
  2203.         uint32 GetNumOptions() const    { return m_numOptions; }
  2204.         uint32 GetCurrentOption() const { return m_fragmentQuery.optionIdx; }
  2205.  
  2206. private:
  2207.  
  2208.         struct SCacheAnims
  2209.         {
  2210.                 explicit SCacheAnims(const uint32 crc)
  2211.                         : m_crc(crc)
  2212.                 {
  2213.                         gEnv->pCharacterManager->CAF_AddRef(m_crc);
  2214.                 }
  2215.                 SCacheAnims(const SCacheAnims& rhs)
  2216.                         : m_crc(rhs.m_crc)
  2217.                 {
  2218.                         gEnv->pCharacterManager->CAF_AddRef(m_crc);
  2219.                 }
  2220.                 ~SCacheAnims()
  2221.                 {
  2222.                         gEnv->pCharacterManager->CAF_Release(m_crc);
  2223.                 }
  2224.  
  2225.                 SCacheAnims& operator=(const SCacheAnims& anim)
  2226.                 {
  2227.                         if (m_crc != anim.m_crc)
  2228.                         {
  2229.                                 gEnv->pCharacterManager->CAF_Release(m_crc);
  2230.                                 m_crc = anim.m_crc;
  2231.                                 gEnv->pCharacterManager->CAF_AddRef(m_crc);
  2232.                         }
  2233.                         return *this;
  2234.                 }
  2235.  
  2236.                 bool IsLoaded() const { return gEnv->pCharacterManager->CAF_IsLoaded(m_crc); }
  2237.  
  2238.                 uint32 m_crc;
  2239.         };
  2240.  
  2241.         struct FPredNotLoaded
  2242.         {
  2243.                 bool operator()(const SCacheAnims& anim) const { return !anim.IsLoaded(); }
  2244.         };
  2245.  
  2246.         void AddFragment(const CFragment& fragment, const IAnimationSet* piAnimationSet)
  2247.         {
  2248.                 const DynArray<TAnimClipSequence>& animLayers = fragment.m_animLayers;
  2249.                 for (int i = 0; i < animLayers.size(); ++i)
  2250.                 {
  2251.                         const TAnimClipSequence& sequence = animLayers[i];
  2252.                         for (int j = 0; j < sequence.size(); ++j)
  2253.                         {
  2254.                                 const SAnimClip& animClip = sequence[j];
  2255.                                 const int animID = piAnimationSet->GetAnimIDByCRC(animClip.animation.animRef.crc);
  2256.                                 const uint32 filePathCRC = piAnimationSet->GetFilePathCRCByAnimID(animID);
  2257.  
  2258.                                 const char* pAnimPath = piAnimationSet->GetFilePathByID(animID);
  2259.  
  2260.                                 // CharacterManager needs the filePathCRC
  2261.                                 m_animsCached.push_back(SCacheAnims(filePathCRC));
  2262.                         }
  2263.                 }
  2264.         }
  2265.  
  2266.         SFragmentQuery m_fragmentQuery;
  2267.         uint32         m_numOptions;
  2268.  
  2269.         typedef std::vector<SCacheAnims> TAnimsCached;
  2270.         TAnimsCached m_animsCached;
  2271. };
  2272.  
  2273. #include "ICryMannequinUserParams.h"
  2274.  
  2275. #endif //__I_CRY_MANNEQUIN_H__
  2276.  
downloadICryMannequin.h Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top