1/****************************************************************************************
2
3 Copyright (C) 2015 Autodesk, Inc.
4 All rights reserved.
5
6 Use of this software is subject to the terms of the Autodesk license agreement
7 provided at the time of installation or download, or which otherwise accompanies
8 this software in either electronic or hard copy form.
9
10****************************************************************************************/
11
12//! \file fbxanimevaluator.h
13#ifndef _FBXSDK_SCENE_ANIMATION_EVALUATOR_H_
14#define _FBXSDK_SCENE_ANIMATION_EVALUATOR_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/core/fbxobject.h>
19#include <fbxsdk/scene/animation/fbxanimevalstate.h>
20#include <fbxsdk/scene/animation/fbxanimstack.h>
21
22#include <fbxsdk/fbxsdk_nsbegin.h>
23
24/** The principal interface for animation evaluators. The animation evaluator is used to compute node transforms
25* and property values at specific times during an animation. Evaluators simplify the process of computing transform
26* matrices by taking into account all of the parameters, such as pre- and post-rotations.
27* This class is abstract so that SDK users can implement their own evaluator if needed. The default evaluator used
28* by the FBX SDK is a FbxAnimEvalClassic. The default evaluator can be queried with the function
29* FbxScene::GetEvaluator(), and can be changed using FbxScene::SetEvaluator().
30*
31* When working with scene nodes, the evaluator will always return an affine transform matrix that contains the
32* translation, rotation and scale of that node.
33*
34* When working with object properties, the evaluator will always return a structure that can contain as many components
35* as the property can have. For example, an RGB color property would return a structure containing 3 channels. The
36* class FbxAnimCurveNode is used as a data container to store those values, because it can handle as many channels as
37* needed, even if the property is not a real curve node .
38*
39* Below is a typical usage of the evaluator class to retrieve the global transform matrix of each node in a scene:
40* \code
41* //Here we assume the user already imported a scene...
42* for( int i = 0, c = MyScene->GetMemberCount(FbxNode::ClassId); i < c; ++i )
43* {
44* FbxNode* CurrentNode = MyScene->GetMember(FbxNode::ClassId, i);
45* FbxAMatrix& NodeGlobalTransform = MyScene->GetEvaluator()->GetNodeGlobalTransform(CurrentNode);
46* }
47*
48* //There is an equivalent call to retrieve a node's global transform, which is exactly the same as calling Scene->GetEvaluator() :
49* FbxAMatrix& NodeGlobalTransform = CurrentNode->EvaluateGlobalTransform();
50* \endcode
51*
52* Another typical usage of the evaluator class, but this time to retrieve the value of an animated color property on a material:
53* \code
54* //Assuming the user imported a scene with objects and materials...
55* FbxColor Color = MyMaterial->GetDiffuseColor()->EvaluateValue();
56* \endcode
57*
58* \note Note that all the methods to retrieve global/local matrices as well as property values returns references.
59* This is important for performance purposes, to prevent an extra memory copy.
60* \see FbxScene, FbxAnimEvalClassic, FbxAnimCurveNode */
61class FBXSDK_DLL FbxAnimEvaluator : public FbxObject
62{
63 FBXSDK_ABSTRACT_OBJECT_DECLARE(FbxAnimEvaluator, FbxObject);
64
65public:
66 /** Returns a node's global transformation matrix at the specified time. The node's translation, rotation and scaling limits are taken into consideration.
67 * \param pNode The node to evaluate.
68 * \param pTime The time used for evaluate. If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
69 * \param pPivotSet The pivot set to take into account
70 * \param pApplyTarget Applies the necessary transform to align into the target node
71 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
72 * \return The resulting global transform of the specified node at the specified time. */
73 FbxAMatrix& GetNodeGlobalTransform(FbxNode* pNode, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
74
75 /** Returns a node's local transformation matrix at the specified time. The node's translation, rotation and scaling limits are taken into consideration.
76 * \param pNode The node to evaluate.
77 * \param pTime The time used for evaluate. If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
78 * \param pPivotSet The pivot set to take into account
79 * \param pApplyTarget Applies the necessary transform to align into the target node
80 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
81 * \return The resulting local transform of the specified node for the specified time.
82 * \remarks The local transform matrix is calculated in this way: ParentGlobal.Inverse * Global, all transforms such as pre/post rotation are taken into consideration.
83 * This will return a different value than LclTranslation, LclRotation and LclScaling at the specified time. To evaluate these properties separately
84 * without taking pre/post rotation, pivots and offsets into consideration, please use GetNodeLocalTranslation(), GetNodeLocalRotation() and GetNodeLocalScaling(). */
85 FbxAMatrix& GetNodeLocalTransform(FbxNode* pNode, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
86
87 /** Returns the value of a node's LclTranslation property at the specified time.
88 * No pivot, offsets, or any other transform is taken into consideration. The translation limit is applied.
89 * \param pNode The transform node to evaluate.
90 * \param pTime The time used for evaluate. If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
91 * \param pPivotSet The pivot set to take into account
92 * \param pApplyTarget Applies the necessary transform to align into the target node
93 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
94 * \return The resulting value of LclTranslation property of the specified node at the specified time. */
95 FbxVector4& GetNodeLocalTranslation(FbxNode* pNode, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
96
97 /** Returns the value of a node's LclRotation property at the specified time.
98 * No pre/post rotation, rotation pivot, rotation offset or any other transform is taken into consideration. The rotation limit is applied.
99 * \param pNode The transform node to evaluate.
100 * \param pTime The time used for evaluate. If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
101 * \param pPivotSet The pivot set to take into account
102 * \param pApplyTarget Applies the necessary transform to align into the target node
103 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
104 * \return The resulting value of LclRotation property of the specified node at the specified time. */
105 FbxVector4& GetNodeLocalRotation(FbxNode* pNode, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
106
107 /** Returns the value of a node's LclScaling property at the specified time.
108 * No scaling pivot, scaling offset or any other transform is taken into consideration. The scaling limit is applied.
109 * \param pNode The transform node to evaluate.
110 * \param pTime The time used for evaluate. If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
111 * \param pPivotSet The pivot set to take into account
112 * \param pApplyTarget Applies the necessary transform to align into the target node
113 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
114 * \return The resulting value of LclScaling property of the specified node at the specified time. */
115 FbxVector4& GetNodeLocalScaling(FbxNode* pNode, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
116
117 /** Get a property's value at the specified time using the template type provided.
118 * \param pProperty The property to evaluate.
119 * \param pTime The time used for evaluate.
120 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
121 * \return The property value at the specified time converted to the template type provided, if possible.
122 * \remark If the property type versus the template cannot be converted, the result is unknown. */
123#if defined(__GNUC__) && (__GNUC__ < 4)
124 template <class T> inline T GetPropertyValue(FbxProperty& pProperty, const FbxTime& pTime, bool pForceEval=false){ FbxPropertyEvalState* s = GetPropertyEvalState(pProperty, pTime, pForceEval); return s->Get<T>(); }
125#else
126 template <class T> inline T GetPropertyValue(FbxProperty& pProperty, const FbxTime& pTime, bool pForceEval=false){ return GetPropertyEvalState(pProperty, pTime, pForceEval)->Get<T>(); }
127#endif
128
129 /** Get a property's value at the specified time.
130 * \param pProperty The property to evaluate.
131 * \param pTime The time used for evaluate.
132 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date.
133 * \return The property value at the specified time. Use FbxPropertyValue::Get() to retrieve the value into a pointer location of your choice. */
134 FbxPropertyValue& GetPropertyValue(FbxProperty& pProperty, const FbxTime& pTime, bool pForceEval=false);
135
136 /** Get a property curve node from the evaluation state for quick access.
137 * \param pProperty The property to search for its animation curve node.
138 * \param pAnimLayer The animation layer on which the animation curve node must be searched.
139 * \remark This function uses a map to store animation curve node search results. If animation curve nodes are replaced, the evaluation state must be reset. */
140 FbxAnimCurveNode* GetPropertyCurveNode(FbxProperty& pProperty, FbxAnimLayer* pAnimLayer);
141
142 /** Validate if the given time value is within animation stack time span range.
143 * \param pTime The time value to validate.
144 * \return The new validated time, clamped by the animation stack time span range.
145 * \remarks If no animation stack are found, time zero is returned. This function is not used by the evaluator itself. */
146 FbxTime ValidateTime(const FbxTime& pTime);
147
148 /** Completely reset the evaluation state cache by deleting all entries. This reset automatically happens when changing the current context. */
149 void Reset();
150
151 /** Clears the specified node evaluation state cache, so the next time the evaluation is called for this node it get refreshed.
152 * \param pNode The node that needs to be re-evaluated in next evaluation. */
153 void Flush(FbxNode* pNode);
154
155 /** Clears the specified property evaluation state cache, so the next time the evaluation is called for this property it get refreshed.
156 * \param pProperty The property that needs to be re-evaluated in next evaluation. */
157 void Flush(FbxProperty& pProperty);
158
159 /** Compute node local TRS from global transform. Doesn't change cached state for current time.
160 * \param[out] pRetLT Computed local translation.
161 * \param[out] pRetLR Computed local rotation.
162 * \param[out] pRetLS Computed local scaling.
163 * \param pNode The transform node to evaluate.
164 * \param pGX Global transformation state.
165 * \param pTime The time used for evaluate.If FBXSDK_TIME_INFINITE is used, this returns the default value, without animation curves evaluation.
166 * \param pPivotSet The pivot set to take into account.
167 * \param pApplyTarget Applies the necessary transform to align into the target node.
168 * \param pForceEval Force the evaluator to refresh the evaluation state cache even if its already up-to-date. */
169 void ComputeLocalTRSFromGlobal(FbxVector4& pRetLT, FbxVector4& pRetLR, FbxVector4& pRetLS, FbxNode* pNode, FbxAMatrix& pGX, const FbxTime& pTime=FBXSDK_TIME_INFINITE, FbxNode::EPivotSet pPivotSet=FbxNode::eSourcePivot, bool pApplyTarget=false, bool pForceEval=false);
170
171/*****************************************************************************************************************************
172** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
173*****************************************************************************************************************************/
174#ifndef DOXYGEN_SHOULD_SKIP_THIS
175protected:
176 virtual void Construct(const FbxObject* pFrom);
177 virtual void Destruct(bool pRecursive);
178
179 virtual void EvaluateNodeTransform(FbxNodeEvalState* pResult, FbxNode* pNode, const FbxTime& pTime, FbxNode::EPivotSet pPivotSet, bool pApplyTarget) = 0;
180 virtual void EvaluatePropertyValue(FbxPropertyEvalState* pResult, FbxProperty& pProperty, const FbxTime& pTime) = 0;
181
182 FbxAnimEvalState* GetDefaultEvalState();
183 FbxAnimEvalState* GetEvalState(const FbxTime& pTime);
184 FbxNodeEvalState* GetNodeEvalState(FbxNode* pNode, const FbxTime& pTime, FbxNode::EPivotSet pPivotSet, bool pApplyTarget, bool pForceEval);
185 FbxPropertyEvalState* GetPropertyEvalState(FbxProperty& pProperty, const FbxTime& pTime, bool pForceEval);
186
187private:
188 FbxAnimEvalState* mEvalState;
189#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
190};
191
192#include <fbxsdk/fbxsdk_nsend.h>
193
194#endif /* _FBXSDK_SCENE_ANIMATION_EVALUATOR_H_ */
195