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
35class FbxAnimStack;
36class FbxAnimCurve;
37class FbxMultiMap;
38class 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 */
55class FBXSDK_DLL FbxAnimCurveNode : public FbxObject
56{
57 FBXSDK_OBJECT_DECLARE(FbxAnimCurveNode, FbxObject);
58
59public:
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
310protected:
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
318private:
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
344FBXSDK_DLL void GetAllAnimCurves(FbxAnimStack* pAnimStack, FbxArray<FbxAnimCurve*>& pCurves);
345FBXSDK_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