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 fbxanimcurvenode.h |
13 | #ifndef _FBXSDK_SCENE_ANIMATION_CURVE_NODE_H_ |
14 | #define _FBXSDK_SCENE_ANIMATION_CURVE_NODE_H_ |
15 | |
16 | #include <fbxsdk/fbxsdk_def.h> |
17 | |
18 | #include <fbxsdk/core/fbxobject.h> |
19 | |
20 | #include <fbxsdk/fbxsdk_nsbegin.h> |
21 | |
22 | //Standard curve node names |
23 | #define FBXSDK_CURVENODE_TRANSFORM "Transform" |
24 | #define FBXSDK_CURVENODE_TRANSLATION "T" |
25 | #define FBXSDK_CURVENODE_ROTATION "R" |
26 | #define FBXSDK_CURVENODE_SCALING "S" |
27 | #define FBXSDK_CURVENODE_COMPONENT_X "X" |
28 | #define FBXSDK_CURVENODE_COMPONENT_Y "Y" |
29 | #define FBXSDK_CURVENODE_COMPONENT_Z "Z" |
30 | #define FBXSDK_CURVENODE_COLOR "Color" |
31 | #define FBXSDK_CURVENODE_COLOR_RED FBXSDK_CURVENODE_COMPONENT_X |
32 | #define FBXSDK_CURVENODE_COLOR_GREEN FBXSDK_CURVENODE_COMPONENT_Y |
33 | #define FBXSDK_CURVENODE_COLOR_BLUE FBXSDK_CURVENODE_COMPONENT_Z |
34 | |
35 | class FbxAnimStack; |
36 | class FbxAnimCurve; |
37 | class FbxMultiMap; |
38 | class KFCurveNode; |
39 | |
40 | /** This class is an composite of animation curves and is called as animation curve node. |
41 | * \nosubgrouping |
42 | * Animation curve node is used as the connection point for animation curves and other animation curve nodes |
43 | * associated to a property. FbxAnimCurveNode can be connected to other FbxAnimCurveNode, |
44 | * in this case, the destination animation curve node may be considered as "composite", \ref IsComposite(). |
45 | * remarks When created, the FbxAnimCurveNode has no valid channels unless it is created using the function CreateTypedCurveNode(). |
46 | * This function will add all the required channels to correctly match the number of values of the property. |
47 | * For instance, when CreateTypedCurveNode(pNode.LclTranslation, pScene) is called, the resulting |
48 | * FbxAnimCurveNode will automatically have 3 channels corresponding to the X,Y and Z components of the LclTranslation property. |
49 | * You can add and remove channels dynamically but can never remove the channels that have been added by the call to CreateTypedCurveNode(). |
50 | * |
51 | * However, the FBX SDK animation system's default implementation is to consider only the first curve connected to |
52 | * the channel. Therefore, if the caller connects multiple animation curves to the same channel, then it becomes |
53 | * the caller's responsibility to handle and manipulate these extra curves in a meaningful manner. |
54 | */ |
55 | class FBXSDK_DLL FbxAnimCurveNode : public FbxObject |
56 | { |
57 | FBXSDK_OBJECT_DECLARE(FbxAnimCurveNode, FbxObject); |
58 | |
59 | public: |
60 | /** |
61 | * \name Utility functions. |
62 | * |
63 | */ |
64 | //@{ |
65 | /** Check if the animation curve node contains any animation key. |
66 | * \param pRecurse \c true to descend to the children if the animation curve node is composite. |
67 | * \return \c true if at least one animation curve that contains one or more animation keys is found, |
68 | * \c false otherwise. |
69 | * \remarks This method only considers the first animation curve connected to each channel. |
70 | * To check multiple animation curves that are connected to the same channel, it is the caller's |
71 | * responsibility to write a new version of this method, and GetCurveCount() will be useful in this case. |
72 | */ |
73 | bool IsAnimated(bool pRecurse=false) const; |
74 | |
75 | /** Find out start and end time of the animation. |
76 | * This function retrieves the including time span for all animation curves of this animation curve node. |
77 | * \param pTimeInterval Reference to receive start time and end time. |
78 | * \return \c true on success, \c false otherwise. |
79 | * \remarks \c false is also returned if this animation curve node has no animation. |
80 | * \remarks This method only considers the first animation curve connected to each channel. |
81 | * To find time interval of multiple animation curves that are connected to the same channel, it is the caller's |
82 | * responsibility to write a new version of this method, and GetCurveCount() will be useful in this case. |
83 | */ |
84 | bool GetAnimationInterval(FbxTimeSpan& pTimeInterval) const; |
85 | |
86 | /** Test this object to see if it is a composite FbxAnimCurveNode or a "leaf". |
87 | * A composite FbxAnimCurveNode is a FbxAnimCurveNode whose all source connections are FbxAnimCurveNode |
88 | * and its property channels is totally empty. It is just a container to take other FbxAnimCurveNode. |
89 | * \return \c true if this object is a composite, \c false otherwise. |
90 | */ |
91 | bool IsComposite() const; |
92 | |
93 | /** Recursively look for the FbxAnimCurveNode matching the passed named argument. |
94 | * \param pName Name of the FbxAnimCurveNode we are looking for. |
95 | * \return The found anim curve node or NULL. |
96 | * \remarks If pName is an empty string, this function automatically return NULL. |
97 | */ |
98 | FbxAnimCurveNode* Find(const char* pName); |
99 | |
100 | /** Create a FbxAnimCurveNode compatible with the specified property data type. |
101 | * \param pProperty The property that needs a FbxAnimCurveNode. |
102 | * \param pScene The scene the created FbxAnimCurveNode will belong to. |
103 | * \return The pointer to the newly created FbxAnimCurveNode. Returns NULL if an error occurred. |
104 | * \remarks This function does not connect the newly created FbxAnimCurveNode to the property. |
105 | * \remarks This function detects FbxDouble3, FbxDouble4 and FbxDouble4x4 properties DataTypes and |
106 | * automatically adds the required channels properties. Any other DataType is not |
107 | * specifically processed and the channels properties are left empty and need to be filled |
108 | * using the AddChannel() function. |
109 | */ |
110 | static FbxAnimCurveNode* CreateTypedCurveNode(FbxProperty& pProperty, FbxScene* pScene); |
111 | |
112 | /** Get the total number of property channels defined in this animation curve node. |
113 | * For composite animation curve nodes, since they do not contain any channels, this function will always return 0. |
114 | * \return The number of property channels. |
115 | */ |
116 | unsigned int GetChannelsCount() const; |
117 | |
118 | /** Get the index of the named channel. |
119 | * \param pChannelName Name of the channel for which we want the index. |
120 | * \return the index of the named channel or -1 if no channel with this name is found. |
121 | */ |
122 | int GetChannelIndex(const char* pChannelName) const; |
123 | |
124 | /** Get the name of the channel. |
125 | * \param pChannelId Index of the channel for which we want the name. |
126 | * \return the name of the indexed channel or "" if the index is invalid. |
127 | */ |
128 | FbxString GetChannelName(int pChannelId) const; |
129 | |
130 | /** Empties the property channels of this animation curve node. |
131 | * \remarks This function will remove all the channels added with the AddChannel() method |
132 | * regardless of their use and/or connections. |
133 | * But it can not remove the channels that are added by the call to CreateTypedCurveNode(). |
134 | */ |
135 | void ResetChannels(); |
136 | |
137 | /** Adds the specified channel property. |
138 | * \param pChnlName Channel name. |
139 | * \param pValue Default value of the channel. |
140 | * \return \c true if successful, \c false otherwise. |
141 | * \remarks It is an error to try to add a channel that already exists. |
142 | */ |
143 | template <class T> bool AddChannel(const char* pChnlName, T const &pValue) |
144 | { |
145 | if (!pChnlName || strlen(pChnlName)==0) return false; |
146 | FbxProperty c = GetChannel(pChnlName); |
147 | if (c.IsValid()) |
148 | { |
149 | return false; |
150 | } |
151 | |
152 | mChannels.BeginCreateOrFindProperty(); |
153 | FbxDataType dt = FbxGetDataTypeFromEnum(FbxTypeOf(pValue)); |
154 | c = FbxProperty::Create(mChannels, dt, pChnlName); |
155 | c.Set(pValue); |
156 | mChannels.EndCreateOrFindProperty(); |
157 | return true; |
158 | } |
159 | |
160 | /** Set the default value of the channel. |
161 | * \param pChnlName Channel name. |
162 | * \param pValue New default value of this channel. |
163 | */ |
164 | template <class T> void SetChannelValue(const char* pChnlName, T pValue) |
165 | { |
166 | FbxProperty c = GetChannel(pChnlName); |
167 | if( c.IsValid() ) c.Set(pValue); |
168 | } |
169 | |
170 | /** Set the default value of the channel. |
171 | * \param pChnlId Channel index. |
172 | * \param pValue New default value of this channel. |
173 | */ |
174 | template <class T> void SetChannelValue(unsigned int pChnlId, T pValue) |
175 | { |
176 | FbxProperty c = GetChannel(pChnlId); |
177 | if( c.IsValid() ) c.Set(pValue); |
178 | } |
179 | |
180 | /** Get the default value of the channel. |
181 | * \param pChnlName Channel name. |
182 | * \param pInitVal Value returned if the specified channel is invalid. |
183 | * \return The default value of this channel. |
184 | */ |
185 | template <class T> T GetChannelValue(const char* pChnlName, T pInitVal) |
186 | { |
187 | T v = pInitVal; |
188 | FbxProperty c = GetChannel(pChnlName); |
189 | if( c.IsValid() ) v = c.Get<T>(); |
190 | return v; |
191 | } |
192 | |
193 | /** Get the default value of the channel. |
194 | * \param pChnlId Channel index. |
195 | * \param pInitVal Value returned if the specified channel is invalid. |
196 | * \return The default value of this channel. |
197 | */ |
198 | template <class T> T GetChannelValue(unsigned int pChnlId, T pInitVal) |
199 | { |
200 | T v = pInitVal; |
201 | FbxProperty c = GetChannel(pChnlId); |
202 | if( c.IsValid() ) v = c.Get<T>(); |
203 | return v; |
204 | } |
205 | //@} |
206 | |
207 | /** |
208 | * \name FbxAnimCurve management. |
209 | * |
210 | */ |
211 | //@{ |
212 | /** Disconnect the animation curve from the channel. |
213 | * \param pCurve The curve to disconnect from the channel. |
214 | * \param pChnlId The channel index. |
215 | * \return \c true if the disconnection was made, \c false if an error occurred. |
216 | */ |
217 | bool DisconnectFromChannel(FbxAnimCurve* pCurve, unsigned int pChnlId); |
218 | |
219 | /** Connects the given animation curve to the specified channel. |
220 | * \param pCurve The curve to connect to the channel. |
221 | * \param pChnl The name of the channel the curve is to be connected to. |
222 | * \param pInFront When \c true, all the current connections are moved after this one, |
223 | * making this one the first. By default, the connection is the last one. |
224 | * \return \c true if the connection was made, \c false if an error occurred. |
225 | */ |
226 | bool ConnectToChannel(FbxAnimCurve* pCurve, const char* pChnl, bool pInFront = false); |
227 | |
228 | /** Connects the given animation curve to the specified channel. |
229 | * \param pCurve The curve to connect to the channel. |
230 | * \param pChnlId Index of the channel the curve is to be connected to. |
231 | * \param pInFront When \c true, all the current connections are moved after this one. |
232 | * making this one the first. By default, the connection is the last one. |
233 | * \return \c true if the connection was made, \c false if an error occurred. |
234 | * \remarks The index is 0 based. |
235 | */ |
236 | bool ConnectToChannel(FbxAnimCurve* pCurve, unsigned int pChnlId, bool pInFront = false); |
237 | |
238 | /** Creates a new curve and connects it to the specified channel of the animation curve node named pCurveNodeName. |
239 | * If this animation curve node is composite, this function will try to search all children animation curve nodes |
240 | * recursively for the one named pCurveNodeName. |
241 | * \param pCurveNodeName Name of the FbxAnimCurveNode we are looking for. |
242 | * \param pChannel Channel identifier. |
243 | * \return Pointer to the FbxAnimCurve or NULL if an error occurred. |
244 | * \remarks pCurveNodeName cannot be empty. |
245 | * \remarks If the pChannel identifier is left NULL, the first valid channel will be used to create curve. |
246 | */ |
247 | FbxAnimCurve* CreateCurve(const char* pCurveNodeName, const char* pChannel); |
248 | |
249 | /** Creates a new curve and connects it to the specified channel of the animation curve node named pCurveNodeName. |
250 | * If this animation curve node is composite, this function will try to search all children animation curve nodes |
251 | * recursively for the one named pCurveNodeName. |
252 | * \param pCurveNodeName Name of the FbxAnimCurveNode we are looking for. |
253 | * \param pChannelId Channel index. |
254 | * \return Pointer to the FbxAnimCurve or NULL if an error occurred. |
255 | * \remarks pCurveNodeName cannot be empty. |
256 | * If the pChannelId is not assigned, the first valid channel will be used to create curve. |
257 | */ |
258 | FbxAnimCurve* CreateCurve(const char* pCurveNodeName, unsigned int pChannelId = 0); |
259 | |
260 | /** Get the number of FbxAnimCurve connected to the specified channel. |
261 | * If this animation curve node is composite, this function will try to search all children animation curve nodes |
262 | * recursively for the one named pCurveNodeName. |
263 | * \param pChannelId Channel index. |
264 | * \param pCurveNodeName Name of the FbxAnimCurveNode we are looking for. |
265 | * \return The number of animation curves on the specified channel or 0 if an error occurred. |
266 | * \remarks This method fails if the FbxAnimCurveNode with name pCurveNodeName does not exist and return 0. |
267 | * If the specified channel cannot be found on the FbxAnimCurveNode with name pCurveNodeName, return 0. |
268 | * \remarks If this animation curve node is composite, this function will try to search all |
269 | * children animation curve nodes recursively for the one named pCurveNodeName. |
270 | * If the pCurveNodeName is left NULL, then only look for the curves on this animation curve node |
271 | * even if it is composite. |
272 | */ |
273 | int GetCurveCount(unsigned int pChannelId, const char* pCurveNodeName = NULL); |
274 | |
275 | /** Get the FbxAnimCurve of the specified channel. |
276 | * If this animation curve node is composite, this function will try to search all children animation curve nodes |
277 | * recursively for the one named pCurveNodeName. |
278 | * \param pChannelId Channel index. |
279 | * \param pId The index of the desired anim curve (in case there is more than one). |
280 | * \param pCurveNodeName Name of the FbxAnimCurveNode we are looking for (if this object is a composite). |
281 | * \return Pointer to the FbxAnimCurve that matches the criteria. |
282 | * \remarks This method fails if the FbxAnimCurveNode with name pCurveNodeName does not exist and return NULL. |
283 | * If the specified channel cannot be found in the FbxAnimCurveNode with name pCurveNodeName, return NULL. |
284 | * \remarks If the pCurveNodeName is left NULL, then only search in the curves on this animation curve node |
285 | * even if it is composite. |
286 | */ |
287 | FbxAnimCurve* GetCurve(unsigned int pChannelId, unsigned int pId = 0, const char* pCurveNodeName = NULL); |
288 | |
289 | //@} |
290 | |
291 | /***************************************************************************************************************************** |
292 | ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! ** |
293 | *****************************************************************************************************************************/ |
294 | #ifndef DOXYGEN_SHOULD_SKIP_THIS |
295 | virtual FbxObject& Copy(const FbxObject& pObject); |
296 | |
297 | void Evaluate(double* pData, FbxTime pTime); |
298 | |
299 | KFCurveNode* GetKFCurveNode(bool pNoCreate=false); |
300 | void ReleaseKFCurveNode(); |
301 | void SyncChannelsWithKFCurve(); |
302 | |
303 | inline bool UseQuaternionInterpolation() {return mQuaternionInterpolation != 0;}; |
304 | bool SetQuaternionInterpolation(unsigned short pVal); |
305 | unsigned short GetQuaternionInterpolation() { return mQuaternionInterpolation; }; |
306 | void SetKFCurveNodeLayerType(FbxProperty& pProp); |
307 | |
308 | static const char* CurveNodeNameFrom(const char* pName); |
309 | |
310 | protected: |
311 | virtual void Construct(const FbxObject* pFrom); |
312 | virtual void Destruct(bool pRecursive); |
313 | virtual void ConstructProperties(bool pForceSet); |
314 | virtual bool ConnectNotify(const FbxConnectEvent& pEvent); |
315 | |
316 | FbxAnimCurveNode* Find(FbxAnimCurveNode* pRoot, const FbxString& pName); |
317 | |
318 | private: |
319 | FbxProperty GetChannel(const char* pChnl); |
320 | FbxProperty GetChannel(unsigned int pChnlId); |
321 | |
322 | friend void CollectAnimFromCurveNode(void **lSrc, void *fcn, unsigned int nbCrvs, FbxAnimCurveNode *cn, FbxMultiMap* pNickToAnimCurveTimeWarpsSet, FbxMultiMap& pNickToKFCurveNodeWarpSet); |
323 | |
324 | unsigned char mNonRemovableChannels; |
325 | FbxProperty mChannels; |
326 | FbxProperty* mCurrentlyProcessed; |
327 | KFCurveNode* mFCurveNode; |
328 | bool* mOwnedKFCurve; |
329 | int mKFCurveNodeLayerType; |
330 | unsigned short mQuaternionInterpolation; |
331 | int* mDirectIndexes; |
332 | int mDirectIndexesSize; |
333 | |
334 | FbxAnimCurve* GetCurve(unsigned int pChannelId, unsigned int pId, FbxAnimCurveNode* pCurveNode); |
335 | bool ConnectToChannel(FbxProperty& p, FbxAnimCurve* pCurve, bool pInFront); |
336 | void ResetKFCurveNode(); |
337 | void SyncKFCurveValue(FbxAnimCurve* pCurve, double pVal); |
338 | void ReleaseOwnershipOfKFCurve(int pIndex); |
339 | |
340 | template <class T> FbxAnimCurve* CreateCurveGeneral(const char* pCurveNodeName, T pChannel); |
341 | #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/ |
342 | }; |
343 | |
344 | FBXSDK_DLL void GetAllAnimCurves(FbxAnimStack* pAnimStack, FbxArray<FbxAnimCurve*>& pCurves); |
345 | FBXSDK_DLL void GetAllAnimCurves(FbxObject* pObj, FbxAnimStack* pAnimStack, FbxArray<FbxAnimCurve*>& pCurves); |
346 | |
347 | #include <fbxsdk/fbxsdk_nsend.h> |
348 | |
349 | #endif // FBXFILESDK_KFBXPLUGINS_KFBXANIMCURVENODE_H |
350 | |
351 | |