kfcurve.h

Go to the documentation of this file.
00001 
00004 #ifndef FBXFILESDK_COMPONENTS_KFCURVE_KFCURVE_H
00005 #define FBXFILESDK_COMPONENTS_KFCURVE_KFCURVE_H
00006 
00007 /**************************************************************************************
00008 
00009  Copyright (C) 2001 - 2010 Autodesk, Inc. and/or its licensors.
00010  All Rights Reserved.
00011 
00012  The coded instructions, statements, computer programs, and/or related material 
00013  (collectively the "Data") in these files contain unpublished information 
00014  proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
00015  Canada and United States of America federal copyright law and by international 
00016  treaties. 
00017  
00018  The Data may not be disclosed or distributed to third parties, in whole or in
00019  part, without the prior written consent of Autodesk, Inc. ("Autodesk").
00020 
00021  THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
00022  ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
00023  WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
00024  BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
00025  NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
00026  WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
00027  OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
00028  
00029  IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
00030  OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
00031  OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
00032  SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
00033  OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
00034  HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
00035  FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
00036  ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
00037  WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
00038  OR DAMAGE. 
00039 
00040 **************************************************************************************/
00041 #include <fbxfilesdk/fbxfilesdk_def.h>
00042 
00043 #include <fbxfilesdk/components/kbaselib/klib/karrayul.h>
00044 #include <fbxfilesdk/components/kbaselib/klib/ktime.h>
00045 #include <fbxfilesdk/components/kbaselib/klib/kdebug.h>
00046 #include <fbxfilesdk/components/kbaselib/object/e/keventbase.h>
00047 
00048 #undef  KFBX_FCURVE_INLINE
00049 #define KFBX_FCURVE_INLINE inline
00050 
00051 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00052 
00053 KFBX_FORWARD(KFbx);
00054 KFBX_FORWARD(KDataType);
00055 KFBX_FORWARD(KgeQuaternion);
00056 KFBX_FORWARD(KgeRMatrix);
00057 
00058 #define KFCURVE_FLOAT
00059 #ifdef KFCURVE_FLOAT
00060     typedef float kFCurveDouble;
00061 #else
00062     typedef double kFCurveDouble;
00063 #endif
00064 
00065 
00066 KFBX_FORWARD(KFCurve);
00067 
00068 #define IKFCurveID 43763635
00069 
00070 typedef HKFCurve HIKFCurve;
00071 typedef class KFBX_DLL KArrayTemplate< KFCurve * > KArrayKFCurve;
00072 
00073 // Recording memory functions declaration
00074 KFBX_DLL kULong GetRecordingMemory();
00075 KFBX_DLL void WatchFree(void* pPtr, kULong pSize);
00076 KFBX_DLL void* WatchMalloc(kULong pSize);
00077 
00079 enum
00080 {
00082     KFCURVE_INTERPOLATION_CONSTANT    = 0x00000002, 
00084     KFCURVE_INTERPOLATION_LINEAR      = 0x00000004,     
00086     KFCURVE_INTERPOLATION_CUBIC       = 0x00000008,     
00088     KFCURVE_INTERPOLATION_ALL         = KFCURVE_INTERPOLATION_CONSTANT|KFCURVE_INTERPOLATION_LINEAR|KFCURVE_INTERPOLATION_CUBIC,
00090     KFCURVE_INTERPOLATION_COUNT       = 3
00091 };                                                
00092 
00094 enum
00095 {
00097     KFCURVE_CONSTANT_STANDARD         = 0x00000000,
00099     KFCURVE_CONSTANT_NEXT             = 0x00000100,
00101     KFCURVE_CONSTANT_ALL              = KFCURVE_CONSTANT_STANDARD | KFCURVE_CONSTANT_NEXT,
00103     KFCURVE_CONSTANT_COUNT            = 2
00104 };
00105 
00107 enum
00108 {
00110     KFCURVE_TANGEANT_AUTO             = 0x00000100,     
00112     KFCURVE_TANGEANT_TCB              = 0x00000200, 
00114     KFCURVE_TANGEANT_USER             = 0x00000400,     
00116     KFCURVE_GENERIC_BREAK             = 0x00000800,     
00118     KFCURVE_GENERIC_CLAMP             = 0x00001000, 
00120     KFCURVE_GENERIC_TIME_INDEPENDENT  = 0x00002000,
00122     KFCURVE_GENERIC_CLAMP_PROGRESSIVE = 0x00004000|KFCURVE_GENERIC_TIME_INDEPENDENT, // this is the AUTOKEY tangent mode and can only work if time-independent
00124     KFCURVE_TANGEANT_BREAK            = KFCURVE_TANGEANT_USER|KFCURVE_GENERIC_BREAK,
00126     KFCURVE_TANGEANT_AUTO_BREAK       = KFCURVE_TANGEANT_AUTO|KFCURVE_GENERIC_BREAK,
00128     KFCURVE_TANGEANT_ALL              = KFCURVE_TANGEANT_AUTO|KFCURVE_TANGEANT_TCB|KFCURVE_TANGEANT_USER|KFCURVE_GENERIC_BREAK|KFCURVE_GENERIC_CLAMP|KFCURVE_GENERIC_CLAMP_PROGRESSIVE|KFCURVE_GENERIC_TIME_INDEPENDENT,
00130     KFCURVE_TANGEANT_TYPE_MASK        = KFCURVE_TANGEANT_AUTO|KFCURVE_TANGEANT_TCB|KFCURVE_TANGEANT_USER|KFCURVE_TANGEANT_BREAK,
00132     KFCURVE_TANGEANT_OVERRIDES_MASK   = KFCURVE_GENERIC_CLAMP|KFCURVE_GENERIC_CLAMP_PROGRESSIVE|KFCURVE_GENERIC_TIME_INDEPENDENT
00133 };
00134 
00136 enum 
00137 {
00139     KFCURVE_SELECT_POINT              = 0x00010000, 
00141     KFCURVE_SELECT_LEFT               = 0x00020000, 
00143     KFCURVE_SELECT_RIGHT              = 0x00040000, 
00145     KFCURVE_SELECT_ALL                = KFCURVE_SELECT_POINT|KFCURVE_SELECT_LEFT|KFCURVE_SELECT_RIGHT
00146 };
00147 
00149 enum
00150 {
00152     KFCURVE_MARKED_FOR_MANIP          = 0x00080000,
00154     KFCURVE_MARKED_ALL                = KFCURVE_MARKED_FOR_MANIP
00155 };
00156 
00159 enum 
00160 {
00162     KFCURVE_TANGEANT_SHOW_NONE        = 0x00000000, 
00164     KFCURVE_TANGEANT_SHOW_LEFT        = 0x00100000, 
00166     KFCURVE_TANGEANT_SHOW_RIGHT       = 0x00200000, 
00168     KFCURVE_TANGEANT_SHOW_BOTH        = KFCURVE_TANGEANT_SHOW_LEFT|KFCURVE_TANGEANT_SHOW_RIGHT
00169 };
00170 
00173 enum
00174 {
00176     KFCURVE_CONTINUITY                = 0x00000000,
00178     KFCURVE_CONTINUITY_FLAT           = 0x00100000,
00180     KFCURVE_CONTINUITY_BREAK          = 0x00200000,
00182     KFCURVE_CONTINUITY_INSERT         = 0x00400000  
00183 };
00184 
00185 
00187 enum 
00188 {
00190     KFCURVE_WEIGHTED_NONE             = 0x00000000, 
00192     KFCURVE_WEIGHTED_RIGHT            = 0x01000000, 
00194     KFCURVE_WEIGHTED_NEXT_LEFT        = 0x02000000, 
00196     KFCURVE_WEIGHTED_ALL              = KFCURVE_WEIGHTED_RIGHT|KFCURVE_WEIGHTED_NEXT_LEFT
00197 };
00198 
00200 enum
00201 {
00203     KFCURVE_VELOCITY_NONE             = 0x00000000,
00205     KFCURVE_VELOCITY_RIGHT            = 0x10000000,
00207     KFCURVE_VELOCITY_NEXT_LEFT        = 0x20000000,
00209     KFCURVE_VELOCITY_ALL              = KFCURVE_VELOCITY_RIGHT | KFCURVE_VELOCITY_NEXT_LEFT
00210 };
00211 
00212 
00213 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00214 
00215 #define KFCURVE_WEIGHT_DIVIDER       9999       // precise enough and can be divided by 3 without error
00216 #define KFCURVE_DEFAULT_WEIGHT       ((kFCurveDouble)(1.0/3.0))
00217 #define KFCURVE_MIN_WEIGHT           ((kFCurveDouble)(1.0/KFCURVE_WEIGHT_DIVIDER))
00218 #define KFCURVE_MAX_WEIGHT           ((kFCurveDouble)0.99)
00219 #define KFCURVE_DEFAULT_VELOCITY     0.0 
00220 
00221 #endif // DOXYGEN_SHOULD_SKIP_THIS
00222 
00223 
00224 
00226 enum EKFCurveDataIndex
00227 {
00230     KFCURVEKEY_RIGHT_SLOPE          = 0, 
00232     KFCURVEKEY_NEXT_LEFT_SLOPE      = 1, 
00233 
00236     KFCURVEKEY_WEIGHTS              = 2, 
00238     KFCURVEKEY_RIGHT_WEIGHT         = 2, 
00240     KFCURVEKEY_NEXT_LEFT_WEIGHT     = 3, 
00241 
00244     KFCURVEKEY_VELOCITY             = 4,
00246     KFCURVEKEY_RIGHT_VELOCITY       = 4,
00248     KFCURVEKEY_NEXT_LEFT_VELOCITY   = 5, 
00249 
00252     KFCURVEKEY_TCB_TENSION          = 0, 
00254     KFCURVEKEY_TCB_CONTINUITY       = 1, 
00256     KFCURVEKEY_TCB_BIAS             = 2,
00257 
00259     KFCURVEKEY_RIGHT_AUTO           = 0,
00261     KFCURVEKEY_NEXT_LEFT_AUTO       = 1
00262 };
00263 
00265 enum 
00266 {
00268     KFCURVE_EXTRAPOLATION_CONST             = 1, 
00270     KFCURVE_EXTRAPOLATION_REPETITION        = 2, 
00272     KFCURVE_EXTRAPOLATION_MIRROR_REPETITION = 3, 
00274     KFCURVE_EXTRAPOLATION_KEEP_SLOPE        = 4
00275 };
00276 
00277 enum 
00278 {
00279     KFCURVE_BEZIER  = 0, 
00280     KFCURVE_SAMPLE  = 1, 
00281     KFCURVE_ISO     = 2
00282 };
00283 
00284 typedef kUInt kFCurveInterpolation;
00285 typedef kUInt kFCurveConstantMode;
00286 typedef kUInt kFCurveTangeantMode;
00287 typedef kUInt kFCurveTangeantWeightMode;
00288 typedef kUInt kFCurveTangeantVelocityMode;
00289 typedef kUInt kFCurveExtrapolationMode;
00290 typedef kUInt kFCurveTangeantVisibility;
00291 typedef int kFCurveIndex;
00292 
00312 enum 
00313 {
00314     KFCURVEEVENT_NONE       =0, // default event value
00315     KFCURVEEVENT_CANDIDATE  =1 << 0, // curve value (not candidate) changed
00316     KFCURVEEVENT_UNUSED1    =1 << 1,
00317     KFCURVEEVENT_UNUSED2    =1 << 2,
00318     KFCURVEEVENT_UNUSED3    =1 << 3,
00319     KFCURVEEVENT_KEY        =1 << 4, // key changed (add, removed, edited); see bits 11-15 for precisions
00320     KFCURVEEVENT_DEPRECATED5 =1 << 5,
00321     KFCURVEEVENT_UNUSED6    =1 << 6,
00322     KFCURVEEVENT_UNUSED7    =1 << 7,
00323     KFCURVEEVENT_SELECTION  =1 << 8, // key selection changed
00324     KFCURVEEVENT_DESTROY    =1 << 9, // animation curve destruction
00325     KFCURVEEVENT_DEPRECATED10 =1 << 10,
00326     KFCURVEEVENT_KEYADD     =1 << 11,
00327     KFCURVEEVENT_KEYREMOVE  =1 << 12,
00328     KFCURVEEVENT_EDITVALUE  =1 << 13,
00329     KFCURVEEVENT_EDITTIME   =1 << 14,
00330     KFCURVEEVENT_EDITOTHER  =1 << 15,
00331 };
00332 
00333 
00338 class KFBX_DLL KFCurveEvent : public KEventBase
00339 {
00340 public:
00341     // Curve event type, the enum stated above allow composition of type (bitfield). 
00342     // Stored in mType
00343     
00345     int mKeyIndexStart;
00347     int mKeyIndexStop;
00349     int mEventCount;
00350 
00352     KFBX_FCURVE_INLINE void Clear (); 
00353     
00358     KFBX_FCURVE_INLINE void Add (int pWhat, int pIndex);
00359 };
00360 
00361 typedef void (*kFCurveCallback) (KFCurve *pFCurve, KFCurveEvent *FCurveEvent, void* pObject);
00362 
00367 class KFBX_DLL KFCurveTangeantInfo 
00368 {
00369 public:
00370     KFBX_FCURVE_INLINE KFCurveTangeantInfo();
00371 
00372     kFCurveDouble mDerivative;
00373     kFCurveDouble mWeight;
00374     kFCurveDouble mVelocity;
00375     kFCurveDouble mAuto;  // The auto parameter!
00376     bool         mWeighted;
00377     bool          mHasVelocity;
00378 };
00379 
00380 class KFCurveKey;
00381 
00385 class KFCurveKeyAttrManager;
00386 
00387 
00391 class KFBX_DLL KMemoryBlockQueue;
00392 
00399 struct KPriFCurveKeyAttr
00400 {
00401     KPriFCurveKeyAttr() : mFlags(0) {}
00402 
00403     KFBX_FCURVE_INLINE void Set 
00404         (
00405         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
00406         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
00407         kFCurveDouble pData0 = 0.0,
00408         kFCurveDouble pData1 = 0.0,
00409         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
00410         kFCurveDouble pWeight0   = KFCURVE_DEFAULT_WEIGHT,
00411         kFCurveDouble pWeight1   = KFCURVE_DEFAULT_WEIGHT,
00412         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
00413         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
00414         );
00415 
00416     KFBX_FCURVE_INLINE void SetTCB (float pData0 = 0.0f, float pData1 = 0.0f, float pData2 = 0.0f);
00417     KFBX_FCURVE_INLINE void Set(KFCurveKey& pSource);
00418     KFBX_FCURVE_INLINE kFCurveInterpolation GetInterpolation() const;
00419     KFBX_FCURVE_INLINE void SetInterpolation(kFCurveInterpolation pInterpolation);
00420     KFBX_FCURVE_INLINE kFCurveConstantMode GetConstantMode() const;
00421     KFBX_FCURVE_INLINE kFCurveTangeantMode GetTangeantMode( bool pIncludeOverrides = false ) const;
00422     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode GetTangeantWeightMode() const;
00423     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode GetTangeantVelocityMode() const;
00424     KFBX_FCURVE_INLINE void SetConstantMode(kFCurveConstantMode pMode);
00425     KFBX_FCURVE_INLINE void SetTangeantMode(kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
00426     KFBX_FCURVE_INLINE void SetTangeantWeightMode(kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
00427     KFBX_FCURVE_INLINE void SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight );
00428     KFBX_FCURVE_INLINE void SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
00429     KFBX_FCURVE_INLINE kFCurveDouble GetDataDouble(EKFCurveDataIndex pIndex) const;
00430     KFBX_FCURVE_INLINE void SetDataDouble(EKFCurveDataIndex pIndex, kFCurveDouble pValue);
00431     KFBX_FCURVE_INLINE float GetDataFloat(EKFCurveDataIndex pIndex) const;
00432     KFBX_FCURVE_INLINE void SetDataFloat(EKFCurveDataIndex pIndex, float pValue);
00433     KFBX_FCURVE_INLINE float* GetDataPtr() const;
00434     KFBX_FCURVE_INLINE void SetSelected(bool pSelected);    
00435     KFBX_FCURVE_INLINE bool GetSelected() const;
00436     KFBX_FCURVE_INLINE void SetMarkedForManipulation(bool pMark);   
00437     KFBX_FCURVE_INLINE bool GetMarkedForManipulation() const;
00438     KFBX_FCURVE_INLINE void SetTangeantVisibility (kFCurveTangeantVisibility pVisibility);  
00439     KFBX_FCURVE_INLINE kFCurveTangeantVisibility GetTangeantVisibility () const;
00440     KFBX_FCURVE_INLINE void SetBreak(bool pVal); 
00441     KFBX_FCURVE_INLINE bool GetBreak() const; 
00442     KFBX_FCURVE_INLINE bool IsEqual(const KPriFCurveKeyAttr& pRsh) const;
00443     KFBX_FCURVE_INLINE void IncRefCount();
00444     KFBX_FCURVE_INLINE void DecRefCount();
00445     KFBX_FCURVE_INLINE kUInt32 GetRefCount() const;
00446 
00447     kUInt32 mFlags;
00448 #ifdef KFCURVE_FLOAT
00449     float  mData[4];
00450 #else 
00451     double  mData[2];
00452     kInt16  mWeight[2];
00453     kInt16  mVelocity[2];
00454 #endif  
00455     kUInt32 mRefCount;
00456 
00457 };
00458 
00459 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00460 
00465 struct KPriFCurveKey
00466 {
00467     KPriFCurveKey()
00468     {
00469         Init();
00470     }
00471 
00472     KFBX_FCURVE_INLINE void Init();
00473     KFBX_FCURVE_INLINE void Set (KTime pTime, kFCurveDouble pValue);
00474     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
00475     KFBX_FCURVE_INLINE void SetValue(kFCurveDouble pValue);
00476     KFBX_FCURVE_INLINE void IncValue(kFCurveDouble pValue);
00477     KFBX_FCURVE_INLINE void MultValue(kFCurveDouble pValue);
00478     KFBX_FCURVE_INLINE KTime GetTime() const;
00479     KFBX_FCURVE_INLINE void SetTime(KTime pTime);
00480     KFBX_FCURVE_INLINE void IncTime(KTime pTime);
00481 
00482     KTime mTime;  //8 Bytes
00483 #ifdef KFCURVE_FLOAT
00484     KPriFCurveKeyAttr* mAttr; // 4 Bytes on 32-bit OS, 8 Bytes on 64-bit OS
00485     kFCurveDouble mValue; // 4 Bytes (float) for KFCRVE_FLOAT, 8 Bytes (double) otherwise.
00486 #else
00487     kFCurveDouble mValue;
00488     KPriFCurveKeyAttr* mAttr;
00489 #endif
00490 };
00491 #endif // DOXYGEN_SHOULD_SKIP_THIS
00492 
00493 
00503 class KFBX_DLL KFCurveKey 
00504 {
00505 public:
00506     KFCurveKey()
00507     {
00508         Init();
00509     }
00510 
00511 public:
00512     
00538     KFBX_FCURVE_INLINE void Set 
00539     (
00540         KTime pTime, 
00541         kFCurveDouble pValue, 
00542         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
00543         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
00544         kFCurveDouble pData0 = 0.0,
00545         kFCurveDouble pData1 = 0.0,
00546         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
00547         kFCurveDouble pWeight0                             = KFCURVE_DEFAULT_WEIGHT,
00548         kFCurveDouble pWeight1                             = KFCURVE_DEFAULT_WEIGHT,
00549         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
00550         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
00551     );
00552     
00560     KFBX_FCURVE_INLINE void SetTCB 
00561     (
00562         KTime pTime, 
00563         kFCurveDouble pValue, 
00564         float pData0 = 0.0f, 
00565         float pData1 = 0.0f, 
00566         float pData2 = 0.0f
00567     );
00568     
00572     KFBX_FCURVE_INLINE void Set(KFCurveKey& pSource);
00573     
00581     KFBX_FCURVE_INLINE kFCurveInterpolation GetInterpolation() const;
00582     
00589     KFBX_FCURVE_INLINE void SetInterpolation(kFCurveInterpolation pInterpolation);
00590 
00599     KFBX_FCURVE_INLINE kFCurveConstantMode GetConstantMode() const;
00600 
00613     KFBX_FCURVE_INLINE kFCurveTangeantMode GetTangeantMode( bool pIncludeOverrides = false ) const;
00614 
00623     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode GetTangeantWeightMode() const;
00624 
00633     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode GetTangeantVelocityMode() const;
00634 
00642     KFBX_FCURVE_INLINE void SetConstantMode(kFCurveConstantMode pMode);
00643 
00655     KFBX_FCURVE_INLINE void SetTangeantMode(kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
00656         
00670     KFBX_FCURVE_INLINE void SetTangeantWeightMode(kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
00671 
00685     KFBX_FCURVE_INLINE void SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
00686 
00710     KFBX_FCURVE_INLINE void SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight );
00711 
00712 
00728     KFBX_FCURVE_INLINE kFCurveDouble GetDataDouble(EKFCurveDataIndex pIndex) const;
00729     
00744     KFBX_FCURVE_INLINE void SetDataDouble(EKFCurveDataIndex pIndex, kFCurveDouble pValue);
00745     
00755     KFBX_FCURVE_INLINE float GetDataFloat(EKFCurveDataIndex pIndex) const;
00756 
00766     KFBX_FCURVE_INLINE void SetDataFloat(EKFCurveDataIndex pIndex, float pValue);
00767 
00771     KFBX_FCURVE_INLINE float* GetDataPtr() const;
00772 
00777     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
00778 
00783     KFBX_FCURVE_INLINE void SetValue(kFCurveDouble pValue);
00784 
00788     KFBX_FCURVE_INLINE void IncValue(kFCurveDouble pValue);
00789 
00793     KFBX_FCURVE_INLINE void MultValue(kFCurveDouble pValue);
00794 
00798     KFBX_FCURVE_INLINE KTime GetTime() const;
00799 
00803     KFBX_FCURVE_INLINE void SetTime(KTime pTime);
00804 
00808     KFBX_FCURVE_INLINE void IncTime(KTime pTime);
00809 
00813     KFBX_FCURVE_INLINE void SetSelected(bool pSelected);    
00814 
00818     KFBX_FCURVE_INLINE bool GetSelected() const;
00819 
00823     KFBX_FCURVE_INLINE void SetMarkedForManipulation(bool pMark);   
00824 
00828     KFBX_FCURVE_INLINE bool GetMarkedForManipulation() const;
00829 
00839     KFBX_FCURVE_INLINE void SetTangeantVisibility (kFCurveTangeantVisibility pVisibility);  
00840 
00850     KFBX_FCURVE_INLINE kFCurveTangeantVisibility GetTangeantVisibility () const;
00851 
00857     KFBX_FCURVE_INLINE void SetBreak(bool pVal); 
00858 
00864     KFBX_FCURVE_INLINE bool GetBreak() const; 
00865 
00868     KFBX_FCURVE_INLINE void Init();
00869 
00870 
00872 //
00873 //  WARNING!
00874 //
00875 //  Anything beyond these lines may not be documented accurately and is 
00876 //  subject to change without notice.
00877 //
00879 
00880 
00881     #ifndef DOXYGEN_SHOULD_SKIP_THIS
00882 private:
00883     friend class KFCurve;
00884     KFBX_FCURVE_INLINE KFCurveKey(const KPriFCurveKey& pKey, const KPriFCurveKeyAttr& pAttr);
00885     KFBX_FCURVE_INLINE KPriFCurveKeyAttr GetKeyAttr() const;
00886 
00887 private:
00888     KTime mTime;
00889     kFCurveDouble mValue;           
00890     kUInt32 mFlags;
00891 
00892     #ifdef KFCURVE_FLOAT
00893         float  mData[4];
00894     #else 
00895         double  mData[2];
00896         kInt16  mWeight[2];
00897         kInt16  mVelocity[2];
00898     #endif  
00899 
00900     #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00901 
00902 };
00903 
00904 #ifdef KFCURVE_FLOAT
00905 extern void TangentWeightAndAdjustTangent(EKFCurveDataIndex pIndex, kFCurveDouble pWeight, float mData[4]);
00906 #else
00907 extern void TangentWeightAndAdjustTangent(EKFCurveDataIndex pIndex, kFCurveDouble pWeight, double mData[2], kInt16 mWeight[2]);
00908 #endif
00909 
00910 const int KEY_BLOCK_SIZE    = 1024;
00911 const int KEY_BLOCK_COUNT   = KEY_BLOCK_SIZE/sizeof (KPriFCurveKey);
00912 
00913 const int KEY_LIST_BLOCK_SIZE   = 256;
00914 const int KEY_LIST_BLOCK_COUNT  = KEY_LIST_BLOCK_SIZE/sizeof (KPriFCurveKey *);
00915 
00962 class KFBX_DLL KFCurve
00963 {
00964 
00965 public:
00966 
00971 
00973     KFCurve();
00974 
00976     virtual ~KFCurve();
00977 
00981     void Destroy(int Local=0);
00982 
00984 
00992     float* GetColor();
00993 
00997     void SetColor(const float *pColor);
00998 
01003     void SetValue(kFCurveDouble pValue);
01004 
01009     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
01011 
01016 
01021     void ResizeKeyBuffer(int pKeyCount, bool pResetKeyCount = false);
01022 
01026     void KeyModifyBegin ();
01027 
01031     void KeyModifyEnd ();
01032 
01036     int KeyGetCount () const;
01037 
01039     int KeyGetSelectionCount () const;
01040 
01042     void KeySelectAll ();
01043 
01045     void KeyUnselectAll ();
01046 
01053     KFCurveKey KeyGet(kFCurveIndex pIndex) const;
01054 
01056     void KeyClear ();
01057 
01061     void KeyShrink();
01062 
01071     bool    KeySet(kFCurveIndex pIndex, KFCurveKey& pKey);
01072 
01082     bool    KeySet(kFCurveIndex pIndex, KFCurve* pSourceCurve, int pSourceIndex);
01083 
01091     int KeyMove(kFCurveIndex pIndex, KTime pTime);
01092 
01102     bool KeyMoveOf (bool pSelectedOnly, KTime pDeltaTime, kFCurveDouble pDeltaValue);
01103 
01110     bool KeyMoveValueTo (bool pSelectedOnly, kFCurveDouble pValue);
01111 
01118     bool KeyScaleValue (bool pSelectedOnly, kFCurveDouble pMultValue);
01119 
01126     bool KeyScaleTangeant (bool pSelectedOnly, kFCurveDouble pMultValue);
01127 
01134     bool KeyScaleValueAndTangeant (bool pSelectedOnly, kFCurveDouble pMultValue);
01135 
01140     bool KeyRemove(kFCurveIndex pIndex);
01141 
01157     int KeyInsert ( KTime pTime, kFCurveIndex* pLast = NULL );
01158 
01175     int KeyAdd (KTime pTime, KFCurveKey& pKey, kFCurveIndex* pLast = NULL);
01176 
01194     int KeyAdd(KTime pTime, KFCurve* pSourceCurve, int pSourceIndex, kFCurveIndex* pLast = NULL);
01195 
01210     int KeyAdd (KTime pTime, kFCurveIndex* pLast = NULL);
01211 
01219     int KeyAppend(KTime pAtTime, KFCurve* pSourceCurve, int pSourceIndex);
01220 
01231     int KeyAppendFast( KTime pTime, kFCurveDouble pValue );
01232 
01246     double KeyFind (KTime pTime, kFCurveIndex* pLast = NULL);   
01247 
01249 
01250     /************************************************************************************************/
01251     /************************************************************************************************/
01252     /************************************************************************************************/
01253     /************************************************************************************************/
01254     /************************************************************************************************/
01255     /************************************************************************************************/
01256 
01257 
01262 
01291     KFBX_FCURVE_INLINE void KeySet 
01292         (
01293         kFCurveIndex pKeyIndex,
01294         KTime pTime, 
01295         kFCurveDouble pValue, 
01296         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
01297         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
01298         kFCurveDouble pRightSlope = 0.0,
01299         kFCurveDouble pNextLeftSlope = 0.0,
01300         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
01301         kFCurveDouble pWeight0                             = KFCURVE_DEFAULT_WEIGHT,
01302         kFCurveDouble pWeight1                             = KFCURVE_DEFAULT_WEIGHT,
01303         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
01304         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
01305         );
01306 
01319     KFBX_FCURVE_INLINE void KeySetTCB 
01320         (
01321         kFCurveIndex pKeyIndex,
01322         KTime pTime, 
01323         kFCurveDouble pValue, 
01324         float pData0 = 0.0f, 
01325         float pData1 = 0.0f, 
01326         float pData2 = 0.0f
01327         );
01328 
01337     KFBX_FCURVE_INLINE kFCurveInterpolation KeyGetInterpolation(kFCurveIndex pKeyIndex) const;
01338 
01347     KFBX_FCURVE_INLINE void KeySetInterpolation(kFCurveIndex pKeyIndex, kFCurveInterpolation pInterpolation);
01348 
01353     bool IsKeyInterpolationPureCubicAuto(kFCurveIndex pKeyIndex);
01354 
01364     KFBX_FCURVE_INLINE kFCurveConstantMode KeyGetConstantMode(kFCurveIndex pKeyIndex) const;
01365 
01379     KFBX_FCURVE_INLINE kFCurveTangeantMode KeyGetTangeantMode(kFCurveIndex pKeyIndex, bool pIncludeOverrides = false ) const;
01380 
01390     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KeyGetTangeantWeightMode(kFCurveIndex pKeyIndex) const;
01391 
01401     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KeyGetTangeantVelocityMode(kFCurveIndex pKeyIndex) const;
01402 
01411     KFBX_FCURVE_INLINE void KeySetConstantMode(kFCurveIndex pKeyIndex, kFCurveConstantMode pMode);
01412 
01425     KFBX_FCURVE_INLINE void KeySetTangeantMode(kFCurveIndex pKeyIndex, kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
01426 
01442     KFBX_FCURVE_INLINE void KeySetTangeantWeightMode(kFCurveIndex pKeyIndex, kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
01443 
01458     KFBX_FCURVE_INLINE void KeySetTangeantVelocityMode(kFCurveIndex pKeyIndex, kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
01459 
01460 
01477     KFBX_FCURVE_INLINE kFCurveDouble KeyGetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const;
01478 
01495     KFBX_FCURVE_INLINE void KeySetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, kFCurveDouble pValue);
01496 
01507     KFBX_FCURVE_INLINE float KeyGetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const;
01508 
01519     KFBX_FCURVE_INLINE void KeySetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, float pValue);
01520 
01525     KFBX_FCURVE_INLINE const float* KeyGetDataPtr(kFCurveIndex pKeyIndex) const;
01526 
01532     KFBX_FCURVE_INLINE kFCurveDouble KeyGetValue(kFCurveIndex pKeyIndex) const;
01533 
01539     KFBX_FCURVE_INLINE void KeySetValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01540 
01546     KFBX_FCURVE_INLINE void KeyIncValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01547 
01554     KFBX_FCURVE_INLINE void KeyMultValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01555 
01563     KFBX_FCURVE_INLINE void KeyMultTangeant(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01564 
01569     KFBX_FCURVE_INLINE KTime KeyGetTime(kFCurveIndex pKeyIndex) const;
01570 
01576     KFBX_FCURVE_INLINE void KeySetTime(kFCurveIndex pKeyIndex, KTime pTime);
01577 
01583     KFBX_FCURVE_INLINE void KeyIncTime(kFCurveIndex pKeyIndex, KTime pTime);
01584 
01591     KFBX_FCURVE_INLINE void KeySetSelected(kFCurveIndex pKeyIndex, bool pSelected); 
01592 
01597     KFBX_FCURVE_INLINE bool KeyGetSelected(kFCurveIndex pKeyIndex) const;
01598 
01605     KFBX_FCURVE_INLINE void KeySetMarkedForManipulation(kFCurveIndex pKeyIndex, bool pMark);    
01606 
01613     KFBX_FCURVE_INLINE bool KeyGetMarkedForManipulation(kFCurveIndex pKeyIndex) const;
01614 
01625     KFBX_FCURVE_INLINE void KeySetTangeantVisibility (kFCurveIndex pKeyIndex, kFCurveTangeantVisibility pVisibility);   
01626 
01637     KFBX_FCURVE_INLINE kFCurveTangeantVisibility KeyGetTangeantVisibility (kFCurveIndex pKeyIndex) const;
01638 
01645     KFBX_FCURVE_INLINE void KeySetBreak(kFCurveIndex pKeyIndex, bool pVal); 
01646 
01653     KFBX_FCURVE_INLINE bool KeyGetBreak(kFCurveIndex pKeyIndex) const; 
01654 
01656 
01657     /************************************************************************************************/
01658     /************************************************************************************************/
01659     /************************************************************************************************/
01660     /************************************************************************************************/
01661     /************************************************************************************************/
01662     /************************************************************************************************/
01663 
01668 
01674     void KeyTangeantSetInterpolation(bool pSelectedOnly, kFCurveInterpolation pInterpolation);
01675 
01683     void KeyTangeantSetMode(bool pSelectedOnly, kFCurveTangeantMode pTangentMode);
01684 
01691     kFCurveDouble KeyGetLeftDerivative(kFCurveIndex pIndex);
01692 
01702     void KeySetLeftDerivative(kFCurveIndex pIndex, kFCurveDouble pValue);
01703 
01711     kFCurveDouble KeyGetLeftAuto(kFCurveIndex pIndex, bool pApplyOvershootProtection = false);
01712 
01722     void KeySetLeftAuto(kFCurveIndex pIndex, kFCurveDouble pValue); 
01723 
01730     KFCurveTangeantInfo KeyGetLeftDerivativeInfo(kFCurveIndex pIndex);
01731 
01743     void KeySetLeftDerivativeInfo(kFCurveIndex pIndex, KFCurveTangeantInfo pValue, bool pForceDerivative = false);
01744 
01745 
01755     void KeyIncLeftDerivative(kFCurveIndex pIndex, kFCurveDouble pInc);
01756 
01763     kFCurveDouble KeyGetRightDerivative(kFCurveIndex pIndex);
01764 
01774     void KeySetRightDerivative(kFCurveIndex pIndex, kFCurveDouble pValue);
01775 
01783     kFCurveDouble KeyGetRightAuto(kFCurveIndex pIndex, bool pApplyOvershootProtection = false);
01784 
01794     void KeySetRightAuto(kFCurveIndex pIndex, kFCurveDouble pValue);
01795 
01802     KFCurveTangeantInfo KeyGetRightDerivativeInfo(kFCurveIndex pIndex);
01803 
01815     void KeySetRightDerivativeInfo(kFCurveIndex pIndex, KFCurveTangeantInfo pValue, bool pForceDerivative = false);
01816 
01817 
01827     void KeyIncRightDerivative(kFCurveIndex pIndex, kFCurveDouble pInc);
01828 
01833     kFCurveDouble KeyGetRightBezierTangeant(kFCurveIndex pIndex);
01834 
01844     void KeySetLeftBezierTangeant(kFCurveIndex pIndex, kFCurveDouble pValue);
01845 
01850     kFCurveDouble KeyGetLeftBezierTangeant(kFCurveIndex pIndex);
01851 
01861     void KeySetRightBezierTangeant(kFCurveIndex pIndex, kFCurveDouble pValue);
01862 
01863 
01872     void KeyMultDerivative(kFCurveIndex pIndex, kFCurveDouble pMultValue);
01873 
01880     bool KeyIsLeftTangeantWeighted(kFCurveIndex pIndex) const;
01881 
01888     bool KeyIsRightTangeantWeighted(kFCurveIndex pIndex) const;
01889 
01897     void   KeySetLeftTangeantWeightedMode( kFCurveIndex pIndex, bool pWeighted);
01898 
01906     void   KeySetRightTangeantWeightedMode( kFCurveIndex pIndex, bool pWeighted);
01907 
01914     kFCurveDouble KeyGetLeftTangeantWeight(kFCurveIndex pIndex) const;
01915 
01922     kFCurveDouble KeyGetRightTangeantWeight(kFCurveIndex pIndex) const;
01923 
01935     void   KeySetLeftTangeantWeight( kFCurveIndex pIndex, kFCurveDouble pWeight, bool pAdjustTan = false );
01936 
01948     void   KeySetRightTangeantWeight( kFCurveIndex pIndex, kFCurveDouble pWeight, bool pAdjustTan = false  );
01949 
01956     bool KeyIsLeftTangeantVelocity(kFCurveIndex pIndex) const;
01957 
01964     bool KeyIsRightTangeantVelocity(kFCurveIndex pIndex) const;
01965 
01973     void   KeySetLeftTangeantVelocityMode( kFCurveIndex pIndex, bool pVelocity );
01974 
01982     void   KeySetRightTangeantVelocityMode( kFCurveIndex pIndex, bool pVelocity);
01983 
01990     kFCurveDouble KeyGetLeftTangeantVelocity(kFCurveIndex pIndex) const;
01991 
01998     kFCurveDouble KeyGetRightTangeantVelocity(kFCurveIndex pIndex) const;
01999 
02008     void   KeySetLeftTangeantVelocity( kFCurveIndex pIndex, kFCurveDouble pVelocity );
02009 
02018     void   KeySetRightTangeantVelocity( kFCurveIndex pIndex, kFCurveDouble pVelocity );
02019 
02021 
02034 
02038     KFBX_FCURVE_INLINE void SetPreExtrapolation(kFCurveExtrapolationMode pExtrapolation);
02039 
02041     KFBX_FCURVE_INLINE kFCurveExtrapolationMode GetPreExtrapolation() const;
02042 
02047     KFBX_FCURVE_INLINE void SetPreExtrapolationCount(kULong pCount);
02048 
02053     KFBX_FCURVE_INLINE kULong GetPreExtrapolationCount() const;
02054 
02058     KFBX_FCURVE_INLINE void SetPostExtrapolation(kFCurveExtrapolationMode pExtrapolation);
02059 
02061     KFBX_FCURVE_INLINE kFCurveExtrapolationMode GetPostExtrapolation() const;
02062 
02067     KFBX_FCURVE_INLINE void SetPostExtrapolationCount(kULong pCount);
02068 
02073     KFBX_FCURVE_INLINE kULong GetPostExtrapolationCount() const;
02074 
02081     int KeyGetCountAll() const;
02082 
02094     double KeyFindAll(KTime pTime, kFCurveIndex* pLast = NULL);
02095 
02097 
02102 
02115     kFCurveDouble Evaluate (KTime pTime, kFCurveIndex* pLast = NULL);
02116 
02127     kFCurveDouble EvaluateIndex( double pIndex);
02128 
02137     kFCurveDouble EvaluateLeftDerivative (KTime pTime, kFCurveIndex* pLast = NULL);
02138 
02147     kFCurveDouble EvaluateRightDerivative (KTime pTime, kFCurveIndex* pLast = NULL);
02148 
02157     int FindPeaks(kFCurveIndex pLeftKeyIndex, KTime& pPeakTime1, KTime& pPeakTime2);
02158 
02167     int FindPeaks(kFCurveIndex pLeftKeyIndex, kFCurveDouble& pPeak1, kFCurveDouble& pPeak2);
02168 
02179     int FindPeaks(kFCurveIndex pLeftKeyIndex, KTime& pPeakTime1, kFCurveDouble& pPeak1, KTime& pPeakTime2, kFCurveDouble& pPeak2);
02180 
02187     void KeyGetPeriods(KTime& pAveragePeriod, KTime& pMinPeriod, KTime& pMaxPeriod);
02188 
02190 
02195 
02202     HKFCurve Copy(KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE);
02203 
02209     void CopyFrom(KFCurve& pSource, bool pWithKeys = true);
02210 
02220     void Replace(HKFCurve pSource, KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE, bool pUseExactGivenSpan = false, bool pKeyStartEndOnNoKey = true, KTime pTimeSpanOffset = KTIME_ZERO );
02221 
02235     void ReplaceForQuaternion(HKFCurve pSource, KTime pStart, KTime pStop, kFCurveDouble pScaleStart, kFCurveDouble pScaleStop, bool pUseExactGivenSpan = false, bool pKeyStartEndOnNoKey = true, KTime pTimeSpanOffset = KTIME_ZERO );
02236 
02256     void ReplaceForEulerXYZ(HKFCurve pSource, KTime pStart, KTime pStop, kFCurveDouble pAddFromStart, kFCurveDouble pAddAfterStop, bool pValueSubOffsetAfterStart, bool pValueSubOffsetAfterStop, bool pUseExactGivenSpan = false, bool pKeyStartEndOnNoKey = true, KTime pTimeSpanOffset = KTIME_ZERO );   
02257 
02270     void Insert(HKFCurve pSource, KTime pInsertTime, kFCurveDouble pFirstKeyLeftDerivative, bool pFirstKeyIsWeighted = false, kFCurveDouble pFirstKeyWeight = KFCURVE_DEFAULT_WEIGHT);
02271 
02281     void Insert(HKFCurve pSource, KTime pInsertTime, KFCurveTangeantInfo pFirstKeyLeftDerivative );
02282 
02292     bool Delete(kFCurveIndex pStartIndex , kFCurveIndex pStopIndex);                                    
02293 
02301     bool Delete (KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE, bool pInclusive = false);
02302 
02310     void ExtractKeysIndex( KArrayTemplate<int> &pArray, int pMinIndex, int pMaxIndex, double pMinValue =  -K_DOUBLE_MAX, double pMaxValue =  K_DOUBLE_MAX);
02311 
02313 
02315     //
02316     //  WARNING!
02317     //
02318     //  Anything beyond these lines may not be documented accurately and is 
02319     //  subject to change without notice.
02320     //
02322 
02323 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02324     typedef enum {
02325         V7   = 4008,
02326         V71  = 4007,
02327         V6   = 4005,
02328         V5   = 4004
02329     } FbxStoreVersionID;
02330 
02331     bool    FbxStore (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = true, FbxStoreVersionID pVersionID = V7);
02332     bool    FbxRetrieve (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false );
02333     bool    FbxInternalRetrieve (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false );
02334 
02335     void    FbxStorePriKeyAndAttrArrays(KFbx* pFbx, FbxStoreVersionID pVersionID = V7);
02336     void    FbxRetrievePriKeyAndAttrArrays(KFbx* pFbx, int pKeyVersion);
02337     void    FbxRetrievePrePostExtrapolation(KFbx* pFbx);
02338 
02339     double CandidateEvaluate (KTime pTime, kFCurveIndex* pLast = NULL);
02340     bool CandidateClear ();
02341     bool CandidateSet (KTime pTime, double pValue);
02342     bool IsCandidate ();
02343     double CandidateGet ();
02344     KTime CandidateGetTime ();
02345 
02346     bool IsLocked() const;
02347     bool IsLockedByLayer() const;
02348     bool IsLockedByProperty() const;
02349     void SetLockedByLayer(bool pLocked);
02350     void SetLockedByProperty(bool pLocked);
02351 
02352     bool CandidateKey
02353         (
02354         kFCurveIndex    *pLast              = NULL, 
02355         int pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
02356         int pTanMode = KFCURVE_TANGEANT_USER, 
02357         int pContinuity = KFCURVE_CONTINUITY,
02358         bool            pTangeantOverride   = true,
02359         KTime           pCandidateTime      = KTIME_INFINITE,
02360         double          pKeyIndexTolerance  = 0.0
02361         );
02362 
02363     bool NormalsSeemsToComeFromAPlot();
02364 
02365     void SetWasData (int pType);
02366     int GetWasData () const;
02367     int GuessWasData (KTime* pStart = NULL, KTime* pStep = NULL);
02368 
02369     void KeyTangeantHide ();
02370 
02371     int GetUpdateId () const;
02372     int GetValuesUpdateId () const;
02373 
02374     void CallbackRegister (kFCurveCallback pCallback, void* pObject);
02375     void CallbackUnregister (kFCurveCallback pCallback, void* pObject);
02376     void CallbackEnable (bool pEnable);
02377     void CallbackClear ();
02378 
02379 public:
02381     static const bool sConvertAutoTimeIndepedent;
02382 
02391     void CopyExternalPriKeyAndAttr(void** pSourceFCurveKeysList, int pSourceFCurveKeyCount); 
02392 
02393     KPriFCurveKey** GetPriFCurveKeysList() const { return mFCurveKeysList; }
02394 
02395 private:
02396     void KeyAttrSet(kFCurveIndex pKeyIndex, const KPriFCurveKeyAttr& pKeyAttr);
02397 
02402     void KeyAttrSeparate(kFCurveIndex pKeyIndex);
02403     
02407     KFBX_FCURVE_INLINE void KeyAttrSeparateCheck(kFCurveIndex pKeyIndex);
02408 
02409     /* Control optimization flag, when enable, we will perform KeyAttrShrink() operation
02410      * when call KeyModifyEnd().
02411      */ 
02412     void KeySetOptimizeEnable(bool pEnable); 
02413     void KeySetOptimizeThreshold(int pThreshold);
02414 
02418     void KeyAttrShrink(kFCurveIndex pStartIndex, kFCurveIndex pStopIndex);
02419 
02420     void IncrementUpdateId(int pInc);
02421     void CallbackAddEvent (int pWhat, int pIndexStart);
02422 
02423     int MapIndexAll (int pIndex, int &pWhere);
02424     void InitBuffers (int pKeyCount, bool pResetKeyCount = false );
02425 
02426     bool CheckCurve();
02427 
02429     void IsClamped( int pIndex, bool &pLeftClamped, bool &pRightClamped ) const;
02430 
02431 public:
02436     static void AllocateGlobals();
02437 
02442     static void FreeGlobals();
02443 
02444 public:
02445     static  KFCurveKeyAttrManager*  smGlobalKeyAttrMemoryPool;
02446     // Recording Memory global var
02447     static  kULong                  smGlobalRecordingMemory;
02448     static  KMemoryBlockQueue*      smGlobalKeyBufferQueue;
02449 
02450 private:
02451 
02452     float mColor[3];
02453 
02454     kFCurveDouble mValue;
02455 
02456     int mUpdateId;
02457     int mFlags;
02458     int mOptimizationThreshold;
02459     int mKeyModifyGuard;
02460 
02461     KPriFCurveKey** mFCurveKeysList;
02462 
02463     int mFCurveKeyCount;    
02464     int mFCurveKeySize; 
02465     int mFCurveLastBlockIndex;  
02466 
02467 
02468     kUInt mPreExtrapolation;
02469     kULong mPreExtrapolationCount;
02470     kUInt mPostExtrapolation;
02471     kULong mPostExtrapolationCount;
02472 
02473     int mWasType;
02474 
02475     kFCurveIndex mLastSearchIndex;
02476 
02477     KTime mCandidateTime;
02478     kFCurveDouble mCandidateValue;
02479 
02480     KFCurveEvent mEvent;
02481     KArrayUL mCallbackFunctions;   // no delete on object must use array ul
02482     KArrayUL mCallbackObjects;     // no delete on object must use array ul
02483 
02484     KFBX_FCURVE_INLINE KPriFCurveKey* InternalPriKeyGetPtr (kFCurveIndex pIndex) const;
02485     KFBX_FCURVE_INLINE KPriFCurveKeyAttr* InternalPriKeyAttrGetPtr(kFCurveIndex pIndex) const;
02486 
02487 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
02488 
02489 };
02490 
02491 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02492 // Allocate memory blocks for animation curve to give room for recording.
02493 KFBX_DLL void KFCURVE_SetFCurveRecordMemoryBlockCount ( int pBlockCount );
02494 KFBX_DLL int KFCURVE_GetFCurveMemoryBlockSize ( );
02495 KFBX_DLL void KFCURVE_ClearMemoryBlockQueue ();
02496 
02497 //
02498 // class KFCurveEvent
02499 //
02500 KFBX_FCURVE_INLINE void KFCurveEvent::Clear () 
02501 {
02502     mType = KFCURVEEVENT_NONE;
02503     mKeyIndexStart = mKeyIndexStop=-1; 
02504     mEventCount = 0; 
02505 }
02506 
02507 
02508 KFBX_FCURVE_INLINE void KFCurveEvent::Add (int pWhat, int pIndex) 
02509 {       
02510     mType |= pWhat;
02511     mEventCount++;
02512     if ( (pIndex<mKeyIndexStart) || (mKeyIndexStart==-1)) 
02513     {
02514         mKeyIndexStart = pIndex;
02515     }
02516     if (pIndex>mKeyIndexStop) 
02517     {
02518         mKeyIndexStop = pIndex;
02519     }
02520 }
02521 
02522 //
02523 //  class KFCurveKey
02524 //
02525 KFBX_FCURVE_INLINE KFCurveTangeantInfo::KFCurveTangeantInfo()
02526 {
02527     mDerivative = 0.0;
02528     mWeight     = KFCURVE_DEFAULT_WEIGHT;
02529     mWeighted   = false;
02530     mVelocity   = KFCURVE_DEFAULT_VELOCITY;
02531     mHasVelocity= false;
02532     mAuto       = 0.0;
02533 }
02534 
02535 KFBX_FCURVE_INLINE KFCurveKey::KFCurveKey(const KPriFCurveKey& pKey, const KPriFCurveKeyAttr& pAttr)
02536 {
02537     mTime = pKey.mTime;
02538     mValue = pKey.mValue;
02539     mFlags = pAttr.mFlags;
02540     mData[0] = pAttr.mData[0];
02541     mData[1] = pAttr.mData[1];
02542 #ifdef KFCURVE_FLOAT
02543     mData[2] = pAttr.mData[2];
02544     mData[3] = pAttr.mData[3];
02545 #else
02546     mWeight[0] = pAttr.mWeight[0];
02547     mWeight[1] = pAttr.mWeight[1];
02548     mVelocity[0] = pAttr.mVelocity[0];
02549     mVelocity[1] = pAttr.mVelocity[1];
02550 #endif
02551 }
02552 
02553 KFBX_FCURVE_INLINE KPriFCurveKeyAttr KFCurveKey::GetKeyAttr() const
02554 {
02555     KPriFCurveKeyAttr lKeyAttr;
02556     lKeyAttr.mFlags = mFlags;
02557     lKeyAttr.mData[0] = mData[0];
02558     lKeyAttr.mData[1] = mData[1];
02559 #ifdef KFCURVE_FLOAT
02560     lKeyAttr.mData[2] = mData[2];
02561     lKeyAttr.mData[3] = mData[3];
02562 #else
02563     lKeyAttr.mWeight[0] = mWeight[0];
02564     lKeyAttr.mWeight[1] = mWeight[1];
02565     lKeyAttr.mVelocity[0] = mVelocity[0];
02566     lKeyAttr.mVelocity[1] = mVelocity[1];
02567 #endif
02568     return lKeyAttr;
02569 }
02570 
02571 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::Set 
02572 (
02573     kFCurveInterpolation pInterpolation /* = KFCURVE_INTERPOLATION_CUBIC*/, 
02574     kFCurveTangeantMode pTangeantMode /*= KFCURVE_TANGEANT_AUTO*/, 
02575     kFCurveDouble pData0 /*= 0*/, 
02576     kFCurveDouble pData1 /*= 0*/,
02577     kFCurveTangeantWeightMode pTangeantWeightMode /*= KFCURVE_WEIGHT_NONE*/, 
02578     kFCurveDouble pWeight0 /* = KFCURVE_DEFAULT_WEIGHT */,
02579     kFCurveDouble pWeight1 /* = KFCURVE_DEFAULT_WEIGHT */,
02580     kFCurveDouble pVelocity0 /* = KFCURVE_DEFAULT_VELOCITY */,
02581     kFCurveDouble pVelocity1 /* = KFCURVE_DEFAULT_VELOCITY */
02582 )
02583 {
02584     K_ASSERT (pInterpolation != KFCURVE_INTERPOLATION_CUBIC || pTangeantMode != KFCURVE_TANGEANT_TCB);
02585 
02586     SetInterpolation (pInterpolation);
02587     SetTangeantMode (pTangeantMode);
02588     SetDataDouble (KFCURVEKEY_RIGHT_SLOPE, pData0);
02589     SetDataDouble (KFCURVEKEY_NEXT_LEFT_SLOPE, pData1);
02590 
02591     SetTangeantWeightMode (pTangeantWeightMode);
02592     SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, pWeight0);
02593     SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, pWeight1);
02594 
02595     SetDataDouble (KFCURVEKEY_RIGHT_VELOCITY, pVelocity0);
02596     SetDataDouble (KFCURVEKEY_NEXT_LEFT_VELOCITY, pVelocity1);
02597 
02598     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE); 
02599 }
02600 
02601 KFBX_FCURVE_INLINE void KPriFCurveKey::Set 
02602 (
02603     KTime pTime, 
02604     kFCurveDouble pValue
02605 )
02606 {
02607     SetTime (pTime);
02608     SetValue (pValue);
02609 }
02610 
02611 //
02612 //  class KFCurveKey
02613 //
02614 
02615 KFBX_FCURVE_INLINE void KFCurveKey::Set 
02616     (
02617     KTime pTime, 
02618     kFCurveDouble pValue, 
02619     kFCurveInterpolation pInterpolation /* = KFCURVE_INTERPOLATION_CUBIC*/, 
02620     kFCurveTangeantMode pTangeantMode /*= KFCURVE_TANGEANT_AUTO*/, 
02621     kFCurveDouble pData0 /*= 0*/, 
02622     kFCurveDouble pData1 /*= 0*/,
02623     kFCurveTangeantWeightMode pTangeantWeightMode /*= KFCURVE_WEIGHT_NONE*/, 
02624     kFCurveDouble pWeight0 /* = KFCURVE_DEFAULT_WEIGHT */,
02625     kFCurveDouble pWeight1 /* = KFCURVE_DEFAULT_WEIGHT */,
02626     kFCurveDouble pVelocity0 /* = KFCURVE_DEFAULT_VELOCITY */,
02627     kFCurveDouble pVelocity1 /* = KFCURVE_DEFAULT_VELOCITY */
02628     )
02629 {
02630     K_ASSERT (pInterpolation != KFCURVE_INTERPOLATION_CUBIC || pTangeantMode != KFCURVE_TANGEANT_TCB);
02631 
02632     SetTime (pTime);
02633     SetValue (pValue);
02634     SetInterpolation (pInterpolation);
02635     SetTangeantMode (pTangeantMode);
02636     SetDataDouble (KFCURVEKEY_RIGHT_SLOPE, pData0);
02637     SetDataDouble (KFCURVEKEY_NEXT_LEFT_SLOPE, pData1);
02638 
02639     SetTangeantWeightMode (pTangeantWeightMode);
02640     SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, pWeight0);
02641     SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, pWeight1);
02642 
02643     SetDataDouble (KFCURVEKEY_RIGHT_VELOCITY, pVelocity0);
02644     SetDataDouble (KFCURVEKEY_NEXT_LEFT_VELOCITY, pVelocity1);
02645 
02646     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02647 }
02648 
02649 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTCB (float pData1/*=0.0f*/, float pData2/*=0.0f*/, float pData3/*=0.0f*/)
02650 {
02651     SetInterpolation (KFCURVE_INTERPOLATION_CUBIC);
02652     SetTangeantMode (KFCURVE_TANGEANT_TCB);
02653     SetDataFloat (KFCURVEKEY_TCB_TENSION, pData1);
02654     SetDataFloat (KFCURVEKEY_TCB_CONTINUITY, pData2);
02655     SetDataFloat (KFCURVEKEY_TCB_BIAS, pData3);
02656     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02657 }
02658 
02659 KFBX_FCURVE_INLINE void KFCurveKey::SetTCB (KTime pTime, kFCurveDouble pValue, float pData1/*=0.0f*/, float pData2/*=0.0f*/, float pData3/*=0.0f*/)
02660 {
02661     SetTime (pTime);
02662     SetValue (pValue);
02663     SetInterpolation (KFCURVE_INTERPOLATION_CUBIC);
02664     SetTangeantMode (KFCURVE_TANGEANT_TCB);
02665     SetDataFloat (KFCURVEKEY_TCB_TENSION, pData1);
02666     SetDataFloat (KFCURVEKEY_TCB_CONTINUITY, pData2);
02667     SetDataFloat (KFCURVEKEY_TCB_BIAS, pData3);
02668     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02669 }
02670 
02671 
02672 KFBX_FCURVE_INLINE void KFCurveKey::Set (KFCurveKey& iSource)
02673 {
02674     memcpy(this, &iSource, sizeof(KFCurveKey));
02675 }
02676 
02677 KFBX_FCURVE_INLINE kFCurveInterpolation KPriFCurveKeyAttr::GetInterpolation() const
02678 {
02679     return mFlags & KFCURVE_INTERPOLATION_ALL;
02680 }
02681 
02682 KFBX_FCURVE_INLINE kFCurveInterpolation KFCurveKey::GetInterpolation () const
02683 {
02684     return mFlags & KFCURVE_INTERPOLATION_ALL;
02685 }
02686 
02687 
02688 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetInterpolation (kFCurveInterpolation pInterpolation)   
02689 {
02690     K_ASSERT_MSG(   (pInterpolation == KFCURVE_INTERPOLATION_CUBIC) || 
02691         (pInterpolation == KFCURVE_INTERPOLATION_LINEAR) ||
02692         (pInterpolation == KFCURVE_INTERPOLATION_CONSTANT) ,"Wrong interpolation type." );
02693 
02694     if( (((mFlags & KFCURVE_INTERPOLATION_ALL)!=KFCURVE_INTERPOLATION_CUBIC)) && pInterpolation == KFCURVE_INTERPOLATION_CUBIC )
02695     {
02696         // Clear weighting information
02697         SetTangeantWeightMode( KFCURVE_WEIGHTED_NONE);
02698         SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02699         SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02700 
02701         SetTangeantVelocityMode(KFCURVE_VELOCITY_NONE);
02702         SetDataDouble( KFCURVEKEY_RIGHT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02703         SetDataDouble( KFCURVEKEY_NEXT_LEFT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02704     }
02705 
02706     mFlags = (mFlags & ~KFCURVE_INTERPOLATION_ALL) | (pInterpolation & KFCURVE_INTERPOLATION_ALL); 
02707 }
02708 
02709 
02710 KFBX_FCURVE_INLINE void KFCurveKey::SetInterpolation (kFCurveInterpolation pInterpolation)  
02711 {
02712     K_ASSERT_MSG(   (pInterpolation == KFCURVE_INTERPOLATION_CUBIC) || 
02713                     (pInterpolation == KFCURVE_INTERPOLATION_LINEAR) ||
02714                     (pInterpolation == KFCURVE_INTERPOLATION_CONSTANT) ,"Wrong interpolation type." );
02715 
02716     if( (((mFlags & KFCURVE_INTERPOLATION_ALL)!=KFCURVE_INTERPOLATION_CUBIC)) && pInterpolation == KFCURVE_INTERPOLATION_CUBIC )
02717     {
02718         // Clear weighting information
02719         SetTangeantWeightMode( KFCURVE_WEIGHTED_NONE);
02720         SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02721         SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02722 
02723         SetTangeantVelocityMode(KFCURVE_VELOCITY_NONE);
02724         SetDataDouble( KFCURVEKEY_RIGHT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02725         SetDataDouble( KFCURVEKEY_NEXT_LEFT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02726     }
02727 
02728     mFlags = (mFlags & ~KFCURVE_INTERPOLATION_ALL) | (pInterpolation & KFCURVE_INTERPOLATION_ALL); 
02729 }
02730 
02731 KFBX_FCURVE_INLINE kFCurveConstantMode KPriFCurveKeyAttr::GetConstantMode() const
02732 {
02733     return mFlags & KFCURVE_CONSTANT_ALL;
02734 }
02735 
02736 KFBX_FCURVE_INLINE kFCurveConstantMode KFCurveKey::GetConstantMode() const
02737 {
02738     return mFlags & KFCURVE_CONSTANT_ALL;
02739 }
02740 
02741 KFBX_FCURVE_INLINE kFCurveTangeantMode KPriFCurveKeyAttr::GetTangeantMode( bool pIncludeOverrides ) const
02742 {
02743     if( pIncludeOverrides )
02744     {
02745         return mFlags & KFCURVE_TANGEANT_ALL;
02746     }
02747     else
02748     {
02749         return mFlags & KFCURVE_TANGEANT_TYPE_MASK;
02750     }
02751 }
02752 
02753 KFBX_FCURVE_INLINE kFCurveTangeantMode KFCurveKey::GetTangeantMode( bool pIncludeOverrides ) const
02754 {
02755     if( pIncludeOverrides )
02756     {
02757         return mFlags & KFCURVE_TANGEANT_ALL;
02758     }
02759     else
02760     {
02761         return mFlags & KFCURVE_TANGEANT_TYPE_MASK;
02762     }
02763 }
02764 
02765 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetConstantMode (kFCurveConstantMode pMode)          
02766 {
02767     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) ||
02768         (pMode == KFCURVE_CONSTANT_STANDARD) ||
02769         (pMode == KFCURVE_CONSTANT_NEXT),"Wrong constant mode.");
02770 
02771     mFlags = (mFlags & ~KFCURVE_CONSTANT_ALL) | (pMode & KFCURVE_CONSTANT_ALL); 
02772 }
02773 
02774 KFBX_FCURVE_INLINE void KFCurveKey::SetConstantMode (kFCurveConstantMode pMode)         
02775 {
02776     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) ||
02777                     (pMode == KFCURVE_CONSTANT_STANDARD) ||
02778                     (pMode == KFCURVE_CONSTANT_NEXT),"Wrong constant mode.");
02779 
02780     mFlags = (mFlags & ~KFCURVE_CONSTANT_ALL) | (pMode & KFCURVE_CONSTANT_ALL); 
02781 }
02782 
02783 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantMode (kFCurveTangeantMode pTangeant, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)            
02784 {
02785     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) || !(pTangeant & ~KFCURVE_TANGEANT_ALL), "Wrong tangeant mode." );
02786     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) || !(pTangeant & ~KFCURVE_CONSTANT_ALL), "Wrong tangeant mode." );
02787 
02788     // Convert Auto to Time-Independent.
02789     if (! pIgnoreAutoTimeIndepedentConversion && KFCurve::sConvertAutoTimeIndepedent && (mFlags & KFCURVE_INTERPOLATION_CUBIC) && (pTangeant & KFCURVE_TANGEANT_AUTO))
02790     {
02791         pTangeant = pTangeant | KFCURVE_GENERIC_TIME_INDEPENDENT;
02792     }
02793 
02794     mFlags = (mFlags & ~(KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL)) | (pTangeant & (KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL) ); 
02795 }
02796 
02797 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantMode (kFCurveTangeantMode pTangeant, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)           
02798 {
02799     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) || !(pTangeant & ~KFCURVE_TANGEANT_ALL), "Wrong tangeant mode." );
02800     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) || !(pTangeant & ~KFCURVE_CONSTANT_ALL), "Wrong tangeant mode." );
02801 
02802     // Convert Auto to Time-Independent.
02803     if (! pIgnoreAutoTimeIndepedentConversion && KFCurve::sConvertAutoTimeIndepedent && (mFlags & KFCURVE_INTERPOLATION_CUBIC) && (pTangeant & KFCURVE_TANGEANT_AUTO))
02804     {
02805         pTangeant = pTangeant | KFCURVE_GENERIC_TIME_INDEPENDENT;
02806     }
02807 
02808     mFlags = (mFlags & ~(KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL)) | (pTangeant & (KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL) ); 
02809 }
02810 
02811 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KPriFCurveKeyAttr::GetTangeantWeightMode() const
02812 {
02813     return mFlags & KFCURVE_WEIGHTED_ALL;
02814 }
02815 
02816 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KFCurveKey::GetTangeantWeightMode() const
02817 {
02818     return mFlags & KFCURVE_WEIGHTED_ALL;
02819 }
02820 
02821 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantWeightMode(kFCurveTangeantWeightMode pTangent, kFCurveTangeantWeightMode pMask /* KFCURVE_WEIGHTED_ALL */ )
02822 {
02823     pMask &= KFCURVE_WEIGHTED_ALL;
02824     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02825 }
02826 
02827 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantWeightMode(kFCurveTangeantWeightMode pTangent, kFCurveTangeantWeightMode pMask /* KFCURVE_WEIGHTED_ALL */ )
02828 {
02829 
02830     pMask &= KFCURVE_WEIGHTED_ALL;
02831     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02832 }
02833 
02834 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KPriFCurveKeyAttr::GetTangeantVelocityMode() const
02835 {
02836     return mFlags & KFCURVE_VELOCITY_ALL;
02837 }
02838 
02839 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KFCurveKey::GetTangeantVelocityMode() const
02840 {
02841     return mFlags & KFCURVE_VELOCITY_ALL;
02842 }
02843 
02844 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight ) 
02845 {
02846 #ifdef KFCURVE_FLOAT
02847     TangentWeightAndAdjustTangent(pIndex, pWeight, mData);
02848 #else
02849     TangentWeightAndAdjustTangent(pIndex, pWeight, mData, mWeight);
02850 #endif
02851 }
02852 
02853 KFBX_FCURVE_INLINE void KFCurveKey::SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight ) 
02854 {
02855 #ifdef KFCURVE_FLOAT
02856     TangentWeightAndAdjustTangent(pIndex, pWeight, mData);
02857 #else
02858     TangentWeightAndAdjustTangent(pIndex, pWeight, mData, mWeight);
02859 #endif
02860 }
02861 
02862 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangent, kFCurveTangeantVelocityMode pMask /* KFCURVE_VELOCITY_ALL */ )
02863 {
02864     pMask &= KFCURVE_VELOCITY_ALL;
02865     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02866 }
02867 
02868 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangent, kFCurveTangeantVelocityMode pMask /* KFCURVE_VELOCITY_ALL */ )
02869 {
02870     pMask &= KFCURVE_VELOCITY_ALL;
02871     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02872 }
02873 
02874 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantVisibility (kFCurveTangeantVisibility pVisibility)                
02875 {
02876     K_ASSERT_MSG(   (pVisibility == KFCURVE_TANGEANT_SHOW_NONE) || 
02877         (pVisibility == KFCURVE_TANGEANT_SHOW_LEFT) ||
02878         (pVisibility == KFCURVE_TANGEANT_SHOW_RIGHT) ||
02879         (pVisibility == KFCURVE_TANGEANT_SHOW_BOTH) ,"Wrong visibility type." );
02880    
02881     mFlags = (mFlags & ~KFCURVE_TANGEANT_SHOW_BOTH) | (pVisibility & KFCURVE_TANGEANT_SHOW_BOTH); 
02882 }
02883 
02884 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantVisibility (kFCurveTangeantVisibility pVisibility)               
02885 {
02886     K_ASSERT_MSG(   (pVisibility == KFCURVE_TANGEANT_SHOW_NONE) || 
02887         (pVisibility == KFCURVE_TANGEANT_SHOW_LEFT) ||
02888         (pVisibility == KFCURVE_TANGEANT_SHOW_RIGHT) ||
02889         (pVisibility == KFCURVE_TANGEANT_SHOW_BOTH) ,"Wrong visibility type." );
02890 
02891     mFlags = (mFlags & ~KFCURVE_TANGEANT_SHOW_BOTH) | (pVisibility & KFCURVE_TANGEANT_SHOW_BOTH); 
02892 }
02893 
02894 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KPriFCurveKeyAttr::GetTangeantVisibility ()  const
02895 {
02896     return mFlags & KFCURVE_TANGEANT_SHOW_BOTH;
02897 }
02898 
02899 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KFCurveKey::GetTangeantVisibility () const
02900 {
02901     return mFlags & KFCURVE_TANGEANT_SHOW_BOTH;
02902 }
02903 
02904 KFBX_FCURVE_INLINE kFCurveDouble KPriFCurveKeyAttr::GetDataDouble (EKFCurveDataIndex pIndex)  const
02905 {
02906     if( pIndex < KFCURVEKEY_WEIGHTS )
02907     {
02908         return mData[pIndex];
02909     }
02910     else
02911     {
02912         #ifdef KFCURVE_FLOAT
02913             return (kFCurveDouble)(((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS])/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02914         #else       
02915             return (kFCurveDouble)mWeight[pIndex-KFCURVEKEY_WEIGHTS]/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02916         #endif
02917     }
02918 }
02919 
02920 KFBX_FCURVE_INLINE kFCurveDouble KFCurveKey::GetDataDouble (EKFCurveDataIndex pIndex) const
02921 {
02922     if( pIndex < KFCURVEKEY_WEIGHTS )
02923     {
02924         return mData[pIndex];
02925     }
02926     else
02927     {
02928         #ifdef KFCURVE_FLOAT
02929             return (kFCurveDouble)(((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS])/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02930         #else       
02931             return (kFCurveDouble)mWeight[pIndex-KFCURVEKEY_WEIGHTS]/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02932         #endif
02933     }
02934 }
02935 
02936 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetDataDouble (EKFCurveDataIndex pIndex, kFCurveDouble pValue) 
02937 {
02938     if( pIndex < KFCURVEKEY_RIGHT_WEIGHT )
02939     {
02940         mData[pIndex] = pValue;
02941     }
02942     else
02943     {
02944         if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue > KFCURVE_MAX_WEIGHT )
02945         {
02946             pValue = KFCURVE_MAX_WEIGHT;
02947         }
02948         else if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue < KFCURVE_MIN_WEIGHT )
02949         {
02950             pValue = KFCURVE_MIN_WEIGHT;
02951         }
02952 
02953         #ifdef KFCURVE_FLOAT
02954             (((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS]) = (kInt16)(pValue*KFCURVE_WEIGHT_DIVIDER);
02955         #else       
02956             mWeight[pIndex-KFCURVEKEY_WEIGHTS] = pValue*KFCURVE_WEIGHT_DIVIDER;
02957         #endif
02958     }
02959 }
02960 
02961 KFBX_FCURVE_INLINE void KFCurveKey::SetDataDouble (EKFCurveDataIndex pIndex, kFCurveDouble pValue) 
02962 {
02963     if( pIndex < KFCURVEKEY_RIGHT_WEIGHT )
02964     {
02965         mData[pIndex] = pValue;
02966     }
02967     else
02968     {
02969         if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue > KFCURVE_MAX_WEIGHT )
02970         {
02971             pValue = KFCURVE_MAX_WEIGHT;
02972         }
02973         else if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue < KFCURVE_MIN_WEIGHT )
02974         {
02975             pValue = KFCURVE_MIN_WEIGHT;
02976         }
02977 
02978         #ifdef KFCURVE_FLOAT
02979             (((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS]) = (kInt16)(pValue*KFCURVE_WEIGHT_DIVIDER);
02980         #else       
02981             mWeight[pIndex-KFCURVEKEY_WEIGHTS] = pValue*KFCURVE_WEIGHT_DIVIDER;
02982         #endif
02983     }
02984 }
02985 
02986 KFBX_FCURVE_INLINE float KPriFCurveKeyAttr::GetDataFloat (EKFCurveDataIndex pIndex)  const
02987 {
02988     return ( (float *)&mData[0])[pIndex];
02989 }
02990 
02991 KFBX_FCURVE_INLINE float KFCurveKey::GetDataFloat (EKFCurveDataIndex pIndex)  const
02992 {
02993     return ( (float *)&mData[0])[pIndex];
02994 }
02995 
02996 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetDataFloat (EKFCurveDataIndex pIndex, float pValue) 
02997 {
02998     ((float *)&mData[0])[pIndex] = pValue;
02999 }
03000 
03001 KFBX_FCURVE_INLINE void KFCurveKey::SetDataFloat (EKFCurveDataIndex pIndex, float pValue) 
03002 {
03003     ((float *)&mData[0])[pIndex] = pValue;
03004 }
03005 
03006 KFBX_FCURVE_INLINE float* KPriFCurveKeyAttr::GetDataPtr() const
03007 {
03008     return (float*)mData;
03009 }
03010 
03011 KFBX_FCURVE_INLINE float* KFCurveKey::GetDataPtr() const
03012 {
03013     return (float*)mData;
03014 }
03015 
03016 KFBX_FCURVE_INLINE kFCurveDouble KPriFCurveKey::GetValue ()  const
03017 {
03018     return mValue;
03019 }
03020 
03021 KFBX_FCURVE_INLINE kFCurveDouble KFCurveKey::GetValue ()  const
03022 {
03023     return mValue;
03024 }
03025 
03026 
03027 KFBX_FCURVE_INLINE void KPriFCurveKey::SetValue (kFCurveDouble pValue) 
03028 {
03029     mValue=pValue;
03030 }
03031 
03032 KFBX_FCURVE_INLINE void KFCurveKey::SetValue (kFCurveDouble pValue) 
03033 {
03034     mValue=pValue;
03035 }
03036 
03037 KFBX_FCURVE_INLINE void KPriFCurveKey::IncValue (kFCurveDouble pValue) 
03038 {
03039     mValue+=pValue;
03040 }
03041 
03042 KFBX_FCURVE_INLINE void KFCurveKey::IncValue (kFCurveDouble pValue) 
03043 {
03044     mValue+=pValue;
03045 }
03046 
03047 KFBX_FCURVE_INLINE void KPriFCurveKey::MultValue (kFCurveDouble pValue) 
03048 {
03049     mValue*=pValue;
03050 }
03051 
03052 KFBX_FCURVE_INLINE void KFCurveKey::MultValue (kFCurveDouble pValue) 
03053 {
03054     mValue*=pValue;
03055 }
03056 
03057 KFBX_FCURVE_INLINE KTime KPriFCurveKey::GetTime ()  const
03058 {
03059     return mTime;
03060 }
03061 
03062 KFBX_FCURVE_INLINE KTime KFCurveKey::GetTime () const
03063 {
03064     return mTime;
03065 }
03066 
03067 KFBX_FCURVE_INLINE void KPriFCurveKey::SetTime (KTime pTime) 
03068 {
03069     K_ASSERT_MSG( pTime != KTIME_MINUS_INFINITE && 
03070     pTime != KTIME_INFINITE, "Key at infinite!" );
03071 
03072     mTime=pTime;
03073 }
03074 
03075 KFBX_FCURVE_INLINE void KFCurveKey::SetTime (KTime pTime) 
03076 {
03077     K_ASSERT_MSG( pTime != KTIME_MINUS_INFINITE && 
03078         pTime != KTIME_INFINITE, "Key at infinite!" );
03079 
03080     mTime=pTime;
03081 }
03082 
03083 KFBX_FCURVE_INLINE void KPriFCurveKey::IncTime (KTime pTime) 
03084 {
03085     mTime+=pTime;
03086 }
03087 
03088 KFBX_FCURVE_INLINE void KFCurveKey::IncTime (KTime pTime) 
03089 {
03090     mTime+=pTime;
03091 }
03092 
03093 
03094 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetSelected (bool pSelected) 
03095 {
03096     mFlags = pSelected ? (mFlags & ~KFCURVE_SELECT_ALL) | KFCURVE_SELECT_POINT : (mFlags & ~KFCURVE_SELECT_ALL);
03097 }
03098 
03099 KFBX_FCURVE_INLINE void KFCurveKey::SetSelected (bool pSelected) 
03100 {
03101     mFlags = pSelected ? (mFlags & ~KFCURVE_SELECT_ALL) | KFCURVE_SELECT_POINT : (mFlags & ~KFCURVE_SELECT_ALL);
03102 }
03103 
03104 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetSelected () const
03105 {
03106     return (mFlags & KFCURVE_SELECT_POINT) ? true : false;
03107 }
03108 
03109 KFBX_FCURVE_INLINE bool KFCurveKey::GetSelected () const
03110 {
03111     return (mFlags & KFCURVE_SELECT_POINT) ? true : false;
03112 }
03113 
03114 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetMarkedForManipulation (bool pSelected) 
03115 {
03116     mFlags = pSelected ? (mFlags & ~KFCURVE_MARKED_ALL) | KFCURVE_MARKED_FOR_MANIP : (mFlags & ~KFCURVE_MARKED_ALL);
03117 }
03118 
03119 KFBX_FCURVE_INLINE void KFCurveKey::SetMarkedForManipulation (bool pSelected) 
03120 {
03121     mFlags = pSelected ? (mFlags & ~KFCURVE_MARKED_ALL) | KFCURVE_MARKED_FOR_MANIP : (mFlags & ~KFCURVE_MARKED_ALL);
03122 }
03123 
03124 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetMarkedForManipulation () const
03125 {
03126     return (mFlags & KFCURVE_MARKED_FOR_MANIP) ? true : false;
03127 }
03128 
03129 KFBX_FCURVE_INLINE bool KFCurveKey::GetMarkedForManipulation () const
03130 {
03131     return (mFlags & KFCURVE_MARKED_FOR_MANIP) ? true : false;
03132 }
03133 
03134 KFBX_FCURVE_INLINE void KPriFCurveKey::Init()
03135 {
03136     mValue = 0.0;
03137     mTime = KTIME_ZERO;
03138     mAttr = NULL;
03139 }
03140 
03141 KFBX_FCURVE_INLINE void KFCurveKey::Init()
03142 {
03143     mValue = 0.0;
03144     mTime = KTIME_ZERO;
03145     mFlags = 0;
03146 }
03147 
03148 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetBreak(bool pVal)
03149 {
03150     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03151         (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03152         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03153         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03154         (GetTangeantMode() == KFCURVE_TANGEANT_USER) ,"Wrong tangeant mode." );
03155 
03156     if(pVal)
03157         mFlags = mFlags |  KFCURVE_GENERIC_BREAK ;
03158     else
03159         mFlags = mFlags & ~KFCURVE_GENERIC_BREAK ;  
03160 
03161 } 
03162 
03163 KFBX_FCURVE_INLINE void KFCurveKey::SetBreak(bool pVal)
03164 {
03165     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03166         (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03167         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03168         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03169         (GetTangeantMode() == KFCURVE_TANGEANT_USER) ,"Wrong tangent mode." );
03170 
03171     if(pVal)
03172         mFlags = mFlags |  KFCURVE_GENERIC_BREAK ;
03173     else
03174         mFlags = mFlags & ~KFCURVE_GENERIC_BREAK ;  
03175 
03176 } 
03177 
03178 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetBreak() const
03179 {
03180     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03181             (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03182             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03183             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03184             (GetTangeantMode() == KFCURVE_TANGEANT_USER)  ,"Wrong tangent mode." );
03185 
03186     if( ((mFlags & KFCURVE_GENERIC_BREAK ) == KFCURVE_GENERIC_BREAK))
03187         return true;
03188     else
03189         return false; 
03190 
03191 }
03192 
03193 KFBX_FCURVE_INLINE bool KFCurveKey::GetBreak() const
03194 {
03195     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03196             (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03197             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03198             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03199             (GetTangeantMode() == KFCURVE_TANGEANT_USER)  ,"Wrong tangent mode." );
03200 
03201     if( ((mFlags & KFCURVE_GENERIC_BREAK ) == KFCURVE_GENERIC_BREAK))
03202         return true;
03203     else
03204         return false; 
03205 
03206 }
03207 
03208 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::IsEqual(const KPriFCurveKeyAttr& pRsh) const
03209 {
03210     // To Modify, don't need to check the data for some Flags. 
03211     return (this == &pRsh) ||
03212         mFlags == pRsh.mFlags &&
03213         mData[0] == pRsh.mData[0] &&
03214         mData[1] == pRsh.mData[1] &&
03215     #ifdef KFCURVE_FLOAT
03216         mData[2] == pRsh.mData[2] &&
03217         mData[3] == pRsh.mData[3];
03218     #else
03219         mWeight[0] == pRsh.mWeight[0] &&
03220         mWeight[1] == pRsh.mWeight[1] &&
03221         mVelocity[0] == pRsh.mVelocity[0] &&
03222         mVelocity[1] == pRsh.mVelocity[1];
03223     #endif
03224 }
03225 
03226 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::IncRefCount()
03227 {
03228     ++mRefCount;
03229 }
03230 
03231 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::DecRefCount()
03232 {
03233     --mRefCount;
03234 }
03235 
03236 KFBX_FCURVE_INLINE kUInt32 KPriFCurveKeyAttr::GetRefCount() const
03237 {
03238     return mRefCount;
03239 }
03240 //****************************************************************************************
03241 // class KFCurve
03242 //****************************************************************************************
03243 
03244 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::GetValue () const 
03245 {
03246     return mValue;
03247 }
03248 
03249 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03250 KFBX_FCURVE_INLINE void KFCurve::SetPreExtrapolation (kUInt pExtrapolation) 
03251 {
03252     K_ASSERT_MSG(   (pExtrapolation == KFCURVE_EXTRAPOLATION_CONST) || 
03253         (pExtrapolation == KFCURVE_EXTRAPOLATION_REPETITION) ||
03254         (pExtrapolation == KFCURVE_EXTRAPOLATION_MIRROR_REPETITION) ||
03255         (pExtrapolation == KFCURVE_EXTRAPOLATION_KEEP_SLOPE) ,"Wrong extrapolation type." );
03256 
03257     mPreExtrapolation = pExtrapolation; 
03258     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03259 }
03260 #endif
03261 
03262 KFBX_FCURVE_INLINE kUInt KFCurve::GetPreExtrapolation () const 
03263 {
03264     return mPreExtrapolation;
03265 }
03266 
03267 
03268 KFBX_FCURVE_INLINE void KFCurve::SetPreExtrapolationCount (kULong pCount) 
03269 {
03270     mPreExtrapolationCount = pCount; 
03271     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03272 }
03273 
03274 
03275 KFBX_FCURVE_INLINE kULong KFCurve::GetPreExtrapolationCount ()  const
03276 {
03277     return mPreExtrapolationCount;
03278 }
03279 
03280 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03281 
03282 KFBX_FCURVE_INLINE void KFCurve::SetPostExtrapolation (kUInt pExtrapolation) 
03283 {
03284     K_ASSERT_MSG(   (pExtrapolation == KFCURVE_EXTRAPOLATION_CONST) || 
03285         (pExtrapolation == KFCURVE_EXTRAPOLATION_REPETITION) ||
03286         (pExtrapolation == KFCURVE_EXTRAPOLATION_MIRROR_REPETITION) ||
03287         (pExtrapolation == KFCURVE_EXTRAPOLATION_KEEP_SLOPE) ,"Wrong extrapolation type." );
03288 
03289     mPostExtrapolation = pExtrapolation; 
03290     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03291 }
03292 
03293 #endif
03294 
03295 KFBX_FCURVE_INLINE kUInt KFCurve::GetPostExtrapolation () const 
03296 {
03297     return mPostExtrapolation;
03298 }
03299 
03300 
03301 KFBX_FCURVE_INLINE void KFCurve::SetPostExtrapolationCount (kULong pCount) 
03302 {
03303     mPostExtrapolationCount = pCount; 
03304     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03305 }
03306 
03307 
03308 KFBX_FCURVE_INLINE kULong KFCurve::GetPostExtrapolationCount ()  const
03309 {
03310     return mPostExtrapolationCount;
03311 }
03312 
03313 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03314 KFBX_FCURVE_INLINE KPriFCurveKey* KFCurve::InternalPriKeyGetPtr (int pIndex) const
03315 {
03316     K_ASSERT_MSG( pIndex >= 0, "Negative indexes are not recommended." );
03317     K_ASSERT_MSG( mFCurveKeysList && mFCurveKeysList[pIndex / KEY_BLOCK_COUNT], "Accessing unallocated buffer." );
03318 
03319     return mFCurveKeysList[pIndex / KEY_BLOCK_COUNT] + (pIndex % KEY_BLOCK_COUNT);
03320 }
03321 
03322 
03323 KFBX_FCURVE_INLINE KPriFCurveKeyAttr* KFCurve::InternalPriKeyAttrGetPtr(kFCurveIndex pIndex) const
03324 {
03325     #ifdef _DEBUG
03326         KPriFCurveKey* lKey = InternalPriKeyGetPtr(pIndex);
03327         K_ASSERT_MSG(lKey->mAttr != NULL, "Accessing uninitialized keyattr.");
03328         return lKey->mAttr;
03329     #else
03330         return InternalPriKeyGetPtr(pIndex)->mAttr;
03331     #endif
03332 }
03333 #endif // DOXYGEN_SHOULD_SKIP_THIS
03334 
03335 /*********************************************************************************************/
03336 /*********************************************************************************************/
03337 /*********************************************************************************************/
03338 /*********************************************************************************************/
03339 KFBX_FCURVE_INLINE void KFCurve::KeySet 
03340     (
03341     kFCurveIndex pKeyIndex,
03342     KTime pTime, 
03343     kFCurveDouble pValue, 
03344     kFCurveInterpolation pInterpolation, 
03345     kFCurveTangeantMode pTangentMode, 
03346     kFCurveDouble pRightSlope, 
03347     kFCurveDouble pNextLeftSlope, 
03348     kFCurveTangeantWeightMode pTangentWeightMode, 
03349     kFCurveDouble pWeight0, 
03350     kFCurveDouble pWeight1, 
03351     kFCurveDouble pVelocity0, 
03352     kFCurveDouble pVelocity1
03353     )
03354 {
03355     KPriFCurveKey *lPriKey = InternalPriKeyGetPtr(pKeyIndex);
03356     lPriKey->Set(pTime, pValue);
03357     KPriFCurveKeyAttr lKeyAttr;
03358     lKeyAttr.mFlags = 0;
03359     if (lPriKey->mAttr)
03360         lKeyAttr.mFlags = lPriKey->mAttr->mFlags;
03361     lKeyAttr.Set( pInterpolation, pTangentMode, pRightSlope, pNextLeftSlope, pTangentWeightMode, pWeight0, pWeight1, pVelocity0, pVelocity1);
03362 
03363     KeyAttrSet(pKeyIndex, lKeyAttr);
03364 }
03365 
03366 KFBX_FCURVE_INLINE void KFCurve::KeySetTCB 
03367     (
03368     kFCurveIndex pKeyIndex,
03369     KTime pTime, 
03370     kFCurveDouble pValue, 
03371     float pData0, 
03372     float pData1, 
03373     float pData2
03374     )
03375 {
03376     InternalPriKeyGetPtr(pKeyIndex)->Set(pTime, pValue);
03377     KPriFCurveKeyAttr lKeyAttr;
03378     lKeyAttr.SetTCB(pData0, pData1, pData2);
03379 
03380     KeyAttrSet(pKeyIndex, lKeyAttr);
03381 }
03382 
03383 KFBX_FCURVE_INLINE kFCurveInterpolation KFCurve::KeyGetInterpolation(kFCurveIndex pKeyIndex) const
03384 {
03385     K_ASSERT(pKeyIndex >= 0);
03386     K_ASSERT(pKeyIndex < KeyGetCount());
03387 
03388     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetInterpolation();
03389 }
03390 
03391 KFBX_FCURVE_INLINE void KFCurve::KeySetInterpolation(kFCurveIndex pKeyIndex, kFCurveInterpolation pInterpolation)
03392 {
03393     K_ASSERT(pKeyIndex >= 0);
03394     K_ASSERT(pKeyIndex < KeyGetCount());
03395 
03396     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03397     K_ASSERT(lKey->mAttr != NULL);
03398     if (lKey->mAttr)
03399     {
03400         if ( lKey->mAttr->GetInterpolation() != pInterpolation)
03401         {
03402             KeyAttrSeparateCheck(pKeyIndex);
03403             lKey->mAttr->SetInterpolation(pInterpolation);
03404             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03405         }
03406     }
03407 }
03408 
03409 KFBX_FCURVE_INLINE kFCurveConstantMode KFCurve::KeyGetConstantMode(kFCurveIndex pKeyIndex) const
03410 {
03411     K_ASSERT(pKeyIndex >= 0);
03412     K_ASSERT(pKeyIndex < KeyGetCount());
03413 
03414     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetConstantMode();
03415 }
03416 
03417 KFBX_FCURVE_INLINE kFCurveTangeantMode KFCurve::KeyGetTangeantMode(kFCurveIndex pKeyIndex, bool pIncludeOverrides ) const
03418 {
03419     K_ASSERT(pKeyIndex >= 0);
03420     K_ASSERT(pKeyIndex < KeyGetCount());
03421 
03422     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantMode( pIncludeOverrides );
03423 }
03424 
03425 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KFCurve::KeyGetTangeantWeightMode(kFCurveIndex pKeyIndex) const
03426 {
03427     K_ASSERT(pKeyIndex >= 0);
03428     K_ASSERT(pKeyIndex < KeyGetCount());
03429 
03430     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantWeightMode();
03431 }
03432 
03433 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KFCurve::KeyGetTangeantVelocityMode(kFCurveIndex pKeyIndex) const
03434 {
03435     K_ASSERT(pKeyIndex >= 0);
03436     K_ASSERT(pKeyIndex < KeyGetCount());
03437 
03438     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantVelocityMode();
03439 }
03440 
03441 KFBX_FCURVE_INLINE void KFCurve::KeySetConstantMode(kFCurveIndex pKeyIndex, kFCurveConstantMode pMode)
03442 {
03443     K_ASSERT(pKeyIndex >= 0);
03444     K_ASSERT(pKeyIndex < KeyGetCount());
03445 
03446     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03447     K_ASSERT(lKey->mAttr != NULL);
03448     if (lKey->mAttr)
03449     {
03450         if (lKey->mAttr->GetConstantMode() != pMode)
03451         {
03452             KeyAttrSeparateCheck(pKeyIndex);
03453             lKey->mAttr->SetConstantMode(pMode);
03454             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03455         }
03456     }
03457 }
03458 
03459 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantMode(kFCurveIndex pKeyIndex, kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)
03460 {
03461     K_ASSERT(pKeyIndex >= 0);
03462     K_ASSERT(pKeyIndex < KeyGetCount());
03463 
03464     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03465     // We need to test if the flag value will be really changed.
03466     // but there is not easy way to tell that change for this operation,
03467     // so we need to performance special "try and swap" technique.
03468     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03469     K_ASSERT(lKey->mAttr != NULL);
03470     if (lKey->mAttr)
03471     {
03472         kUInt32 lFlags = lKey->mAttr->mFlags;
03473         lKey->mAttr->SetTangeantMode(pTangent, pIgnoreAutoTimeIndepedentConversion); //only affect mFlags
03474 
03475         if (lKey->mAttr->mFlags != lFlags)
03476         {
03477             if (lKey->mAttr->GetRefCount() > 1)
03478             {
03479                 kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03480                 lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03481                 KeyAttrSeparate(pKeyIndex);
03482                 lKey->mAttr->mFlags = lSwapFlags;
03483             }
03484             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03485         }
03486     }
03487 }
03488 
03489 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantWeightMode(kFCurveIndex pKeyIndex, kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask)
03490 {
03491     K_ASSERT(pKeyIndex >= 0);
03492     K_ASSERT(pKeyIndex < KeyGetCount());
03493 
03494     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03495     // We need to test if the flag value will be really changed.
03496     // but there is not easy way to tell that change for this operation,
03497     // so we need to performance special "try and swap" technique.
03498     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03499     K_ASSERT(lKey->mAttr != NULL);
03500     if (lKey->mAttr)
03501     {
03502         kUInt32 lFlags = lKey->mAttr->mFlags;
03503         lKey->mAttr->SetTangeantWeightMode(pTangentWeightMode, pMask); //only affect mFlags
03504         if (lKey->mAttr->mFlags != lFlags)
03505         {
03506            if (lKey->mAttr->GetRefCount() > 1)
03507            {
03508               kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03509               lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03510               KeyAttrSeparate(pKeyIndex);
03511               lKey->mAttr->mFlags = lSwapFlags;
03512            }
03513             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03514         }
03515     }
03516 }
03517 
03518 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantVelocityMode(kFCurveIndex pKeyIndex, kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask)
03519 {
03520     K_ASSERT(pKeyIndex >= 0);
03521     K_ASSERT(pKeyIndex < KeyGetCount());
03522 
03523     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03524     // We need to test if the flag value will be really changed.
03525     // but there is not easy way to tell that change for this operation,
03526     // so we need to performance special "try and swap" technique.
03527     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03528     K_ASSERT(lKey->mAttr != NULL);
03529     if (lKey->mAttr)
03530     {
03531         kUInt32 lFlags = lKey->mAttr->mFlags;
03532         lKey->mAttr->SetTangeantVelocityMode(pTangentVelocityMode, pMask); //only affect mFlags
03533         if (lKey->mAttr->mFlags != lFlags)
03534         {
03535            if (lKey->mAttr->GetRefCount() > 1)
03536            {
03537               kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03538               lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03539               KeyAttrSeparate(pKeyIndex);
03540               lKey->mAttr->mFlags = lSwapFlags;
03541            }
03542             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03543         }
03544     }
03545 }
03546 
03547 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::KeyGetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const
03548 {
03549     K_ASSERT(pKeyIndex >= 0);
03550     K_ASSERT(pKeyIndex < KeyGetCount());
03551 
03552     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataDouble(pIndex);
03553 }
03554 
03555 KFBX_FCURVE_INLINE void KFCurve::KeySetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, kFCurveDouble pValue)
03556 {
03557     K_ASSERT(pKeyIndex >= 0);
03558     K_ASSERT(pKeyIndex < KeyGetCount());
03559 
03560     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03561     K_ASSERT(lKey->mAttr != NULL);
03562     if (lKey->mAttr)
03563     {
03564         if (lKey->mAttr->GetDataDouble(pIndex) != pValue)
03565         {
03566             KeyAttrSeparateCheck(pKeyIndex);
03567             lKey->mAttr->SetDataDouble(pIndex, pValue);
03568             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03569         }
03570     }
03571 }
03572 
03573 KFBX_FCURVE_INLINE float KFCurve::KeyGetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const
03574 {
03575     K_ASSERT(pKeyIndex >= 0);
03576     K_ASSERT(pKeyIndex < KeyGetCount());
03577 
03578     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataFloat(pIndex);
03579 }
03580 
03581 KFBX_FCURVE_INLINE void KFCurve::KeySetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, float pValue)
03582 {
03583     K_ASSERT(pKeyIndex >= 0);
03584     K_ASSERT(pKeyIndex < KeyGetCount());
03585 
03586     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03587     K_ASSERT(lKey->mAttr != NULL);
03588     if (lKey->mAttr)
03589     {
03590         if (lKey->mAttr->GetDataFloat(pIndex) != pValue)
03591         {
03592             KeyAttrSeparateCheck(pKeyIndex);
03593             lKey->mAttr->SetDataFloat(pIndex, pValue);
03594             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03595         }
03596     }
03597 }
03598 
03599 KFBX_FCURVE_INLINE const float* KFCurve::KeyGetDataPtr(kFCurveIndex pKeyIndex) const
03600 {
03601     K_ASSERT(pKeyIndex >= 0);
03602     K_ASSERT(pKeyIndex < KeyGetCount());
03603 
03604     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataPtr();
03605 }
03606 
03607 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::KeyGetValue(kFCurveIndex pKeyIndex) const
03608 {
03609     K_ASSERT(pKeyIndex >= 0);
03610     K_ASSERT(pKeyIndex < KeyGetCount());
03611 
03612     return InternalPriKeyGetPtr(pKeyIndex)->GetValue();
03613 }
03614 
03615 KFBX_FCURVE_INLINE void KFCurve::KeySetValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03616 {
03617     InternalPriKeyGetPtr(pKeyIndex)->SetValue(pValue);
03618     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03619 }
03620 
03621 KFBX_FCURVE_INLINE void KFCurve::KeyIncValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03622 {
03623     K_ASSERT(pKeyIndex >= 0);
03624     K_ASSERT(pKeyIndex < KeyGetCount());
03625 
03626     InternalPriKeyGetPtr(pKeyIndex)->IncValue(pValue);
03627     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03628 }
03629 
03630 KFBX_FCURVE_INLINE void KFCurve::KeyMultValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03631 {
03632     K_ASSERT(pKeyIndex >= 0);
03633     K_ASSERT(pKeyIndex < KeyGetCount());
03634 
03635     InternalPriKeyGetPtr(pKeyIndex)->MultValue(pValue);
03636     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03637 }
03638 
03639 KFBX_FCURVE_INLINE void KFCurve::KeyMultTangeant(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03640 {
03641     K_ASSERT(pKeyIndex >= 0);
03642     K_ASSERT(pKeyIndex < KeyGetCount());
03643 
03644     if (pValue == 1.0)
03645     {
03646        return;
03647     }
03648     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex); K_ASSERT(lKey->mAttr != NULL);
03649     KPriFCurveKey* lKeyNext = NULL;
03650     if (pKeyIndex < KeyGetCount()-1)
03651     {
03652         lKeyNext = InternalPriKeyGetPtr(pKeyIndex+1); 
03653         K_ASSERT(lKeyNext->mAttr != NULL);
03654     }
03655 
03656     if (lKey->mAttr)
03657     {
03658         if (lKey->mAttr->GetInterpolation() == KFCURVE_INTERPOLATION_CUBIC)
03659         {
03660             bool lScaleNextLeft = false;
03661             switch (lKey->mAttr->GetTangeantMode())
03662             {                   
03663             case KFCURVE_TANGEANT_USER:
03664             case KFCURVE_TANGEANT_BREAK:
03665                 lScaleNextLeft = true;
03666                 KeyAttrSeparateCheck(pKeyIndex);                        
03667                 lKey->mAttr->SetDataDouble(KFCURVEKEY_RIGHT_SLOPE, lKey->mAttr->GetDataDouble(KFCURVEKEY_RIGHT_SLOPE) * pValue);
03668 
03669             case KFCURVE_TANGEANT_AUTO:
03670             case KFCURVE_TANGEANT_AUTO_BREAK:
03671                 if (lKeyNext)
03672                 {
03673                     switch (lKeyNext->mAttr->GetTangeantMode())
03674                     {
03675                     case KFCURVE_TANGEANT_USER:
03676                     case KFCURVE_TANGEANT_BREAK:                    
03677                         lScaleNextLeft = true;
03678                     }
03679                 }
03680 
03681                 if (lScaleNextLeft)
03682                 {
03683                     lKey->mAttr->SetDataDouble(KFCURVEKEY_NEXT_LEFT_SLOPE, lKey->mAttr->GetDataDouble(KFCURVEKEY_NEXT_LEFT_SLOPE) * pValue);
03684                     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03685                 }
03686                 break;
03687 
03688             case KFCURVE_TANGEANT_TCB:
03689                 // dunno how to handle this
03690             default:
03691                 // nothing to do
03692                 break;
03693             }
03694         }
03695     }
03696 }
03697 
03698 KFBX_FCURVE_INLINE KTime KFCurve::KeyGetTime(kFCurveIndex pKeyIndex) const
03699 {
03700     K_ASSERT(pKeyIndex >= 0);
03701     K_ASSERT(pKeyIndex < KeyGetCount());
03702 
03703     return InternalPriKeyGetPtr(pKeyIndex)->GetTime();
03704 }
03705 
03706 KFBX_FCURVE_INLINE void KFCurve::KeySetTime(kFCurveIndex pKeyIndex, KTime pTime)
03707 {
03708     K_ASSERT(pKeyIndex >= 0);
03709     K_ASSERT(pKeyIndex < KeyGetCount());
03710 
03711     InternalPriKeyGetPtr(pKeyIndex)->SetTime(pTime);
03712     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITTIME, pKeyIndex);
03713 }
03714 
03715 KFBX_FCURVE_INLINE void KFCurve::KeyIncTime(kFCurveIndex pKeyIndex, KTime pTime)
03716 {
03717     K_ASSERT(pKeyIndex >= 0);
03718     K_ASSERT(pKeyIndex < KeyGetCount());
03719 
03720     InternalPriKeyGetPtr(pKeyIndex)->IncTime(pTime);
03721     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITTIME, pKeyIndex);
03722 }
03723 
03724 KFBX_FCURVE_INLINE void KFCurve::KeySetSelected(kFCurveIndex pKeyIndex, bool pSelected)
03725 {
03726     K_ASSERT(pKeyIndex >= 0);
03727     K_ASSERT(pKeyIndex < KeyGetCount());
03728 
03729     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03730     K_ASSERT(lKey->mAttr != NULL);
03731     if (lKey->mAttr)
03732     {
03733         if (lKey->mAttr->GetSelected() != pSelected)
03734         {
03735             KeyAttrSeparateCheck(pKeyIndex);
03736             lKey->mAttr->SetSelected(pSelected);
03737             CallbackAddEvent(KFCURVEEVENT_SELECTION, pKeyIndex);
03738         }
03739     }
03740 }
03741 
03742 KFBX_FCURVE_INLINE bool KFCurve::KeyGetSelected(kFCurveIndex pKeyIndex) const
03743 {
03744     K_ASSERT(pKeyIndex >= 0);
03745     K_ASSERT(pKeyIndex < KeyGetCount());
03746 
03747     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetSelected();
03748 }
03749 
03750 KFBX_FCURVE_INLINE void KFCurve::KeySetMarkedForManipulation(kFCurveIndex pKeyIndex, bool pMarked)
03751 {
03752     K_ASSERT(pKeyIndex >= 0);
03753     K_ASSERT(pKeyIndex < KeyGetCount());
03754 
03755     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03756     K_ASSERT(lKey->mAttr != NULL);
03757     if (lKey->mAttr)
03758     {
03759         if (lKey->mAttr->GetMarkedForManipulation() != pMarked)
03760         {
03761             KeyAttrSeparateCheck(pKeyIndex);
03762             lKey->mAttr->SetMarkedForManipulation(pMarked);
03763         }
03764     }
03765 }
03766 
03767 KFBX_FCURVE_INLINE bool KFCurve::KeyGetMarkedForManipulation(kFCurveIndex pKeyIndex) const
03768 {
03769     K_ASSERT(pKeyIndex >= 0);
03770     K_ASSERT(pKeyIndex < KeyGetCount());
03771 
03772     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetMarkedForManipulation();
03773 }
03774 
03775 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantVisibility (kFCurveIndex pKeyIndex, kFCurveTangeantVisibility pVisibility)
03776 {
03777     K_ASSERT(pKeyIndex >= 0);
03778     K_ASSERT(pKeyIndex < KeyGetCount());
03779 
03780     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);  
03781     K_ASSERT(lKey->mAttr != NULL);
03782     if (lKey->mAttr)
03783     {
03784         if (lKey->mAttr->GetTangeantVisibility() != pVisibility)
03785         {
03786             KeyAttrSeparateCheck(pKeyIndex);
03787             lKey->mAttr->SetTangeantVisibility(pVisibility);
03788             CallbackAddEvent(KFCURVEEVENT_SELECTION, pKeyIndex);
03789         }
03790     }
03791 }
03792 
03793 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KFCurve::KeyGetTangeantVisibility (kFCurveIndex pKeyIndex) const
03794 {
03795     K_ASSERT(pKeyIndex >= 0);
03796     K_ASSERT(pKeyIndex < KeyGetCount());
03797 
03798     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantVisibility();
03799 }
03800 
03801 KFBX_FCURVE_INLINE void KFCurve::KeySetBreak(kFCurveIndex pKeyIndex, bool pVal)
03802 {
03803     K_ASSERT(pKeyIndex >= 0);
03804     K_ASSERT(pKeyIndex < KeyGetCount());
03805 
03806     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03807     K_ASSERT(lKey->mAttr != NULL);
03808     if (lKey->mAttr)
03809     {   
03810         if (lKey->mAttr->GetBreak() != pVal)
03811         {
03812             KeyAttrSeparateCheck(pKeyIndex);
03813             lKey->mAttr->SetBreak(pVal);
03814             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03815         }
03816     }
03817 }
03818 
03819 KFBX_FCURVE_INLINE bool KFCurve::KeyGetBreak(kFCurveIndex pKeyIndex) const
03820 {
03821     K_ASSERT(pKeyIndex >= 0);
03822     K_ASSERT(pKeyIndex < KeyGetCount());
03823 
03824     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetBreak();
03825 }
03826 
03827 KFBX_FCURVE_INLINE void KFCurve::KeyAttrSeparateCheck(kFCurveIndex pKeyIndex)
03828 {
03829     KPriFCurveKeyAttr* lCurKeyAttr = InternalPriKeyAttrGetPtr(pKeyIndex);
03830     if (! lCurKeyAttr || lCurKeyAttr->GetRefCount() > 1 )
03831         KeyAttrSeparate(pKeyIndex);
03832 }
03833 
03834 
03837 KFBX_DLL HKFCurve KFCurveCreate();
03838 
03839 // Create an animation curve, FBX SDK internal use only.
03840 KFBX_DLL HKFCurve KFCurveCreate(KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false);
03841 
03842 // Create an animation curve, FBX SDK internal use only.
03843 KFBX_DLL HKFCurve KFCurveCreate(KFbx* pFbx, HKFCurve pCurve, bool pOnlyDefaults = false, bool pColor = false);
03844 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS 
03845 
03846 #include <fbxfilesdk/fbxfilesdk_nsend.h>
03847 
03848 
03849 #endif // FBXFILESDK_COMPONENTS_KFCURVE_KFCURVE_H
03850