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 
00085 enum
00086 {
00087     KFCURVE_INTERPOLATION_CONSTANT    = 0x00000002,     
00088     KFCURVE_INTERPOLATION_LINEAR      = 0x00000004,     
00089     KFCURVE_INTERPOLATION_CUBIC       = 0x00000008,     
00090     KFCURVE_INTERPOLATION_ALL         = KFCURVE_INTERPOLATION_CONSTANT|KFCURVE_INTERPOLATION_LINEAR|KFCURVE_INTERPOLATION_CUBIC,
00091     KFCURVE_INTERPOLATION_COUNT       = 3
00092 };                                                
00093 
00100 enum
00101 {
00102     KFCURVE_CONSTANT_STANDARD         = 0x00000000,
00103     KFCURVE_CONSTANT_NEXT             = 0x00000100,
00104     KFCURVE_CONSTANT_ALL              = KFCURVE_CONSTANT_STANDARD | KFCURVE_CONSTANT_NEXT,
00105     KFCURVE_CONSTANT_COUNT            = 2
00106 };
00107 
00121 enum
00122 {
00123     KFCURVE_TANGEANT_AUTO             = 0x00000100,     
00124     KFCURVE_TANGEANT_TCB              = 0x00000200,     
00125     KFCURVE_TANGEANT_USER             = 0x00000400,     
00126     KFCURVE_GENERIC_BREAK             = 0x00000800,     
00127     KFCURVE_GENERIC_CLAMP             = 0x00001000, 
00128     KFCURVE_GENERIC_TIME_INDEPENDENT  = 0x00002000,
00129     KFCURVE_TANGEANT_BREAK            = KFCURVE_TANGEANT_USER|KFCURVE_GENERIC_BREAK,
00130     KFCURVE_TANGEANT_AUTO_BREAK       = KFCURVE_TANGEANT_AUTO|KFCURVE_GENERIC_BREAK,
00131     KFCURVE_TANGEANT_ALL              = KFCURVE_TANGEANT_AUTO|KFCURVE_TANGEANT_TCB|KFCURVE_TANGEANT_USER|KFCURVE_GENERIC_BREAK|KFCURVE_GENERIC_CLAMP|KFCURVE_GENERIC_TIME_INDEPENDENT,
00132     KFCURVE_TANGEANT_TYPE_MASK        = KFCURVE_TANGEANT_AUTO|KFCURVE_TANGEANT_TCB|KFCURVE_TANGEANT_USER|KFCURVE_TANGEANT_BREAK,
00133     KFCURVE_TANGEANT_OVERRIDES_MASK   = KFCURVE_GENERIC_CLAMP|KFCURVE_GENERIC_TIME_INDEPENDENT
00134 };
00135 
00142 enum 
00143 {
00144     KFCURVE_SELECT_POINT              = 0x00010000, 
00145     KFCURVE_SELECT_LEFT               = 0x00020000, 
00146     KFCURVE_SELECT_RIGHT              = 0x00040000, 
00147     KFCURVE_SELECT_ALL                = KFCURVE_SELECT_POINT|KFCURVE_SELECT_LEFT|KFCURVE_SELECT_RIGHT
00148 };
00149 
00154 enum
00155 {
00156     KFCURVE_MARKED_FOR_MANIP          = 0x00080000,
00157     KFCURVE_MARKED_ALL                = KFCURVE_MARKED_FOR_MANIP
00158 };
00159 
00166 enum 
00167 {
00168     KFCURVE_TANGEANT_SHOW_NONE        = 0x00000000, 
00169     KFCURVE_TANGEANT_SHOW_LEFT        = 0x00100000, 
00170     KFCURVE_TANGEANT_SHOW_RIGHT       = 0x00200000, 
00171     KFCURVE_TANGEANT_SHOW_BOTH        = KFCURVE_TANGEANT_SHOW_LEFT|KFCURVE_TANGEANT_SHOW_RIGHT
00172 };
00173 
00180 enum
00181 {
00182     KFCURVE_CONTINUITY                = 0x00000000,
00183     KFCURVE_CONTINUITY_FLAT           = 0x00100000,
00184     KFCURVE_CONTINUITY_BREAK          = 0x00200000,
00185     KFCURVE_CONTINUITY_INSERT         = 0x00400000  
00186 };
00187 
00194 enum 
00195 {
00196     KFCURVE_WEIGHTED_NONE             = 0x00000000, 
00197     KFCURVE_WEIGHTED_RIGHT            = 0x01000000, 
00198     KFCURVE_WEIGHTED_NEXT_LEFT        = 0x02000000, 
00199     KFCURVE_WEIGHTED_ALL              = KFCURVE_WEIGHTED_RIGHT|KFCURVE_WEIGHTED_NEXT_LEFT
00200 };
00201 
00208 enum
00209 {
00210     KFCURVE_VELOCITY_NONE             = 0x00000000,
00211     KFCURVE_VELOCITY_RIGHT            = 0x10000000,
00212     KFCURVE_VELOCITY_NEXT_LEFT        = 0x20000000,
00213     KFCURVE_VELOCITY_ALL              = KFCURVE_VELOCITY_RIGHT | KFCURVE_VELOCITY_NEXT_LEFT
00214 };
00215 
00216 
00217 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00218 
00219 #define KFCURVE_WEIGHT_DIVIDER       9999       // precise enough and can be divided by 3 without error
00220 #define KFCURVE_DEFAULT_WEIGHT       ((kFCurveDouble)(1.0/3.0))
00221 #define KFCURVE_MIN_WEIGHT           ((kFCurveDouble)(1.0/KFCURVE_WEIGHT_DIVIDER))
00222 #define KFCURVE_MAX_WEIGHT           ((kFCurveDouble)0.99)
00223 #define KFCURVE_DEFAULT_VELOCITY     0.0 
00224 
00225 #endif // DOXYGEN_SHOULD_SKIP_THIS
00226 
00227 
00251 enum EKFCurveDataIndex
00252 {
00253     // User and Break tangent mode (data are doubles).
00254     KFCURVEKEY_RIGHT_SLOPE          = 0, 
00255     KFCURVEKEY_NEXT_LEFT_SLOPE      = 1, 
00256 
00257     // User and Break tangent break mode (data are kInt16 tokens from weight and converted to doubles).
00258     KFCURVEKEY_WEIGHTS              = 2, 
00259     KFCURVEKEY_RIGHT_WEIGHT         = 2, 
00260     KFCURVEKEY_NEXT_LEFT_WEIGHT     = 3, 
00261 
00262     // Velocity mode
00263     KFCURVEKEY_VELOCITY             = 4,
00264     KFCURVEKEY_RIGHT_VELOCITY       = 4,
00265     KFCURVEKEY_NEXT_LEFT_VELOCITY   = 5, 
00266 
00267     // TCB tangent mode (data are floats).
00268     KFCURVEKEY_TCB_TENSION          = 0, 
00269     KFCURVEKEY_TCB_CONTINUITY       = 1, 
00270     KFCURVEKEY_TCB_BIAS             = 2,
00271 
00272     KFCURVEKEY_RIGHT_AUTO           = 0,
00273     KFCURVEKEY_NEXT_LEFT_AUTO       = 1
00274 };
00275 
00282 enum 
00283 {
00284     KFCURVE_EXTRAPOLATION_CONST             = 1, 
00285     KFCURVE_EXTRAPOLATION_REPETITION        = 2, 
00286     KFCURVE_EXTRAPOLATION_MIRROR_REPETITION = 3, 
00287     KFCURVE_EXTRAPOLATION_KEEP_SLOPE        = 4
00288 };
00289 
00290 enum 
00291 {
00292     KFCURVE_BEZIER  = 0, 
00293     KFCURVE_SAMPLE  = 1, 
00294     KFCURVE_ISO     = 2
00295 };
00296 
00297 typedef kUInt kFCurveInterpolation;
00298 typedef kUInt kFCurveConstantMode;
00299 typedef kUInt kFCurveTangeantMode;
00300 typedef kUInt kFCurveTangeantWeightMode;
00301 typedef kUInt kFCurveTangeantVelocityMode;
00302 typedef kUInt kFCurveExtrapolationMode;
00303 typedef kUInt kFCurveTangeantVisibility;
00304 typedef int kFCurveIndex;
00305 
00325 enum 
00326 {
00327     KFCURVEEVENT_NONE       =0, // default event value
00328     KFCURVEEVENT_CANDIDATE  =1 << 0, // curve value (not candidate) changed
00329     KFCURVEEVENT_UNUSED1    =1 << 1,
00330     KFCURVEEVENT_UNUSED2    =1 << 2,
00331     KFCURVEEVENT_UNUSED3    =1 << 3,
00332     KFCURVEEVENT_KEY        =1 << 4, // key changed (add, removed, edited); see bits 11-15 for precisions
00333     KFCURVEEVENT_DEPRECATED5 =1 << 5,
00334     KFCURVEEVENT_UNUSED6    =1 << 6,
00335     KFCURVEEVENT_UNUSED7    =1 << 7,
00336     KFCURVEEVENT_SELECTION  =1 << 8, // key selection changed
00337     KFCURVEEVENT_DESTROY    =1 << 9, // fcurve destruction
00338     KFCURVEEVENT_DEPRECATED10 =1 << 10,
00339     KFCURVEEVENT_KEYADD     =1 << 11,
00340     KFCURVEEVENT_KEYREMOVE  =1 << 12,
00341     KFCURVEEVENT_EDITVALUE  =1 << 13,
00342     KFCURVEEVENT_EDITTIME   =1 << 14,
00343     KFCURVEEVENT_EDITOTHER  =1 << 15,
00344 };
00345 
00346 
00349 class KFBX_DLL KFCurveEvent : public KEventBase
00350 {
00351 public:
00352     // Curve event type, the enum stated above allow composition of type (bitfield). 
00353     // Stored in mType
00354     
00355     int mKeyIndexStart; 
00356 
00357     int mKeyIndexStop;  
00358 
00359     int mEventCount;    
00360 
00363     KFBX_FCURVE_INLINE void Clear (); 
00364     
00369     KFBX_FCURVE_INLINE void Add (int pWhat, int pIndex);
00370 };
00371 
00372 typedef void (*kFCurveCallback) (KFCurve *pFCurve, KFCurveEvent *FCurveEvent, void* pObject);
00373 
00378 class KFBX_DLL KFCurveTangeantInfo 
00379 {
00380 public:
00381     KFBX_FCURVE_INLINE KFCurveTangeantInfo();
00382 
00383     kFCurveDouble mDerivative;
00384     kFCurveDouble mWeight;
00385     kFCurveDouble mVelocity;
00386     kFCurveDouble mAuto;  // The auto parameter!
00387     bool         mWeighted;
00388     bool          mHasVelocity;
00389 };
00390 
00391 class KFCurveKey;
00392 
00396 class KFCurveKeyAttrManager;
00397 
00398 
00402 class KFBX_DLL KMemoryBlockQueue;
00403 
00410 struct KPriFCurveKeyAttr
00411 {
00412     KPriFCurveKeyAttr() : mFlags(0) {}
00413 
00414     KFBX_FCURVE_INLINE void Set 
00415         (
00416         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
00417         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
00418         kFCurveDouble pData0 = 0.0,
00419         kFCurveDouble pData1 = 0.0,
00420         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
00421         kFCurveDouble pWeight0   = KFCURVE_DEFAULT_WEIGHT,
00422         kFCurveDouble pWeight1   = KFCURVE_DEFAULT_WEIGHT,
00423         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
00424         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
00425         );
00426 
00427     KFBX_FCURVE_INLINE void SetTCB (float pData0 = 0.0f, float pData1 = 0.0f, float pData2 = 0.0f);
00428     KFBX_FCURVE_INLINE void Set(KFCurveKey& pSource);
00429     KFBX_FCURVE_INLINE kFCurveInterpolation GetInterpolation() const;
00430     KFBX_FCURVE_INLINE void SetInterpolation(kFCurveInterpolation pInterpolation);
00431     KFBX_FCURVE_INLINE kFCurveConstantMode GetConstantMode() const;
00432     KFBX_FCURVE_INLINE kFCurveTangeantMode GetTangeantMode( bool pIncludeOverrides = false ) const;
00433     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode GetTangeantWeightMode() const;
00434     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode GetTangeantVelocityMode() const;
00435     KFBX_FCURVE_INLINE void SetConstantMode(kFCurveConstantMode pMode);
00436     KFBX_FCURVE_INLINE void SetTangeantMode(kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
00437     KFBX_FCURVE_INLINE void SetTangeantWeightMode(kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
00438     KFBX_FCURVE_INLINE void SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight );
00439     KFBX_FCURVE_INLINE void SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
00440     KFBX_FCURVE_INLINE kFCurveDouble GetDataDouble(EKFCurveDataIndex pIndex) const;
00441     KFBX_FCURVE_INLINE void SetDataDouble(EKFCurveDataIndex pIndex, kFCurveDouble pValue);
00442     KFBX_FCURVE_INLINE float GetDataFloat(EKFCurveDataIndex pIndex) const;
00443     KFBX_FCURVE_INLINE void SetDataFloat(EKFCurveDataIndex pIndex, float pValue);
00444     KFBX_FCURVE_INLINE float* GetDataPtr() const;
00445     KFBX_FCURVE_INLINE void SetSelected(bool pSelected);    
00446     KFBX_FCURVE_INLINE bool GetSelected() const;
00447     KFBX_FCURVE_INLINE void SetMarkedForManipulation(bool pMark);   
00448     KFBX_FCURVE_INLINE bool GetMarkedForManipulation() const;
00449     KFBX_FCURVE_INLINE void SetTangeantVisibility (kFCurveTangeantVisibility pVisibility);  
00450     KFBX_FCURVE_INLINE kFCurveTangeantVisibility GetTangeantVisibility () const;
00451     KFBX_FCURVE_INLINE void SetBreak(bool pVal); 
00452     KFBX_FCURVE_INLINE bool GetBreak() const; 
00453     KFBX_FCURVE_INLINE bool IsEqual(const KPriFCurveKeyAttr& pRsh) const;
00454     KFBX_FCURVE_INLINE void IncRefCount();
00455     KFBX_FCURVE_INLINE void DecRefCount();
00456     KFBX_FCURVE_INLINE kUInt32 GetRefCount() const;
00457 
00458     kUInt32 mFlags;
00459 #ifdef KFCURVE_FLOAT
00460     float  mData[4];
00461 #else 
00462     double  mData[2];
00463     kInt16  mWeight[2];
00464     kInt16  mVelocity[2];
00465 #endif  
00466     kUInt32 mRefCount;
00467 
00468 };
00469 
00475 struct KPriFCurveKey
00476 {
00477     KPriFCurveKey()
00478     {
00479         Init();
00480     }
00481 
00482     KFBX_FCURVE_INLINE void Init();
00483     KFBX_FCURVE_INLINE void Set (KTime pTime, kFCurveDouble pValue);
00484     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
00485     KFBX_FCURVE_INLINE void SetValue(kFCurveDouble pValue);
00486     KFBX_FCURVE_INLINE void IncValue(kFCurveDouble pValue);
00487     KFBX_FCURVE_INLINE void MultValue(kFCurveDouble pValue);
00488     KFBX_FCURVE_INLINE KTime GetTime() const;
00489     KFBX_FCURVE_INLINE void SetTime(KTime pTime);
00490     KFBX_FCURVE_INLINE void IncTime(KTime pTime);
00491 
00492     KTime mTime;  //8 Bytes
00493 #ifdef KFCURVE_FLOAT
00494     KPriFCurveKeyAttr* mAttr; // 4 Bytes on 32-bit OS, 8 Bytes on 64-bit OS
00495     kFCurveDouble mValue; // 4 Bytes (float) for KFCRVE_FLOAT, 8 Bytes (double) otherwise.
00496 #else
00497     kFCurveDouble mValue;
00498     KPriFCurveKeyAttr* mAttr;
00499 #endif
00500 };
00501 
00502 
00512 class KFBX_DLL KFCurveKey 
00513 {
00514 public:
00515     KFCurveKey()
00516     {
00517         Init();
00518     }
00519 
00520 public:
00521     
00547     KFBX_FCURVE_INLINE void Set 
00548     (
00549         KTime pTime, 
00550         kFCurveDouble pValue, 
00551         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
00552         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
00553         kFCurveDouble pData0 = 0.0,
00554         kFCurveDouble pData1 = 0.0,
00555         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
00556         kFCurveDouble pWeight0                             = KFCURVE_DEFAULT_WEIGHT,
00557         kFCurveDouble pWeight1                             = KFCURVE_DEFAULT_WEIGHT,
00558         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
00559         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
00560     );
00561     
00569     KFBX_FCURVE_INLINE void SetTCB 
00570     (
00571         KTime pTime, 
00572         kFCurveDouble pValue, 
00573         float pData0 = 0.0f, 
00574         float pData1 = 0.0f, 
00575         float pData2 = 0.0f
00576     );
00577     
00581     KFBX_FCURVE_INLINE void Set(KFCurveKey& pSource);
00582     
00588     KFBX_FCURVE_INLINE kFCurveInterpolation GetInterpolation() const;
00589     
00596     KFBX_FCURVE_INLINE void SetInterpolation(kFCurveInterpolation pInterpolation);
00597 
00605     KFBX_FCURVE_INLINE kFCurveConstantMode GetConstantMode() const;
00606 
00618     KFBX_FCURVE_INLINE kFCurveTangeantMode GetTangeantMode( bool pIncludeOverrides = false ) const;
00619 
00627     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode GetTangeantWeightMode() const;
00628 
00636     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode GetTangeantVelocityMode() const;
00637 
00644     KFBX_FCURVE_INLINE void SetConstantMode(kFCurveConstantMode pMode);
00645 
00656     KFBX_FCURVE_INLINE void SetTangeantMode(kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
00657         
00671     KFBX_FCURVE_INLINE void SetTangeantWeightMode(kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
00672 
00686     KFBX_FCURVE_INLINE void SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
00687 
00711     KFBX_FCURVE_INLINE void SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight );
00712 
00713 
00728     KFBX_FCURVE_INLINE kFCurveDouble GetDataDouble(EKFCurveDataIndex pIndex) const;
00729     
00745     KFBX_FCURVE_INLINE void SetDataDouble(EKFCurveDataIndex pIndex, kFCurveDouble pValue);
00746     
00752     KFBX_FCURVE_INLINE float GetDataFloat(EKFCurveDataIndex pIndex) const;
00753 
00760     KFBX_FCURVE_INLINE void SetDataFloat(EKFCurveDataIndex pIndex, float pValue);
00761 
00765     KFBX_FCURVE_INLINE float* GetDataPtr() const;
00766 
00768     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
00769 
00773     KFBX_FCURVE_INLINE void SetValue(kFCurveDouble pValue);
00774 
00778     KFBX_FCURVE_INLINE void IncValue(kFCurveDouble pValue);
00779 
00783     KFBX_FCURVE_INLINE void MultValue(kFCurveDouble pValue);
00784 
00788     KFBX_FCURVE_INLINE KTime GetTime() const;
00789 
00793     KFBX_FCURVE_INLINE void SetTime(KTime pTime);
00794 
00798     KFBX_FCURVE_INLINE void IncTime(KTime pTime);
00799 
00803     KFBX_FCURVE_INLINE void SetSelected(bool pSelected);    
00804 
00808     KFBX_FCURVE_INLINE bool GetSelected() const;
00809 
00813     KFBX_FCURVE_INLINE void SetMarkedForManipulation(bool pMark);   
00814 
00818     KFBX_FCURVE_INLINE bool GetMarkedForManipulation() const;
00819 
00827     KFBX_FCURVE_INLINE void SetTangeantVisibility (kFCurveTangeantVisibility pVisibility);  
00828 
00836     KFBX_FCURVE_INLINE kFCurveTangeantVisibility GetTangeantVisibility () const;
00837 
00842     KFBX_FCURVE_INLINE void SetBreak(bool pVal); 
00843 
00847     KFBX_FCURVE_INLINE bool GetBreak() const; 
00848 
00851     KFBX_FCURVE_INLINE void Init();
00852 
00853 
00855 //
00856 //  WARNING!
00857 //
00858 //  Anything beyond these lines may not be documented accurately and is 
00859 //  subject to change without notice.
00860 //
00862 
00863 
00864     #ifndef DOXYGEN_SHOULD_SKIP_THIS
00865 private:
00866     friend class KFCurve;
00867     KFBX_FCURVE_INLINE KFCurveKey(const KPriFCurveKey& pKey, const KPriFCurveKeyAttr& pAttr);
00868     KFBX_FCURVE_INLINE KPriFCurveKeyAttr GetKeyAttr() const;
00869 
00870 private:
00871     KTime mTime;
00872     kFCurveDouble mValue;           
00873     kUInt32 mFlags;
00874 
00875     #ifdef KFCURVE_FLOAT
00876         float  mData[4];
00877     #else 
00878         double  mData[2];
00879         kInt16  mWeight[2];
00880         kInt16  mVelocity[2];
00881     #endif  
00882 
00883     #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00884 
00885 };
00886 
00887 #ifdef KFCURVE_FLOAT
00888 extern void TangentWeightAndAdjustTangent(EKFCurveDataIndex pIndex, kFCurveDouble pWeight, float mData[4]);
00889 #else
00890 extern void TangentWeightAndAdjustTangent(EKFCurveDataIndex pIndex, kFCurveDouble pWeight, double mData[2], kInt16 mWeight[2]);
00891 #endif
00892 
00893 const int KEY_BLOCK_SIZE    = 1024;
00894 const int KEY_BLOCK_COUNT   = KEY_BLOCK_SIZE/sizeof (KPriFCurveKey);
00895 
00896 const int KEY_LIST_BLOCK_SIZE   = 256;
00897 const int KEY_LIST_BLOCK_COUNT  = KEY_LIST_BLOCK_SIZE/sizeof (KPriFCurveKey *);
00898 
00899 
00906 class KFBX_DLL KFCurve
00907 {
00908 
00909 public:
00910 
00915 
00917     KFCurve();
00918 
00920     virtual ~KFCurve();
00921 
00922     void Destroy(int Local=0);
00923 
00925 
00929     float* GetColor();
00930 
00934     void SetColor(const float *pColor);
00935 
00940     void SetValue(kFCurveDouble pValue);
00941 
00946     KFBX_FCURVE_INLINE kFCurveDouble GetValue() const;
00947 
00952 
00957     void ResizeKeyBuffer(int pKeyCount, bool pResetKeyCount = false);
00958 
00963     void KeyModifyBegin ();
00964 
00968     void KeyModifyEnd ();
00969 
00971     int KeyGetCount () const;
00972 
00974     int KeyGetSelectionCount () const;
00975 
00977     void KeySelectAll ();
00978 
00980     void KeyUnselectAll ();
00981 
00987     KFCurveKey KeyGet(kFCurveIndex pIndex) const;
00988 
00990     void KeyClear ();
00991 
00993     void KeyShrink();
00994 
01003     bool    KeySet(kFCurveIndex pIndex, KFCurveKey& pKey);
01004 
01014     bool    KeySet(kFCurveIndex pIndex, KFCurve* pSourceCurve, int pSourceIndex);
01015 
01023     int KeyMove(kFCurveIndex pIndex, KTime pTime);
01024 
01032     bool KeyMoveOf (bool pSelectedOnly, KTime pDeltaTime, kFCurveDouble pDeltaValue);
01033 
01040     bool KeyMoveValueTo (bool pSelectedOnly, kFCurveDouble pValue);
01041 
01048     bool KeyScaleValue (bool pSelectedOnly, kFCurveDouble pMultValue);
01049 
01056     bool KeyScaleTangeant (bool pSelectedOnly, kFCurveDouble pMultValue);
01057 
01064     bool KeyScaleValueAndTangeant (bool pSelectedOnly, kFCurveDouble pMultValue);
01065 
01070     bool KeyRemove(kFCurveIndex pIndex);
01071 
01087     int KeyInsert ( KTime pTime, kFCurveIndex* pLast = NULL );
01088 
01105     int KeyAdd (KTime pTime, KFCurveKey& pKey, kFCurveIndex* pLast = NULL);
01106 
01124     int KeyAdd(KTime pTime, KFCurve* pSourceCurve, int pSourceIndex, kFCurveIndex* pLast = NULL);
01125 
01140     int KeyAdd (KTime pTime, kFCurveIndex* pLast = NULL);
01141 
01149     int KeyAppend(KTime pAtTime, KFCurve* pSourceCurve, int pSourceIndex);
01150 
01160     int KeyAppendFast( KTime pTime, kFCurveDouble pValue );
01161 
01172     double KeyFind (KTime pTime, kFCurveIndex* pLast = NULL);   
01173 
01175 
01176     /************************************************************************************************/
01177     /************************************************************************************************/
01178     /************************************************************************************************/
01179     /************************************************************************************************/
01180     /************************************************************************************************/
01181     /************************************************************************************************/
01182 
01183 
01188 
01215     KFBX_FCURVE_INLINE void KeySet 
01216         (
01217         kFCurveIndex pKeyIndex,
01218         KTime pTime, 
01219         kFCurveDouble pValue, 
01220         kFCurveInterpolation pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
01221         kFCurveTangeantMode pTangentMode = KFCURVE_TANGEANT_AUTO, 
01222         kFCurveDouble pRightSlope = 0.0,
01223         kFCurveDouble pNextLeftSlope = 0.0,
01224         kFCurveTangeantWeightMode pTangentWeightMode = KFCURVE_WEIGHTED_NONE, 
01225         kFCurveDouble pWeight0                             = KFCURVE_DEFAULT_WEIGHT,
01226         kFCurveDouble pWeight1                             = KFCURVE_DEFAULT_WEIGHT,
01227         kFCurveDouble pVelocity0 = KFCURVE_DEFAULT_VELOCITY,
01228         kFCurveDouble pVelocity1 = KFCURVE_DEFAULT_VELOCITY
01229         );
01230 
01239     KFBX_FCURVE_INLINE void KeySetTCB 
01240         (
01241         kFCurveIndex pKeyIndex,
01242         KTime pTime, 
01243         kFCurveDouble pValue, 
01244         float pData0 = 0.0f, 
01245         float pData1 = 0.0f, 
01246         float pData2 = 0.0f
01247         );
01248 
01256     KFBX_FCURVE_INLINE kFCurveInterpolation KeyGetInterpolation(kFCurveIndex pKeyIndex) const;
01257 
01265     KFBX_FCURVE_INLINE void KeySetInterpolation(kFCurveIndex pKeyIndex, kFCurveInterpolation pInterpolation);
01266 
01275     KFBX_FCURVE_INLINE kFCurveConstantMode KeyGetConstantMode(kFCurveIndex pKeyIndex) const;
01276 
01289     KFBX_FCURVE_INLINE kFCurveTangeantMode KeyGetTangeantMode(kFCurveIndex pKeyIndex, bool pIncludeOverrides = false ) const;
01290 
01299     KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KeyGetTangeantWeightMode(kFCurveIndex pKeyIndex) const;
01300 
01309     KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KeyGetTangeantVelocityMode(kFCurveIndex pKeyIndex) const;
01310 
01318     KFBX_FCURVE_INLINE void KeySetConstantMode(kFCurveIndex pKeyIndex, kFCurveConstantMode pMode);
01319 
01331     KFBX_FCURVE_INLINE void KeySetTangeantMode(kFCurveIndex pKeyIndex, kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion = false);
01332 
01347     KFBX_FCURVE_INLINE void KeySetTangeantWeightMode(kFCurveIndex pKeyIndex, kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask = KFCURVE_WEIGHTED_ALL );
01348 
01363     KFBX_FCURVE_INLINE void KeySetTangeantVelocityMode(kFCurveIndex pKeyIndex, kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask = KFCURVE_VELOCITY_ALL );
01364 
01365 
01381     KFBX_FCURVE_INLINE kFCurveDouble KeyGetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const;
01382 
01399     KFBX_FCURVE_INLINE void KeySetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, kFCurveDouble pValue);
01400 
01407     KFBX_FCURVE_INLINE float KeyGetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const;
01408 
01416     KFBX_FCURVE_INLINE void KeySetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, float pValue);
01417 
01422     KFBX_FCURVE_INLINE const float* KeyGetDataPtr(kFCurveIndex pKeyIndex) const;
01423 
01427     KFBX_FCURVE_INLINE kFCurveDouble KeyGetValue(kFCurveIndex pKeyIndex) const;
01428 
01433     KFBX_FCURVE_INLINE void KeySetValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01434 
01439     KFBX_FCURVE_INLINE void KeyIncValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01440 
01445     KFBX_FCURVE_INLINE void KeyMultValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01446 
01453     KFBX_FCURVE_INLINE void KeyMultTangeant(kFCurveIndex pKeyIndex, kFCurveDouble pValue);
01454 
01459     KFBX_FCURVE_INLINE KTime KeyGetTime(kFCurveIndex pKeyIndex) const;
01460 
01465     KFBX_FCURVE_INLINE void KeySetTime(kFCurveIndex pKeyIndex, KTime pTime);
01466 
01471     KFBX_FCURVE_INLINE void KeyIncTime(kFCurveIndex pKeyIndex, KTime pTime);
01472 
01477     KFBX_FCURVE_INLINE void KeySetSelected(kFCurveIndex pKeyIndex, bool pSelected); 
01478 
01483     KFBX_FCURVE_INLINE bool KeyGetSelected(kFCurveIndex pKeyIndex) const;
01484 
01489     KFBX_FCURVE_INLINE void KeySetMarkedForManipulation(kFCurveIndex pKeyIndex, bool pMark);    
01490 
01495     KFBX_FCURVE_INLINE bool KeyGetMarkedForManipulation(kFCurveIndex pKeyIndex) const;
01496 
01505     KFBX_FCURVE_INLINE void KeySetTangeantVisibility (kFCurveIndex pKeyIndex, kFCurveTangeantVisibility pVisibility);   
01506 
01515     KFBX_FCURVE_INLINE kFCurveTangeantVisibility KeyGetTangeantVisibility (kFCurveIndex pKeyIndex) const;
01516 
01522     KFBX_FCURVE_INLINE void KeySetBreak(kFCurveIndex pKeyIndex, bool pVal); 
01523 
01528     KFBX_FCURVE_INLINE bool KeyGetBreak(kFCurveIndex pKeyIndex) const; 
01529 
01531 
01532     /************************************************************************************************/
01533     /************************************************************************************************/
01534     /************************************************************************************************/
01535     /************************************************************************************************/
01536     /************************************************************************************************/
01537     /************************************************************************************************/
01538 
01543 
01549     void KeyTangeantSetInterpolation(bool pSelectedOnly, kFCurveInterpolation pInterpolation);
01550 
01557     void KeyTangeantSetMode(bool pSelectedOnly, kFCurveTangeantMode pTangentMode);
01558 
01565     kFCurveDouble KeyGetLeftDerivative(kFCurveIndex pIndex);
01566 
01576     void KeySetLeftDerivative(kFCurveIndex pIndex, kFCurveDouble pValue);
01577 
01585     kFCurveDouble KeyGetLeftAuto(kFCurveIndex pIndex, bool pApplyOvershootProtection = false);
01586 
01596     void KeySetLeftAuto(kFCurveIndex pIndex, kFCurveDouble pValue); 
01597 
01604     KFCurveTangeantInfo KeyGetLeftDerivativeInfo(kFCurveIndex pIndex);
01605 
01617     void KeySetLeftDerivativeInfo(kFCurveIndex pIndex, KFCurveTangeantInfo pValue, bool pForceDerivative = false);
01618 
01619 
01629     void KeyIncLeftDerivative(kFCurveIndex pIndex, kFCurveDouble pInc);
01630 
01637     kFCurveDouble KeyGetRightDerivative(kFCurveIndex pIndex);
01638 
01648     void KeySetRightDerivative(kFCurveIndex pIndex, kFCurveDouble pValue);
01649 
01657     kFCurveDouble KeyGetRightAuto(kFCurveIndex pIndex, bool pApplyOvershootProtection = false);
01658 
01668     void KeySetRightAuto(kFCurveIndex pIndex, kFCurveDouble pValue);
01669 
01670 
01677     KFCurveTangeantInfo KeyGetRightDerivativeInfo(kFCurveIndex pIndex);
01678 
01689     void KeySetRightDerivativeInfo(kFCurveIndex pIndex, KFCurveTangeantInfo pValue, bool pForceDerivative = false);
01690 
01691 
01701     void KeyIncRightDerivative(kFCurveIndex pIndex, kFCurveDouble pInc);
01702 
01706     kFCurveDouble KeyGetRightBezierTangeant(kFCurveIndex pIndex);
01707 
01717     void KeySetLeftBezierTangeant(kFCurveIndex pIndex, kFCurveDouble pValue);
01718 
01722     kFCurveDouble KeyGetLeftBezierTangeant(kFCurveIndex pIndex);
01723 
01733     void KeySetRightBezierTangeant(kFCurveIndex pIndex, kFCurveDouble pValue);
01734 
01735 
01744     void KeyMultDerivative(kFCurveIndex pIndex, kFCurveDouble pMultValue);
01745 
01752     bool KeyIsLeftTangeantWeighted(kFCurveIndex pIndex) const;
01753 
01760     bool KeyIsRightTangeantWeighted(kFCurveIndex pIndex) const;
01761 
01769     void   KeySetLeftTangeantWeightedMode( kFCurveIndex pIndex, bool pWeighted);
01770 
01778     void   KeySetRightTangeantWeightedMode( kFCurveIndex pIndex, bool pWeighted);
01779 
01786     kFCurveDouble KeyGetLeftTangeantWeight(kFCurveIndex pIndex) const;
01787 
01794     kFCurveDouble KeyGetRightTangeantWeight(kFCurveIndex pIndex) const;
01795 
01808     void   KeySetLeftTangeantWeight( kFCurveIndex pIndex, kFCurveDouble pWeight, bool pAdjustTan = false );
01809 
01822     void   KeySetRightTangeantWeight( kFCurveIndex pIndex, kFCurveDouble pWeight, bool pAdjustTan = false  );
01823 
01830     bool KeyIsLeftTangeantVelocity(kFCurveIndex pIndex) const;
01831 
01838     bool KeyIsRightTangeantVelocity(kFCurveIndex pIndex) const;
01839 
01847     void   KeySetLeftTangeantVelocityMode( kFCurveIndex pIndex, bool pVelocity );
01848 
01856     void   KeySetRightTangeantVelocityMode( kFCurveIndex pIndex, bool pVelocity);
01857 
01864     kFCurveDouble KeyGetLeftTangeantVelocity(kFCurveIndex pIndex) const;
01865 
01872     kFCurveDouble KeyGetRightTangeantVelocity(kFCurveIndex pIndex) const;
01873 
01882     void   KeySetLeftTangeantVelocity( kFCurveIndex pIndex, kFCurveDouble pVelocity );
01883 
01892     void   KeySetRightTangeantVelocity( kFCurveIndex pIndex, kFCurveDouble pVelocity );
01893 
01895 
01907 
01911     KFBX_FCURVE_INLINE void SetPreExtrapolation(kFCurveExtrapolationMode pExtrapolation);
01912 
01914     KFBX_FCURVE_INLINE kFCurveExtrapolationMode GetPreExtrapolation() const;
01915 
01920     KFBX_FCURVE_INLINE void SetPreExtrapolationCount(kULong pCount);
01921 
01926     KFBX_FCURVE_INLINE kULong GetPreExtrapolationCount() const;
01927 
01931     KFBX_FCURVE_INLINE void SetPostExtrapolation(kFCurveExtrapolationMode pExtrapolation);
01932 
01934     KFBX_FCURVE_INLINE kFCurveExtrapolationMode GetPostExtrapolation() const;
01935 
01940     KFBX_FCURVE_INLINE void SetPostExtrapolationCount(kULong pCount);
01941 
01946     KFBX_FCURVE_INLINE kULong GetPostExtrapolationCount() const;
01947 
01954     int KeyGetCountAll() const;
01955 
01967     double KeyFindAll(KTime pTime, kFCurveIndex* pLast = NULL);
01968 
01970 
01975 
01988     kFCurveDouble Evaluate (KTime pTime, kFCurveIndex* pLast = NULL);
01989 
01999     kFCurveDouble EvaluateIndex( double pIndex);
02000 
02009     kFCurveDouble EvaluateLeftDerivative (KTime pTime, kFCurveIndex* pLast = NULL);
02010 
02019     kFCurveDouble EvaluateRightDerivative (KTime pTime, kFCurveIndex* pLast = NULL);
02020 
02029     int FindPeaks(kFCurveIndex pLeftKeyIndex, KTime& pPeakTime1, KTime& pPeakTime2);
02030 
02039     int FindPeaks(kFCurveIndex pLeftKeyIndex, kFCurveDouble& pPeak1, kFCurveDouble& pPeak2);
02040 
02051     int FindPeaks(kFCurveIndex pLeftKeyIndex, KTime& pPeakTime1, kFCurveDouble& pPeak1, KTime& pPeakTime2, kFCurveDouble& pPeak2);
02052 
02058     void KeyGetPeriods(KTime& pAveragePeriod, KTime& pMinPeriod, KTime& pMaxPeriod);
02059 
02061 
02066 
02073     HKFCurve Copy(KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE);
02074 
02081     void CopyFrom(KFCurve& pSource, bool pWithKeys = true);
02082 
02091     void Replace(HKFCurve pSource, KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE, bool pUseExactGivenSpan = false, bool pKeyStartEndOnNoKey = true, KTime pTimeSpanOffset = KTIME_ZERO );
02092 
02105     void ReplaceForQuaternion(HKFCurve pSource, KTime pStart, KTime pStop, kFCurveDouble pScaleStart, kFCurveDouble pScaleStop, bool pUseExactGivenSpan = false, bool pKeyStartEndOnNoKey = true, KTime pTimeSpanOffset = KTIME_ZERO );
02106 
02125     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 );   
02126 
02139     void Insert(HKFCurve pSource, KTime pInsertTime, kFCurveDouble pFirstKeyLeftDerivative, bool pFirstKeyIsWeighted = false, kFCurveDouble pFirstKeyWeight = KFCURVE_DEFAULT_WEIGHT);
02140 
02150     void Insert(HKFCurve pSource, KTime pInsertTime, KFCurveTangeantInfo pFirstKeyLeftDerivative );
02151 
02161     bool Delete(kFCurveIndex pStartIndex , kFCurveIndex pStopIndex);                                    
02162 
02170     bool Delete (KTime pStart = KTIME_MINUS_INFINITE, KTime pStop = KTIME_INFINITE, bool pInclusive = false);
02171 
02176     bool IsKeyInterpolationPureCubicAuto(kFCurveIndex pKeyIndex);
02177 
02185     void ExtractKeysIndex( KArrayTemplate<int> &pArray, int pMinIndex, int pMaxIndex, double pMinValue =  -K_DOUBLE_MAX, double pMaxValue =  K_DOUBLE_MAX);
02186 
02188 
02190     //
02191     //  WARNING!
02192     //
02193     //  Anything beyond these lines may not be documented accurately and is 
02194     //  subject to change without notice.
02195     //
02197 
02198 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02199     typedef enum {
02200         V7 = 4007,
02201         V6 = 4005,
02202         V5 = 4004
02203     } FbxStoreVersionID;
02204 
02205     bool    FbxStore (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = true, FbxStoreVersionID pVersionID = V7 );
02206     bool    FbxRetrieve (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false );
02207     bool    FbxInternalRetrieve (KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false );
02208 
02209     void    FbxStorePriKeyAndAttrArrays(KFbx* pFbx);
02210     void    FbxRetrievePriKeyAndAttrArrays(KFbx* pFbx);
02211     void    FbxRetrievePrePostExtrapolation(KFbx* pFbx);
02212 
02213     double CandidateEvaluate (KTime pTime, kFCurveIndex* pLast = NULL);
02214     bool CandidateClear ();
02215     bool CandidateSet (KTime pTime, double pValue);
02216     bool IsCandidate ();
02217     double CandidateGet ();
02218     KTime CandidateGetTime ();
02219 
02220     bool IsLocked() const;
02221     bool IsLockedByLayer() const;
02222     bool IsLockedByProperty() const;
02223     void SetLockedByLayer(bool pLocked);
02224     void SetLockedByProperty(bool pLocked);
02225 
02226     bool CandidateKey
02227         (
02228         kFCurveIndex    *pLast              = NULL, 
02229         int pInterpolation = KFCURVE_INTERPOLATION_CUBIC, 
02230         int pTanMode = KFCURVE_TANGEANT_USER, 
02231         int pContinuity = KFCURVE_CONTINUITY,
02232         bool            pTangeantOverride   = true,
02233         KTime           pCandidateTime      = KTIME_INFINITE,
02234         double          pKeyIndexTolerance  = 0.0
02235         );
02236 
02237     bool NormalsSeemsToComeFromAPlot();
02238 
02239     void SetWasData (int pType);
02240     int GetWasData () const;
02241     int GuessWasData (KTime* pStart = NULL, KTime* pStep = NULL);
02242 
02243     void KeyTangeantHide ();
02244 
02245     int GetUpdateId () const;
02246     int GetValuesUpdateId () const;
02247 
02248     void CallbackRegister (kFCurveCallback pCallback, void* pObject);
02249     void CallbackUnregister (kFCurveCallback pCallback, void* pObject);
02250     void CallbackEnable (bool pEnable);
02251     void CallbackClear ();
02252 
02253 public:
02255     static bool sConvertAutoTimeIndepedent;
02256 
02263     void CopyExternalPriKeyAndAttr(void** pSourceFCurveKeysList, int pSourceFCurveKeyCount); 
02264 
02265     KPriFCurveKey** GetPriFCurveKeysList() const { return mFCurveKeysList; }
02266 
02267 private:
02268     void KeyAttrSet(kFCurveIndex pKeyIndex, const KPriFCurveKeyAttr& pKeyAttr);
02269 
02274     void KeyAttrSeparate(kFCurveIndex pKeyIndex);
02275     
02279     KFBX_FCURVE_INLINE void KeyAttrSeparateCheck(kFCurveIndex pKeyIndex);
02280 
02281     /* Control optimization flag, when enable, we will perform KeyAttrShrink() operation
02282      * when call KeyModifyEnd().
02283      */ 
02284     void KeySetOptimizeEnable(bool pEnable); 
02285     void KeySetOptimizeThreshold(int pThreshold);
02286 
02290     void KeyAttrShrink(kFCurveIndex pStartIndex, kFCurveIndex pStopIndex);
02291 
02292     void IncrementUpdateId(int pInc);
02293     void CallbackAddEvent (int pWhat, int pIndexStart);
02294 
02295     int MapIndexAll (int pIndex, int &pWhere);
02296     void InitBuffers (int pKeyCount, bool pResetKeyCount = false );
02297 
02298     bool CheckCurve();
02299     void IsClamped( int pIndex, bool &pLeftClamped, bool &pRightClamped ) const; // Return true if the specified key is an auto clamp that is currently clamped
02300 
02301 public:
02306     static void AllocateGlobals();
02307 
02312     static void FreeGlobals();
02313 
02314 public:
02315     static  KFCurveKeyAttrManager*  mGlobalKeyAttrMemoryPool;
02316     // Recording Memory global var
02317     static  kULong                  mGlobalRecordingMemory;
02318     static  KMemoryBlockQueue*      mGlobalKeyBufferQueue;
02319 
02320 private:
02321 
02322     float mColor[3];
02323 
02324     kFCurveDouble mValue;
02325 
02326     int mUpdateId;
02327     int mFlags;
02328     int mOptimizationThreshold;
02329     int mKeyModifyGuard;
02330 
02331     KPriFCurveKey** mFCurveKeysList;
02332 
02333     int mFCurveKeyCount;    
02334     int mFCurveKeySize; 
02335     int mFCurveLastBlockIndex;  
02336 
02337 
02338     kUInt mPreExtrapolation;
02339     kULong mPreExtrapolationCount;
02340     kUInt mPostExtrapolation;
02341     kULong mPostExtrapolationCount;
02342 
02343     int mWasType;
02344 
02345     kFCurveIndex mLastSearchIndex;
02346 
02347     KTime mCandidateTime;
02348     kFCurveDouble mCandidateValue;
02349 
02350     KFCurveEvent mEvent;
02351     KArrayUL mCallbackFunctions;   // no delete on object must use array ul
02352     KArrayUL mCallbackObjects;     // no delete on object must use array ul
02353 
02354     KFBX_FCURVE_INLINE KPriFCurveKey* InternalPriKeyGetPtr (kFCurveIndex pIndex) const;
02355     KFBX_FCURVE_INLINE KPriFCurveKeyAttr* InternalPriKeyAttrGetPtr(kFCurveIndex pIndex) const;
02356 
02357 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
02358 
02359 };
02360 
02361 // Allocate memory blocks for fcurve to give room for recording.
02362 KFBX_DLL void KFCURVE_SetFCurveRecordMemoryBlockCount ( int pBlockCount );
02363 KFBX_DLL int KFCURVE_GetFCurveMemoryBlockSize ( );
02364 KFBX_DLL void KFCURVE_ClearMemoryBlockQueue ();
02365 
02366 //
02367 // class KFCurveEvent
02368 //
02369 KFBX_FCURVE_INLINE void KFCurveEvent::Clear () 
02370 {
02371     mType = KFCURVEEVENT_NONE;
02372     mKeyIndexStart = mKeyIndexStop=-1; 
02373     mEventCount = 0; 
02374 }
02375 
02376 
02377 KFBX_FCURVE_INLINE void KFCurveEvent::Add (int pWhat, int pIndex) 
02378 {       
02379     mType |= pWhat;
02380     mEventCount++;
02381     if ( (pIndex<mKeyIndexStart) || (mKeyIndexStart==-1)) 
02382     {
02383         mKeyIndexStart = pIndex;
02384     }
02385     if (pIndex>mKeyIndexStop) 
02386     {
02387         mKeyIndexStop = pIndex;
02388     }
02389 }
02390 
02391 //
02392 //  class KFCurveKey
02393 //
02394 KFBX_FCURVE_INLINE KFCurveTangeantInfo::KFCurveTangeantInfo()
02395 {
02396     mDerivative = 0.0;
02397     mWeight     = KFCURVE_DEFAULT_WEIGHT;
02398     mWeighted   = false;
02399     mVelocity   = KFCURVE_DEFAULT_VELOCITY;
02400     mHasVelocity= false;
02401     mAuto       = 0.0;
02402 }
02403 
02404 KFBX_FCURVE_INLINE KFCurveKey::KFCurveKey(const KPriFCurveKey& pKey, const KPriFCurveKeyAttr& pAttr)
02405 {
02406     mTime = pKey.mTime;
02407     mValue = pKey.mValue;
02408     mFlags = pAttr.mFlags;
02409     mData[0] = pAttr.mData[0];
02410     mData[1] = pAttr.mData[1];
02411 #ifdef KFCURVE_FLOAT
02412     mData[2] = pAttr.mData[2];
02413     mData[3] = pAttr.mData[3];
02414 #else
02415     mWeight[0] = pAttr.mWeight[0];
02416     mWeight[1] = pAttr.mWeight[1];
02417     mVelocity[0] = pAttr.mVelocity[0];
02418     mVelocity[1] = pAttr.mVelocity[1];
02419 #endif
02420 }
02421 
02422 KFBX_FCURVE_INLINE KPriFCurveKeyAttr KFCurveKey::GetKeyAttr() const
02423 {
02424     KPriFCurveKeyAttr lKeyAttr;
02425     lKeyAttr.mFlags = mFlags;
02426     lKeyAttr.mData[0] = mData[0];
02427     lKeyAttr.mData[1] = mData[1];
02428 #ifdef KFCURVE_FLOAT
02429     lKeyAttr.mData[2] = mData[2];
02430     lKeyAttr.mData[3] = mData[3];
02431 #else
02432     lKeyAttr.mWeight[0] = mWeight[0];
02433     lKeyAttr.mWeight[1] = mWeight[1];
02434     lKeyAttr.mVelocity[0] = mVelocity[0];
02435     lKeyAttr.mVelocity[1] = mVelocity[1];
02436 #endif
02437     return lKeyAttr;
02438 }
02439 
02440 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::Set 
02441 (
02442     kFCurveInterpolation pInterpolation /* = KFCURVE_INTERPOLATION_CUBIC*/, 
02443     kFCurveTangeantMode pTangeantMode /*= KFCURVE_TANGEANT_AUTO*/, 
02444     kFCurveDouble pData0 /*= 0*/, 
02445     kFCurveDouble pData1 /*= 0*/,
02446     kFCurveTangeantWeightMode pTangeantWeightMode /*= KFCURVE_WEIGHT_NONE*/, 
02447     kFCurveDouble pWeight0 /* = KFCURVE_DEFAULT_WEIGHT */,
02448     kFCurveDouble pWeight1 /* = KFCURVE_DEFAULT_WEIGHT */,
02449     kFCurveDouble pVelocity0 /* = KFCURVE_DEFAULT_VELOCITY */,
02450     kFCurveDouble pVelocity1 /* = KFCURVE_DEFAULT_VELOCITY */
02451 )
02452 {
02453     K_ASSERT (pInterpolation != KFCURVE_INTERPOLATION_CUBIC || pTangeantMode != KFCURVE_TANGEANT_TCB);
02454 
02455     SetInterpolation (pInterpolation);
02456     SetTangeantMode (pTangeantMode);
02457     SetDataDouble (KFCURVEKEY_RIGHT_SLOPE, pData0);
02458     SetDataDouble (KFCURVEKEY_NEXT_LEFT_SLOPE, pData1);
02459 
02460     SetTangeantWeightMode (pTangeantWeightMode);
02461     SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, pWeight0);
02462     SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, pWeight1);
02463 
02464     SetDataDouble (KFCURVEKEY_RIGHT_VELOCITY, pVelocity0);
02465     SetDataDouble (KFCURVEKEY_NEXT_LEFT_VELOCITY, pVelocity1);
02466 
02467     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE); 
02468 }
02469 
02470 KFBX_FCURVE_INLINE void KPriFCurveKey::Set 
02471 (
02472     KTime pTime, 
02473     kFCurveDouble pValue
02474 )
02475 {
02476     SetTime (pTime);
02477     SetValue (pValue);
02478 }
02479 
02480 //
02481 //  class KFCurveKey
02482 //
02483 
02484 KFBX_FCURVE_INLINE void KFCurveKey::Set 
02485     (
02486     KTime pTime, 
02487     kFCurveDouble pValue, 
02488     kFCurveInterpolation pInterpolation /* = KFCURVE_INTERPOLATION_CUBIC*/, 
02489     kFCurveTangeantMode pTangeantMode /*= KFCURVE_TANGEANT_AUTO*/, 
02490     kFCurveDouble pData0 /*= 0*/, 
02491     kFCurveDouble pData1 /*= 0*/,
02492     kFCurveTangeantWeightMode pTangeantWeightMode /*= KFCURVE_WEIGHT_NONE*/, 
02493     kFCurveDouble pWeight0 /* = KFCURVE_DEFAULT_WEIGHT */,
02494     kFCurveDouble pWeight1 /* = KFCURVE_DEFAULT_WEIGHT */,
02495     kFCurveDouble pVelocity0 /* = KFCURVE_DEFAULT_VELOCITY */,
02496     kFCurveDouble pVelocity1 /* = KFCURVE_DEFAULT_VELOCITY */
02497     )
02498 {
02499     K_ASSERT (pInterpolation != KFCURVE_INTERPOLATION_CUBIC || pTangeantMode != KFCURVE_TANGEANT_TCB);
02500 
02501     SetTime (pTime);
02502     SetValue (pValue);
02503     SetInterpolation (pInterpolation);
02504     SetTangeantMode (pTangeantMode);
02505     SetDataDouble (KFCURVEKEY_RIGHT_SLOPE, pData0);
02506     SetDataDouble (KFCURVEKEY_NEXT_LEFT_SLOPE, pData1);
02507 
02508     SetTangeantWeightMode (pTangeantWeightMode);
02509     SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, pWeight0);
02510     SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, pWeight1);
02511 
02512     SetDataDouble (KFCURVEKEY_RIGHT_VELOCITY, pVelocity0);
02513     SetDataDouble (KFCURVEKEY_NEXT_LEFT_VELOCITY, pVelocity1);
02514 
02515     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02516 }
02517 
02518 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTCB (float pData1/*=0.0f*/, float pData2/*=0.0f*/, float pData3/*=0.0f*/)
02519 {
02520     SetInterpolation (KFCURVE_INTERPOLATION_CUBIC);
02521     SetTangeantMode (KFCURVE_TANGEANT_TCB);
02522     SetDataFloat (KFCURVEKEY_TCB_TENSION, pData1);
02523     SetDataFloat (KFCURVEKEY_TCB_CONTINUITY, pData2);
02524     SetDataFloat (KFCURVEKEY_TCB_BIAS, pData3);
02525     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02526 }
02527 
02528 KFBX_FCURVE_INLINE void KFCurveKey::SetTCB (KTime pTime, kFCurveDouble pValue, float pData1/*=0.0f*/, float pData2/*=0.0f*/, float pData3/*=0.0f*/)
02529 {
02530     SetTime (pTime);
02531     SetValue (pValue);
02532     SetInterpolation (KFCURVE_INTERPOLATION_CUBIC);
02533     SetTangeantMode (KFCURVE_TANGEANT_TCB);
02534     SetDataFloat (KFCURVEKEY_TCB_TENSION, pData1);
02535     SetDataFloat (KFCURVEKEY_TCB_CONTINUITY, pData2);
02536     SetDataFloat (KFCURVEKEY_TCB_BIAS, pData3);
02537     SetTangeantVisibility (KFCURVE_TANGEANT_SHOW_NONE);
02538 }
02539 
02540 
02541 KFBX_FCURVE_INLINE void KFCurveKey::Set (KFCurveKey& iSource)
02542 {
02543     memcpy(this, &iSource, sizeof(KFCurveKey));
02544 }
02545 
02546 KFBX_FCURVE_INLINE kFCurveInterpolation KPriFCurveKeyAttr::GetInterpolation() const
02547 {
02548     return mFlags & KFCURVE_INTERPOLATION_ALL;
02549 }
02550 
02551 KFBX_FCURVE_INLINE kFCurveInterpolation KFCurveKey::GetInterpolation () const
02552 {
02553     return mFlags & KFCURVE_INTERPOLATION_ALL;
02554 }
02555 
02556 
02557 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetInterpolation (kFCurveInterpolation pInterpolation)   
02558 {
02559     K_ASSERT_MSG(   (pInterpolation == KFCURVE_INTERPOLATION_CUBIC) || 
02560         (pInterpolation == KFCURVE_INTERPOLATION_LINEAR) ||
02561         (pInterpolation == KFCURVE_INTERPOLATION_CONSTANT) ,"Wrong interpolation type." );
02562 
02563     if( (((mFlags & KFCURVE_INTERPOLATION_ALL)!=KFCURVE_INTERPOLATION_CUBIC)) && pInterpolation == KFCURVE_INTERPOLATION_CUBIC )
02564     {
02565         // Clear weighting information
02566         SetTangeantWeightMode( KFCURVE_WEIGHTED_NONE);
02567         SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02568         SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02569 
02570         SetTangeantVelocityMode(KFCURVE_VELOCITY_NONE);
02571         SetDataDouble( KFCURVEKEY_RIGHT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02572         SetDataDouble( KFCURVEKEY_NEXT_LEFT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02573     }
02574 
02575     mFlags = (mFlags & ~KFCURVE_INTERPOLATION_ALL) | (pInterpolation & KFCURVE_INTERPOLATION_ALL); 
02576 }
02577 
02578 
02579 KFBX_FCURVE_INLINE void KFCurveKey::SetInterpolation (kFCurveInterpolation pInterpolation)  
02580 {
02581     K_ASSERT_MSG(   (pInterpolation == KFCURVE_INTERPOLATION_CUBIC) || 
02582                     (pInterpolation == KFCURVE_INTERPOLATION_LINEAR) ||
02583                     (pInterpolation == KFCURVE_INTERPOLATION_CONSTANT) ,"Wrong interpolation type." );
02584 
02585     if( (((mFlags & KFCURVE_INTERPOLATION_ALL)!=KFCURVE_INTERPOLATION_CUBIC)) && pInterpolation == KFCURVE_INTERPOLATION_CUBIC )
02586     {
02587         // Clear weighting information
02588         SetTangeantWeightMode( KFCURVE_WEIGHTED_NONE);
02589         SetDataDouble (KFCURVEKEY_RIGHT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02590         SetDataDouble (KFCURVEKEY_NEXT_LEFT_WEIGHT, KFCURVE_DEFAULT_WEIGHT);
02591 
02592         SetTangeantVelocityMode(KFCURVE_VELOCITY_NONE);
02593         SetDataDouble( KFCURVEKEY_RIGHT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02594         SetDataDouble( KFCURVEKEY_NEXT_LEFT_VELOCITY, KFCURVE_DEFAULT_VELOCITY);
02595     }
02596 
02597     mFlags = (mFlags & ~KFCURVE_INTERPOLATION_ALL) | (pInterpolation & KFCURVE_INTERPOLATION_ALL); 
02598 }
02599 
02600 KFBX_FCURVE_INLINE kFCurveConstantMode KPriFCurveKeyAttr::GetConstantMode() const
02601 {
02602     return mFlags & KFCURVE_CONSTANT_ALL;
02603 }
02604 
02605 KFBX_FCURVE_INLINE kFCurveConstantMode KFCurveKey::GetConstantMode() const
02606 {
02607     return mFlags & KFCURVE_CONSTANT_ALL;
02608 }
02609 
02610 KFBX_FCURVE_INLINE kFCurveTangeantMode KPriFCurveKeyAttr::GetTangeantMode( bool pIncludeOverrides ) const
02611 {
02612     if( pIncludeOverrides )
02613     {
02614         return mFlags & KFCURVE_TANGEANT_ALL;
02615     }
02616     else
02617     {
02618         return mFlags & KFCURVE_TANGEANT_TYPE_MASK;
02619     }
02620 }
02621 
02622 KFBX_FCURVE_INLINE kFCurveTangeantMode KFCurveKey::GetTangeantMode( bool pIncludeOverrides ) const
02623 {
02624     if( pIncludeOverrides )
02625     {
02626         return mFlags & KFCURVE_TANGEANT_ALL;
02627     }
02628     else
02629     {
02630         return mFlags & KFCURVE_TANGEANT_TYPE_MASK;
02631     }
02632 }
02633 
02634 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetConstantMode (kFCurveConstantMode pMode)          
02635 {
02636     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) ||
02637         (pMode == KFCURVE_CONSTANT_STANDARD) ||
02638         (pMode == KFCURVE_CONSTANT_NEXT),"Wrong constant mode.");
02639 
02640     mFlags = (mFlags & ~KFCURVE_CONSTANT_ALL) | (pMode & KFCURVE_CONSTANT_ALL); 
02641 }
02642 
02643 KFBX_FCURVE_INLINE void KFCurveKey::SetConstantMode (kFCurveConstantMode pMode)         
02644 {
02645     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) ||
02646                     (pMode == KFCURVE_CONSTANT_STANDARD) ||
02647                     (pMode == KFCURVE_CONSTANT_NEXT),"Wrong constant mode.");
02648 
02649     mFlags = (mFlags & ~KFCURVE_CONSTANT_ALL) | (pMode & KFCURVE_CONSTANT_ALL); 
02650 }
02651 
02652 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantMode (kFCurveTangeantMode pTangeant, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)            
02653 {
02654     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) || !(pTangeant & ~KFCURVE_TANGEANT_ALL), "Wrong tangeant mode." );
02655     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) || !(pTangeant & ~KFCURVE_CONSTANT_ALL), "Wrong tangeant mode." );
02656 
02657     // Convert Auto to Time-Independent.
02658     if (! pIgnoreAutoTimeIndepedentConversion && KFCurve::sConvertAutoTimeIndepedent && (mFlags & KFCURVE_INTERPOLATION_CUBIC) && (pTangeant & KFCURVE_TANGEANT_AUTO))
02659     {
02660         pTangeant = pTangeant | KFCURVE_GENERIC_TIME_INDEPENDENT;
02661     }
02662 
02663     mFlags = (mFlags & ~(KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL)) | (pTangeant & (KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL) ); 
02664 }
02665 
02666 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantMode (kFCurveTangeantMode pTangeant, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)           
02667 {
02668     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) || !(pTangeant & ~KFCURVE_TANGEANT_ALL), "Wrong tangeant mode." );
02669     K_ASSERT_MSG( (GetInterpolation() != KFCURVE_INTERPOLATION_CONSTANT) || !(pTangeant & ~KFCURVE_CONSTANT_ALL), "Wrong tangeant mode." );
02670 
02671     // Convert Auto to Time-Independent.
02672     if (! pIgnoreAutoTimeIndepedentConversion && KFCurve::sConvertAutoTimeIndepedent && (mFlags & KFCURVE_INTERPOLATION_CUBIC) && (pTangeant & KFCURVE_TANGEANT_AUTO))
02673     {
02674         pTangeant = pTangeant | KFCURVE_GENERIC_TIME_INDEPENDENT;
02675     }
02676 
02677     mFlags = (mFlags & ~(KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL)) | (pTangeant & (KFCURVE_TANGEANT_ALL|KFCURVE_CONSTANT_ALL) ); 
02678 }
02679 
02680 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KPriFCurveKeyAttr::GetTangeantWeightMode() const
02681 {
02682     return mFlags & KFCURVE_WEIGHTED_ALL;
02683 }
02684 
02685 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KFCurveKey::GetTangeantWeightMode() const
02686 {
02687     return mFlags & KFCURVE_WEIGHTED_ALL;
02688 }
02689 
02690 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantWeightMode(kFCurveTangeantWeightMode pTangent, kFCurveTangeantWeightMode pMask /* KFCURVE_WEIGHTED_ALL */ )
02691 {
02692     pMask &= KFCURVE_WEIGHTED_ALL;
02693     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02694 }
02695 
02696 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantWeightMode(kFCurveTangeantWeightMode pTangent, kFCurveTangeantWeightMode pMask /* KFCURVE_WEIGHTED_ALL */ )
02697 {
02698 
02699     pMask &= KFCURVE_WEIGHTED_ALL;
02700     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02701 }
02702 
02703 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KPriFCurveKeyAttr::GetTangeantVelocityMode() const
02704 {
02705     return mFlags & KFCURVE_VELOCITY_ALL;
02706 }
02707 
02708 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KFCurveKey::GetTangeantVelocityMode() const
02709 {
02710     return mFlags & KFCURVE_VELOCITY_ALL;
02711 }
02712 
02713 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight ) 
02714 {
02715 #ifdef KFCURVE_FLOAT
02716     TangentWeightAndAdjustTangent(pIndex, pWeight, mData);
02717 #else
02718     TangentWeightAndAdjustTangent(pIndex, pWeight, mData, mWeight);
02719 #endif
02720 }
02721 
02722 KFBX_FCURVE_INLINE void KFCurveKey::SetTangentWeightAndAdjustTangent( EKFCurveDataIndex pIndex, kFCurveDouble pWeight ) 
02723 {
02724 #ifdef KFCURVE_FLOAT
02725     TangentWeightAndAdjustTangent(pIndex, pWeight, mData);
02726 #else
02727     TangentWeightAndAdjustTangent(pIndex, pWeight, mData, mWeight);
02728 #endif
02729 }
02730 
02731 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangent, kFCurveTangeantVelocityMode pMask /* KFCURVE_VELOCITY_ALL */ )
02732 {
02733     pMask &= KFCURVE_VELOCITY_ALL;
02734     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02735 }
02736 
02737 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantVelocityMode(kFCurveTangeantVelocityMode pTangent, kFCurveTangeantVelocityMode pMask /* KFCURVE_VELOCITY_ALL */ )
02738 {
02739     pMask &= KFCURVE_VELOCITY_ALL;
02740     mFlags = (mFlags & ~pMask) | (pTangent & pMask); 
02741 }
02742 
02743 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetTangeantVisibility (kFCurveTangeantVisibility pVisibility)                
02744 {
02745     K_ASSERT_MSG(   (pVisibility == KFCURVE_TANGEANT_SHOW_NONE) || 
02746         (pVisibility == KFCURVE_TANGEANT_SHOW_LEFT) ||
02747         (pVisibility == KFCURVE_TANGEANT_SHOW_RIGHT) ||
02748         (pVisibility == KFCURVE_TANGEANT_SHOW_BOTH) ,"Wrong visibility type." );
02749    
02750     mFlags = (mFlags & ~KFCURVE_TANGEANT_SHOW_BOTH) | (pVisibility & KFCURVE_TANGEANT_SHOW_BOTH); 
02751 }
02752 
02753 KFBX_FCURVE_INLINE void KFCurveKey::SetTangeantVisibility (kFCurveTangeantVisibility pVisibility)               
02754 {
02755     K_ASSERT_MSG(   (pVisibility == KFCURVE_TANGEANT_SHOW_NONE) || 
02756         (pVisibility == KFCURVE_TANGEANT_SHOW_LEFT) ||
02757         (pVisibility == KFCURVE_TANGEANT_SHOW_RIGHT) ||
02758         (pVisibility == KFCURVE_TANGEANT_SHOW_BOTH) ,"Wrong visibility type." );
02759 
02760     mFlags = (mFlags & ~KFCURVE_TANGEANT_SHOW_BOTH) | (pVisibility & KFCURVE_TANGEANT_SHOW_BOTH); 
02761 }
02762 
02763 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KPriFCurveKeyAttr::GetTangeantVisibility ()  const
02764 {
02765     return mFlags & KFCURVE_TANGEANT_SHOW_BOTH;
02766 }
02767 
02768 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KFCurveKey::GetTangeantVisibility () const
02769 {
02770     return mFlags & KFCURVE_TANGEANT_SHOW_BOTH;
02771 }
02772 
02773 KFBX_FCURVE_INLINE kFCurveDouble KPriFCurveKeyAttr::GetDataDouble (EKFCurveDataIndex pIndex)  const
02774 {
02775     if( pIndex < KFCURVEKEY_WEIGHTS )
02776     {
02777         return mData[pIndex];
02778     }
02779     else
02780     {
02781         #ifdef KFCURVE_FLOAT
02782             return (kFCurveDouble)(((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS])/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02783         #else       
02784             return (kFCurveDouble)mWeight[pIndex-KFCURVEKEY_WEIGHTS]/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02785         #endif
02786     }
02787 }
02788 
02789 KFBX_FCURVE_INLINE kFCurveDouble KFCurveKey::GetDataDouble (EKFCurveDataIndex pIndex) const
02790 {
02791     if( pIndex < KFCURVEKEY_WEIGHTS )
02792     {
02793         return mData[pIndex];
02794     }
02795     else
02796     {
02797         #ifdef KFCURVE_FLOAT
02798             return (kFCurveDouble)(((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS])/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02799         #else       
02800             return (kFCurveDouble)mWeight[pIndex-KFCURVEKEY_WEIGHTS]/(kFCurveDouble)KFCURVE_WEIGHT_DIVIDER;
02801         #endif
02802     }
02803 }
02804 
02805 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetDataDouble (EKFCurveDataIndex pIndex, kFCurveDouble pValue) 
02806 {
02807     if( pIndex < KFCURVEKEY_RIGHT_WEIGHT )
02808     {
02809         mData[pIndex] = pValue;
02810     }
02811     else
02812     {
02813         if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue > KFCURVE_MAX_WEIGHT )
02814         {
02815             pValue = KFCURVE_MAX_WEIGHT;
02816         }
02817         else if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue < KFCURVE_MIN_WEIGHT )
02818         {
02819             pValue = KFCURVE_MIN_WEIGHT;
02820         }
02821 
02822         #ifdef KFCURVE_FLOAT
02823             (((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS]) = (kInt16)(pValue*KFCURVE_WEIGHT_DIVIDER);
02824         #else       
02825             mWeight[pIndex-KFCURVEKEY_WEIGHTS] = pValue*KFCURVE_WEIGHT_DIVIDER;
02826         #endif
02827     }
02828 }
02829 
02830 KFBX_FCURVE_INLINE void KFCurveKey::SetDataDouble (EKFCurveDataIndex pIndex, kFCurveDouble pValue) 
02831 {
02832     if( pIndex < KFCURVEKEY_RIGHT_WEIGHT )
02833     {
02834         mData[pIndex] = pValue;
02835     }
02836     else
02837     {
02838         if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue > KFCURVE_MAX_WEIGHT )
02839         {
02840             pValue = KFCURVE_MAX_WEIGHT;
02841         }
02842         else if( (pIndex == KFCURVEKEY_RIGHT_WEIGHT || pIndex == KFCURVEKEY_NEXT_LEFT_WEIGHT ) && pValue < KFCURVE_MIN_WEIGHT )
02843         {
02844             pValue = KFCURVE_MIN_WEIGHT;
02845         }
02846 
02847         #ifdef KFCURVE_FLOAT
02848             (((kInt16*)(&mData[KFCURVEKEY_WEIGHTS]))[pIndex-KFCURVEKEY_WEIGHTS]) = (kInt16)(pValue*KFCURVE_WEIGHT_DIVIDER);
02849         #else       
02850             mWeight[pIndex-KFCURVEKEY_WEIGHTS] = pValue*KFCURVE_WEIGHT_DIVIDER;
02851         #endif
02852     }
02853 }
02854 
02855 KFBX_FCURVE_INLINE float KPriFCurveKeyAttr::GetDataFloat (EKFCurveDataIndex pIndex)  const
02856 {
02857     return ( (float *)&mData[0])[pIndex];
02858 }
02859 
02860 KFBX_FCURVE_INLINE float KFCurveKey::GetDataFloat (EKFCurveDataIndex pIndex)  const
02861 {
02862     return ( (float *)&mData[0])[pIndex];
02863 }
02864 
02865 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetDataFloat (EKFCurveDataIndex pIndex, float pValue) 
02866 {
02867     ((float *)&mData[0])[pIndex] = pValue;
02868 }
02869 
02870 KFBX_FCURVE_INLINE void KFCurveKey::SetDataFloat (EKFCurveDataIndex pIndex, float pValue) 
02871 {
02872     ((float *)&mData[0])[pIndex] = pValue;
02873 }
02874 
02875 KFBX_FCURVE_INLINE float* KPriFCurveKeyAttr::GetDataPtr() const
02876 {
02877     return (float*)mData;
02878 }
02879 
02880 KFBX_FCURVE_INLINE float* KFCurveKey::GetDataPtr() const
02881 {
02882     return (float*)mData;
02883 }
02884 
02885 KFBX_FCURVE_INLINE kFCurveDouble KPriFCurveKey::GetValue ()  const
02886 {
02887     return mValue;
02888 }
02889 
02890 KFBX_FCURVE_INLINE kFCurveDouble KFCurveKey::GetValue ()  const
02891 {
02892     return mValue;
02893 }
02894 
02895 
02896 KFBX_FCURVE_INLINE void KPriFCurveKey::SetValue (kFCurveDouble pValue) 
02897 {
02898     mValue=pValue;
02899 }
02900 
02901 KFBX_FCURVE_INLINE void KFCurveKey::SetValue (kFCurveDouble pValue) 
02902 {
02903     mValue=pValue;
02904 }
02905 
02906 KFBX_FCURVE_INLINE void KPriFCurveKey::IncValue (kFCurveDouble pValue) 
02907 {
02908     mValue+=pValue;
02909 }
02910 
02911 KFBX_FCURVE_INLINE void KFCurveKey::IncValue (kFCurveDouble pValue) 
02912 {
02913     mValue+=pValue;
02914 }
02915 
02916 KFBX_FCURVE_INLINE void KPriFCurveKey::MultValue (kFCurveDouble pValue) 
02917 {
02918     mValue*=pValue;
02919 }
02920 
02921 KFBX_FCURVE_INLINE void KFCurveKey::MultValue (kFCurveDouble pValue) 
02922 {
02923     mValue*=pValue;
02924 }
02925 
02926 KFBX_FCURVE_INLINE KTime KPriFCurveKey::GetTime ()  const
02927 {
02928     return mTime;
02929 }
02930 
02931 KFBX_FCURVE_INLINE KTime KFCurveKey::GetTime () const
02932 {
02933     return mTime;
02934 }
02935 
02936 KFBX_FCURVE_INLINE void KPriFCurveKey::SetTime (KTime pTime) 
02937 {
02938     K_ASSERT_MSG( pTime != KTIME_MINUS_INFINITE && 
02939     pTime != KTIME_INFINITE, "Key at infinite!" );
02940 
02941     mTime=pTime;
02942 }
02943 
02944 KFBX_FCURVE_INLINE void KFCurveKey::SetTime (KTime pTime) 
02945 {
02946     K_ASSERT_MSG( pTime != KTIME_MINUS_INFINITE && 
02947         pTime != KTIME_INFINITE, "Key at infinite!" );
02948 
02949     mTime=pTime;
02950 }
02951 
02952 KFBX_FCURVE_INLINE void KPriFCurveKey::IncTime (KTime pTime) 
02953 {
02954     mTime+=pTime;
02955 }
02956 
02957 KFBX_FCURVE_INLINE void KFCurveKey::IncTime (KTime pTime) 
02958 {
02959     mTime+=pTime;
02960 }
02961 
02962 
02963 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetSelected (bool pSelected) 
02964 {
02965     mFlags = pSelected ? (mFlags & ~KFCURVE_SELECT_ALL) | KFCURVE_SELECT_POINT : (mFlags & ~KFCURVE_SELECT_ALL);
02966 }
02967 
02968 KFBX_FCURVE_INLINE void KFCurveKey::SetSelected (bool pSelected) 
02969 {
02970     mFlags = pSelected ? (mFlags & ~KFCURVE_SELECT_ALL) | KFCURVE_SELECT_POINT : (mFlags & ~KFCURVE_SELECT_ALL);
02971 }
02972 
02973 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetSelected () const
02974 {
02975     return (mFlags & KFCURVE_SELECT_POINT) ? true : false;
02976 }
02977 
02978 KFBX_FCURVE_INLINE bool KFCurveKey::GetSelected () const
02979 {
02980     return (mFlags & KFCURVE_SELECT_POINT) ? true : false;
02981 }
02982 
02983 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetMarkedForManipulation (bool pSelected) 
02984 {
02985     mFlags = pSelected ? (mFlags & ~KFCURVE_MARKED_ALL) | KFCURVE_MARKED_FOR_MANIP : (mFlags & ~KFCURVE_MARKED_ALL);
02986 }
02987 
02988 KFBX_FCURVE_INLINE void KFCurveKey::SetMarkedForManipulation (bool pSelected) 
02989 {
02990     mFlags = pSelected ? (mFlags & ~KFCURVE_MARKED_ALL) | KFCURVE_MARKED_FOR_MANIP : (mFlags & ~KFCURVE_MARKED_ALL);
02991 }
02992 
02993 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetMarkedForManipulation () const
02994 {
02995     return (mFlags & KFCURVE_MARKED_FOR_MANIP) ? true : false;
02996 }
02997 
02998 KFBX_FCURVE_INLINE bool KFCurveKey::GetMarkedForManipulation () const
02999 {
03000     return (mFlags & KFCURVE_MARKED_FOR_MANIP) ? true : false;
03001 }
03002 
03003 KFBX_FCURVE_INLINE void KPriFCurveKey::Init()
03004 {
03005     mValue = 0.0;
03006     mTime = KTIME_ZERO;
03007     mAttr = NULL;
03008 }
03009 
03010 KFBX_FCURVE_INLINE void KFCurveKey::Init()
03011 {
03012     mValue = 0.0;
03013     mTime = KTIME_ZERO;
03014     mFlags = 0;
03015 }
03016 
03017 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::SetBreak(bool pVal)
03018 {
03019     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03020         (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03021         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03022         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03023         (GetTangeantMode() == KFCURVE_TANGEANT_USER) ,"Wrong tangeant mode." );
03024 
03025     if(pVal)
03026         mFlags = mFlags |  KFCURVE_GENERIC_BREAK ;
03027     else
03028         mFlags = mFlags & ~KFCURVE_GENERIC_BREAK ;  
03029 
03030 } 
03031 
03032 KFBX_FCURVE_INLINE void KFCurveKey::SetBreak(bool pVal)
03033 {
03034     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03035         (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03036         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03037         (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03038         (GetTangeantMode() == KFCURVE_TANGEANT_USER) ,"Wrong tangent mode." );
03039 
03040     if(pVal)
03041         mFlags = mFlags |  KFCURVE_GENERIC_BREAK ;
03042     else
03043         mFlags = mFlags & ~KFCURVE_GENERIC_BREAK ;  
03044 
03045 } 
03046 
03047 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::GetBreak() const
03048 {
03049     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03050             (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03051             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03052             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03053             (GetTangeantMode() == KFCURVE_TANGEANT_USER)  ,"Wrong tangent mode." );
03054 
03055     if( ((mFlags & KFCURVE_GENERIC_BREAK ) == KFCURVE_GENERIC_BREAK))
03056         return true;
03057     else
03058         return false; 
03059 
03060 }
03061 
03062 KFBX_FCURVE_INLINE bool KFCurveKey::GetBreak() const
03063 {
03064     K_ASSERT_MSG(   (GetInterpolation() != KFCURVE_INTERPOLATION_CUBIC) ||                  
03065             (GetTangeantMode() == KFCURVE_TANGEANT_BREAK) ||
03066             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO)  ||
03067             (GetTangeantMode() == KFCURVE_TANGEANT_AUTO_BREAK)  ||
03068             (GetTangeantMode() == KFCURVE_TANGEANT_USER)  ,"Wrong tangent mode." );
03069 
03070     if( ((mFlags & KFCURVE_GENERIC_BREAK ) == KFCURVE_GENERIC_BREAK))
03071         return true;
03072     else
03073         return false; 
03074 
03075 }
03076 
03077 KFBX_FCURVE_INLINE bool KPriFCurveKeyAttr::IsEqual(const KPriFCurveKeyAttr& pRsh) const
03078 {
03079     // To Modify, don't need to check the data for some Flags. 
03080     return (this == &pRsh) ||
03081         mFlags == pRsh.mFlags &&
03082         mData[0] == pRsh.mData[0] &&
03083         mData[1] == pRsh.mData[1] &&
03084     #ifdef KFCURVE_FLOAT
03085         mData[2] == pRsh.mData[2] &&
03086         mData[3] == pRsh.mData[3];
03087     #else
03088         mWeight[0] == pRsh.mWeight[0] &&
03089         mWeight[1] == pRsh.mWeight[1] &&
03090         mVelocity[0] == pRsh.mVelocity[0] &&
03091         mVelocity[1] == pRsh.mVelocity[1];
03092     #endif
03093 }
03094 
03095 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::IncRefCount()
03096 {
03097     ++mRefCount;
03098 }
03099 
03100 KFBX_FCURVE_INLINE void KPriFCurveKeyAttr::DecRefCount()
03101 {
03102     --mRefCount;
03103 }
03104 
03105 KFBX_FCURVE_INLINE kUInt32 KPriFCurveKeyAttr::GetRefCount() const
03106 {
03107     return mRefCount;
03108 }
03109 //****************************************************************************************
03110 // class KFCurve
03111 //****************************************************************************************
03112 
03113 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::GetValue () const 
03114 {
03115     return mValue;
03116 }
03117 
03118 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03119 KFBX_FCURVE_INLINE void KFCurve::SetPreExtrapolation (kUInt pExtrapolation) 
03120 {
03121     K_ASSERT_MSG(   (pExtrapolation == KFCURVE_EXTRAPOLATION_CONST) || 
03122         (pExtrapolation == KFCURVE_EXTRAPOLATION_REPETITION) ||
03123         (pExtrapolation == KFCURVE_EXTRAPOLATION_MIRROR_REPETITION) ||
03124         (pExtrapolation == KFCURVE_EXTRAPOLATION_KEEP_SLOPE) ,"Wrong extrapolation type." );
03125 
03126     mPreExtrapolation = pExtrapolation; 
03127     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03128 }
03129 #endif
03130 
03131 KFBX_FCURVE_INLINE kUInt KFCurve::GetPreExtrapolation () const 
03132 {
03133     return mPreExtrapolation;
03134 }
03135 
03136 
03137 KFBX_FCURVE_INLINE void KFCurve::SetPreExtrapolationCount (kULong pCount) 
03138 {
03139     mPreExtrapolationCount = pCount; 
03140     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03141 }
03142 
03143 
03144 KFBX_FCURVE_INLINE kULong KFCurve::GetPreExtrapolationCount ()  const
03145 {
03146     return mPreExtrapolationCount;
03147 }
03148 
03149 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03150 
03151 KFBX_FCURVE_INLINE void KFCurve::SetPostExtrapolation (kUInt pExtrapolation) 
03152 {
03153     K_ASSERT_MSG(   (pExtrapolation == KFCURVE_EXTRAPOLATION_CONST) || 
03154         (pExtrapolation == KFCURVE_EXTRAPOLATION_REPETITION) ||
03155         (pExtrapolation == KFCURVE_EXTRAPOLATION_MIRROR_REPETITION) ||
03156         (pExtrapolation == KFCURVE_EXTRAPOLATION_KEEP_SLOPE) ,"Wrong extrapolation type." );
03157 
03158     mPostExtrapolation = pExtrapolation; 
03159     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03160 }
03161 
03162 #endif
03163 
03164 KFBX_FCURVE_INLINE kUInt KFCurve::GetPostExtrapolation () const 
03165 {
03166     return mPostExtrapolation;
03167 }
03168 
03169 
03170 KFBX_FCURVE_INLINE void KFCurve::SetPostExtrapolationCount (kULong pCount) 
03171 {
03172     mPostExtrapolationCount = pCount; 
03173     CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, -1);
03174 }
03175 
03176 
03177 KFBX_FCURVE_INLINE kULong KFCurve::GetPostExtrapolationCount ()  const
03178 {
03179     return mPostExtrapolationCount;
03180 }
03181 
03182 #ifndef DOXYGEN_SHOULD_SKIP_THIS
03183 KFBX_FCURVE_INLINE KPriFCurveKey* KFCurve::InternalPriKeyGetPtr (int pIndex) const
03184 {
03185     K_ASSERT_MSG( pIndex >= 0, "Negative indexes are not recommended." );
03186     K_ASSERT_MSG( mFCurveKeysList && mFCurveKeysList[pIndex / KEY_BLOCK_COUNT], "Accessing unallocated buffer." );
03187 
03188     return mFCurveKeysList[pIndex / KEY_BLOCK_COUNT] + (pIndex % KEY_BLOCK_COUNT);
03189 }
03190 
03191 
03192 KFBX_FCURVE_INLINE KPriFCurveKeyAttr* KFCurve::InternalPriKeyAttrGetPtr(kFCurveIndex pIndex) const
03193 {
03194     #ifdef _DEBUG
03195         KPriFCurveKey* lKey = InternalPriKeyGetPtr(pIndex);
03196         K_ASSERT_MSG(lKey->mAttr != NULL, "Accessing uninitialized keyattr.");
03197         return lKey->mAttr;
03198     #else
03199         return InternalPriKeyGetPtr(pIndex)->mAttr;
03200     #endif
03201 }
03202 #endif // DOXYGEN_SHOULD_SKIP_THIS
03203 
03204 /*********************************************************************************************/
03205 /*********************************************************************************************/
03206 /*********************************************************************************************/
03207 /*********************************************************************************************/
03208 KFBX_FCURVE_INLINE void KFCurve::KeySet 
03209     (
03210     kFCurveIndex pKeyIndex,
03211     KTime pTime, 
03212     kFCurveDouble pValue, 
03213     kFCurveInterpolation pInterpolation, 
03214     kFCurveTangeantMode pTangentMode, 
03215     kFCurveDouble pRightSlope, 
03216     kFCurveDouble pNextLeftSlope, 
03217     kFCurveTangeantWeightMode pTangentWeightMode, 
03218     kFCurveDouble pWeight0, 
03219     kFCurveDouble pWeight1, 
03220     kFCurveDouble pVelocity0, 
03221     kFCurveDouble pVelocity1
03222     )
03223 {
03224     KPriFCurveKey *lPriKey = InternalPriKeyGetPtr(pKeyIndex);
03225     lPriKey->Set(pTime, pValue);
03226     KPriFCurveKeyAttr lKeyAttr;
03227     lKeyAttr.mFlags = 0;
03228     if (lPriKey->mAttr)
03229         lKeyAttr.mFlags = lPriKey->mAttr->mFlags;
03230     lKeyAttr.Set( pInterpolation, pTangentMode, pRightSlope, pNextLeftSlope, pTangentWeightMode, pWeight0, pWeight1, pVelocity0, pVelocity1);
03231 
03232     KeyAttrSet(pKeyIndex, lKeyAttr);
03233 }
03234 
03235 KFBX_FCURVE_INLINE void KFCurve::KeySetTCB 
03236     (
03237     kFCurveIndex pKeyIndex,
03238     KTime pTime, 
03239     kFCurveDouble pValue, 
03240     float pData0, 
03241     float pData1, 
03242     float pData2
03243     )
03244 {
03245     InternalPriKeyGetPtr(pKeyIndex)->Set(pTime, pValue);
03246     KPriFCurveKeyAttr lKeyAttr;
03247     lKeyAttr.SetTCB(pData0, pData1, pData2);
03248 
03249     KeyAttrSet(pKeyIndex, lKeyAttr);
03250 }
03251 
03252 KFBX_FCURVE_INLINE kFCurveInterpolation KFCurve::KeyGetInterpolation(kFCurveIndex pKeyIndex) const
03253 {
03254     K_ASSERT(pKeyIndex >= 0);
03255     K_ASSERT(pKeyIndex < KeyGetCount());
03256 
03257     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetInterpolation();
03258 }
03259 
03260 KFBX_FCURVE_INLINE void KFCurve::KeySetInterpolation(kFCurveIndex pKeyIndex, kFCurveInterpolation pInterpolation)
03261 {
03262     K_ASSERT(pKeyIndex >= 0);
03263     K_ASSERT(pKeyIndex < KeyGetCount());
03264 
03265     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03266     K_ASSERT(lKey->mAttr != NULL);
03267     if (lKey->mAttr)
03268     {
03269         if ( lKey->mAttr->GetInterpolation() != pInterpolation)
03270         {
03271             KeyAttrSeparateCheck(pKeyIndex);
03272             lKey->mAttr->SetInterpolation(pInterpolation);
03273             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03274         }
03275     }
03276 }
03277 
03278 KFBX_FCURVE_INLINE kFCurveConstantMode KFCurve::KeyGetConstantMode(kFCurveIndex pKeyIndex) const
03279 {
03280     K_ASSERT(pKeyIndex >= 0);
03281     K_ASSERT(pKeyIndex < KeyGetCount());
03282 
03283     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetConstantMode();
03284 }
03285 
03286 KFBX_FCURVE_INLINE kFCurveTangeantMode KFCurve::KeyGetTangeantMode(kFCurveIndex pKeyIndex, bool pIncludeOverrides ) const
03287 {
03288     K_ASSERT(pKeyIndex >= 0);
03289     K_ASSERT(pKeyIndex < KeyGetCount());
03290 
03291     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantMode( pIncludeOverrides );
03292 }
03293 
03294 KFBX_FCURVE_INLINE kFCurveTangeantWeightMode KFCurve::KeyGetTangeantWeightMode(kFCurveIndex pKeyIndex) const
03295 {
03296     K_ASSERT(pKeyIndex >= 0);
03297     K_ASSERT(pKeyIndex < KeyGetCount());
03298 
03299     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantWeightMode();
03300 }
03301 
03302 KFBX_FCURVE_INLINE kFCurveTangeantVelocityMode KFCurve::KeyGetTangeantVelocityMode(kFCurveIndex pKeyIndex) const
03303 {
03304     K_ASSERT(pKeyIndex >= 0);
03305     K_ASSERT(pKeyIndex < KeyGetCount());
03306 
03307     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantVelocityMode();
03308 }
03309 
03310 KFBX_FCURVE_INLINE void KFCurve::KeySetConstantMode(kFCurveIndex pKeyIndex, kFCurveConstantMode pMode)
03311 {
03312     K_ASSERT(pKeyIndex >= 0);
03313     K_ASSERT(pKeyIndex < KeyGetCount());
03314 
03315     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03316     K_ASSERT(lKey->mAttr != NULL);
03317     if (lKey->mAttr)
03318     {
03319         if (lKey->mAttr->GetConstantMode() != pMode)
03320         {
03321             KeyAttrSeparateCheck(pKeyIndex);
03322             lKey->mAttr->SetConstantMode(pMode);
03323             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03324         }
03325     }
03326 }
03327 
03328 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantMode(kFCurveIndex pKeyIndex, kFCurveTangeantMode pTangent, bool pIgnoreAutoTimeIndepedentConversion/* = false*/)
03329 {
03330     K_ASSERT(pKeyIndex >= 0);
03331     K_ASSERT(pKeyIndex < KeyGetCount());
03332 
03333     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03334     // We need to test if the flag value will be really changed.
03335     // but there is not easy way to tell that change for this operation,
03336     // so we need to performance special "try and swap" technique.
03337     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03338     K_ASSERT(lKey->mAttr != NULL);
03339     if (lKey->mAttr)
03340     {
03341         kUInt32 lFlags = lKey->mAttr->mFlags;
03342         lKey->mAttr->SetTangeantMode(pTangent, pIgnoreAutoTimeIndepedentConversion); //only affect mFlags
03343 
03344         if (lKey->mAttr->mFlags != lFlags)
03345         {
03346             if (lKey->mAttr->GetRefCount() > 1)
03347             {
03348                 kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03349                 lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03350                 KeyAttrSeparate(pKeyIndex);
03351                 lKey->mAttr->mFlags = lSwapFlags;
03352             }
03353             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03354         }
03355     }
03356 }
03357 
03358 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantWeightMode(kFCurveIndex pKeyIndex, kFCurveTangeantWeightMode pTangentWeightMode, kFCurveTangeantWeightMode pMask)
03359 {
03360     K_ASSERT(pKeyIndex >= 0);
03361     K_ASSERT(pKeyIndex < KeyGetCount());
03362 
03363     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03364     // We need to test if the flag value will be really changed.
03365     // but there is not easy way to tell that change for this operation,
03366     // so we need to performance special "try and swap" technique.
03367     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03368     K_ASSERT(lKey->mAttr != NULL);
03369     if (lKey->mAttr)
03370     {
03371         kUInt32 lFlags = lKey->mAttr->mFlags;
03372         lKey->mAttr->SetTangeantWeightMode(pTangentWeightMode, pMask); //only affect mFlags
03373         if (lKey->mAttr->mFlags != lFlags)
03374         {
03375            if (lKey->mAttr->GetRefCount() > 1)
03376            {
03377               kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03378               lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03379               KeyAttrSeparate(pKeyIndex);
03380               lKey->mAttr->mFlags = lSwapFlags;
03381            }
03382             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03383         }
03384     }
03385 }
03386 
03387 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantVelocityMode(kFCurveIndex pKeyIndex, kFCurveTangeantVelocityMode pTangentVelocityMode, kFCurveTangeantVelocityMode pMask)
03388 {
03389     K_ASSERT(pKeyIndex >= 0);
03390     K_ASSERT(pKeyIndex < KeyGetCount());
03391 
03392     // Avoid call expensive CallbackAddEvent() and KeyAttrSeparate(). 
03393     // We need to test if the flag value will be really changed.
03394     // but there is not easy way to tell that change for this operation,
03395     // so we need to performance special "try and swap" technique.
03396     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03397     K_ASSERT(lKey->mAttr != NULL);
03398     if (lKey->mAttr)
03399     {
03400         kUInt32 lFlags = lKey->mAttr->mFlags;
03401         lKey->mAttr->SetTangeantVelocityMode(pTangentVelocityMode, pMask); //only affect mFlags
03402         if (lKey->mAttr->mFlags != lFlags)
03403         {
03404            if (lKey->mAttr->GetRefCount() > 1)
03405            {
03406               kUInt32 lSwapFlags = lKey->mAttr->mFlags;
03407               lKey->mAttr->mFlags = lFlags; //Restore previous attr flag for other keys.
03408               KeyAttrSeparate(pKeyIndex);
03409               lKey->mAttr->mFlags = lSwapFlags;
03410            }
03411             CallbackAddEvent (KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03412         }
03413     }
03414 }
03415 
03416 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::KeyGetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const
03417 {
03418     K_ASSERT(pKeyIndex >= 0);
03419     K_ASSERT(pKeyIndex < KeyGetCount());
03420 
03421     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataDouble(pIndex);
03422 }
03423 
03424 KFBX_FCURVE_INLINE void KFCurve::KeySetDataDouble(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, kFCurveDouble pValue)
03425 {
03426     K_ASSERT(pKeyIndex >= 0);
03427     K_ASSERT(pKeyIndex < KeyGetCount());
03428 
03429     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03430     K_ASSERT(lKey->mAttr != NULL);
03431     if (lKey->mAttr)
03432     {
03433         if (lKey->mAttr->GetDataDouble(pIndex) != pValue)
03434         {
03435             KeyAttrSeparateCheck(pKeyIndex);
03436             lKey->mAttr->SetDataDouble(pIndex, pValue);
03437             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03438         }
03439     }
03440 }
03441 
03442 KFBX_FCURVE_INLINE float KFCurve::KeyGetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex) const
03443 {
03444     K_ASSERT(pKeyIndex >= 0);
03445     K_ASSERT(pKeyIndex < KeyGetCount());
03446 
03447     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataFloat(pIndex);
03448 }
03449 
03450 KFBX_FCURVE_INLINE void KFCurve::KeySetDataFloat(kFCurveIndex pKeyIndex, EKFCurveDataIndex pIndex, float pValue)
03451 {
03452     K_ASSERT(pKeyIndex >= 0);
03453     K_ASSERT(pKeyIndex < KeyGetCount());
03454 
03455     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03456     K_ASSERT(lKey->mAttr != NULL);
03457     if (lKey->mAttr)
03458     {
03459         if (lKey->mAttr->GetDataFloat(pIndex) != pValue)
03460         {
03461             KeyAttrSeparateCheck(pKeyIndex);
03462             lKey->mAttr->SetDataFloat(pIndex, pValue);
03463             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03464         }
03465     }
03466 }
03467 
03468 KFBX_FCURVE_INLINE const float* KFCurve::KeyGetDataPtr(kFCurveIndex pKeyIndex) const
03469 {
03470     K_ASSERT(pKeyIndex >= 0);
03471     K_ASSERT(pKeyIndex < KeyGetCount());
03472 
03473     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetDataPtr();
03474 }
03475 
03476 KFBX_FCURVE_INLINE kFCurveDouble KFCurve::KeyGetValue(kFCurveIndex pKeyIndex) const
03477 {
03478     K_ASSERT(pKeyIndex >= 0);
03479     K_ASSERT(pKeyIndex < KeyGetCount());
03480 
03481     return InternalPriKeyGetPtr(pKeyIndex)->GetValue();
03482 }
03483 
03484 KFBX_FCURVE_INLINE void KFCurve::KeySetValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03485 {
03486     InternalPriKeyGetPtr(pKeyIndex)->SetValue(pValue);
03487     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03488 }
03489 
03490 KFBX_FCURVE_INLINE void KFCurve::KeyIncValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03491 {
03492     K_ASSERT(pKeyIndex >= 0);
03493     K_ASSERT(pKeyIndex < KeyGetCount());
03494 
03495     InternalPriKeyGetPtr(pKeyIndex)->IncValue(pValue);
03496     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03497 }
03498 
03499 KFBX_FCURVE_INLINE void KFCurve::KeyMultValue(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03500 {
03501     K_ASSERT(pKeyIndex >= 0);
03502     K_ASSERT(pKeyIndex < KeyGetCount());
03503 
03504     InternalPriKeyGetPtr(pKeyIndex)->MultValue(pValue);
03505     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITVALUE, pKeyIndex);
03506 }
03507 
03508 KFBX_FCURVE_INLINE void KFCurve::KeyMultTangeant(kFCurveIndex pKeyIndex, kFCurveDouble pValue)
03509 {
03510     K_ASSERT(pKeyIndex >= 0);
03511     K_ASSERT(pKeyIndex < KeyGetCount());
03512 
03513     if (pValue == 1.0)
03514     {
03515        return;
03516     }
03517     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex); K_ASSERT(lKey->mAttr != NULL);
03518     KPriFCurveKey* lKeyNext = NULL;
03519     if (pKeyIndex < KeyGetCount()-1)
03520     {
03521         lKeyNext = InternalPriKeyGetPtr(pKeyIndex+1); 
03522         K_ASSERT(lKeyNext->mAttr != NULL);
03523     }
03524 
03525     if (lKey->mAttr)
03526     {
03527         if (lKey->mAttr->GetInterpolation() == KFCURVE_INTERPOLATION_CUBIC)
03528         {
03529             bool lScaleNextLeft = false;
03530             switch (lKey->mAttr->GetTangeantMode())
03531             {                   
03532             case KFCURVE_TANGEANT_USER:
03533             case KFCURVE_TANGEANT_BREAK:
03534                 lScaleNextLeft = true;
03535                 KeyAttrSeparateCheck(pKeyIndex);                        
03536                 lKey->mAttr->SetDataDouble(KFCURVEKEY_RIGHT_SLOPE, lKey->mAttr->GetDataDouble(KFCURVEKEY_RIGHT_SLOPE) * pValue);
03537 
03538             case KFCURVE_TANGEANT_AUTO:
03539             case KFCURVE_TANGEANT_AUTO_BREAK:
03540                 if (lKeyNext)
03541                 {
03542                     switch (lKeyNext->mAttr->GetTangeantMode())
03543                     {
03544                     case KFCURVE_TANGEANT_USER:
03545                     case KFCURVE_TANGEANT_BREAK:                    
03546                         lScaleNextLeft = true;
03547                     }
03548                 }
03549 
03550                 if (lScaleNextLeft)
03551                 {
03552                     lKey->mAttr->SetDataDouble(KFCURVEKEY_NEXT_LEFT_SLOPE, lKey->mAttr->GetDataDouble(KFCURVEKEY_NEXT_LEFT_SLOPE) * pValue);
03553                     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03554                 }
03555                 break;
03556 
03557             case KFCURVE_TANGEANT_TCB:
03558                 // dunno how to handle this
03559             default:
03560                 // nothing to do
03561                 break;
03562             }
03563         }
03564     }
03565 }
03566 
03567 KFBX_FCURVE_INLINE KTime KFCurve::KeyGetTime(kFCurveIndex pKeyIndex) const
03568 {
03569     K_ASSERT(pKeyIndex >= 0);
03570     K_ASSERT(pKeyIndex < KeyGetCount());
03571 
03572     return InternalPriKeyGetPtr(pKeyIndex)->GetTime();
03573 }
03574 
03575 KFBX_FCURVE_INLINE void KFCurve::KeySetTime(kFCurveIndex pKeyIndex, KTime pTime)
03576 {
03577     K_ASSERT(pKeyIndex >= 0);
03578     K_ASSERT(pKeyIndex < KeyGetCount());
03579 
03580     InternalPriKeyGetPtr(pKeyIndex)->SetTime(pTime);
03581     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITTIME, pKeyIndex);
03582 }
03583 
03584 KFBX_FCURVE_INLINE void KFCurve::KeyIncTime(kFCurveIndex pKeyIndex, KTime pTime)
03585 {
03586     K_ASSERT(pKeyIndex >= 0);
03587     K_ASSERT(pKeyIndex < KeyGetCount());
03588 
03589     InternalPriKeyGetPtr(pKeyIndex)->IncTime(pTime);
03590     CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITTIME, pKeyIndex);
03591 }
03592 
03593 KFBX_FCURVE_INLINE void KFCurve::KeySetSelected(kFCurveIndex pKeyIndex, bool pSelected)
03594 {
03595     K_ASSERT(pKeyIndex >= 0);
03596     K_ASSERT(pKeyIndex < KeyGetCount());
03597 
03598     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03599     K_ASSERT(lKey->mAttr != NULL);
03600     if (lKey->mAttr)
03601     {
03602         if (lKey->mAttr->GetSelected() != pSelected)
03603         {
03604             KeyAttrSeparateCheck(pKeyIndex);
03605             lKey->mAttr->SetSelected(pSelected);
03606             CallbackAddEvent(KFCURVEEVENT_SELECTION, pKeyIndex);
03607         }
03608     }
03609 }
03610 
03611 KFBX_FCURVE_INLINE bool KFCurve::KeyGetSelected(kFCurveIndex pKeyIndex) const
03612 {
03613     K_ASSERT(pKeyIndex >= 0);
03614     K_ASSERT(pKeyIndex < KeyGetCount());
03615 
03616     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetSelected();
03617 }
03618 
03619 KFBX_FCURVE_INLINE void KFCurve::KeySetMarkedForManipulation(kFCurveIndex pKeyIndex, bool pMarked)
03620 {
03621     K_ASSERT(pKeyIndex >= 0);
03622     K_ASSERT(pKeyIndex < KeyGetCount());
03623 
03624     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03625     K_ASSERT(lKey->mAttr != NULL);
03626     if (lKey->mAttr)
03627     {
03628         if (lKey->mAttr->GetMarkedForManipulation() != pMarked)
03629         {
03630             KeyAttrSeparateCheck(pKeyIndex);
03631             lKey->mAttr->SetMarkedForManipulation(pMarked);
03632         }
03633     }
03634 }
03635 
03636 KFBX_FCURVE_INLINE bool KFCurve::KeyGetMarkedForManipulation(kFCurveIndex pKeyIndex) const
03637 {
03638     K_ASSERT(pKeyIndex >= 0);
03639     K_ASSERT(pKeyIndex < KeyGetCount());
03640 
03641     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetMarkedForManipulation();
03642 }
03643 
03644 KFBX_FCURVE_INLINE void KFCurve::KeySetTangeantVisibility (kFCurveIndex pKeyIndex, kFCurveTangeantVisibility pVisibility)
03645 {
03646     K_ASSERT(pKeyIndex >= 0);
03647     K_ASSERT(pKeyIndex < KeyGetCount());
03648 
03649     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);  
03650     K_ASSERT(lKey->mAttr != NULL);
03651     if (lKey->mAttr)
03652     {
03653         if (lKey->mAttr->GetTangeantVisibility() != pVisibility)
03654         {
03655             KeyAttrSeparateCheck(pKeyIndex);
03656             lKey->mAttr->SetTangeantVisibility(pVisibility);
03657             CallbackAddEvent(KFCURVEEVENT_SELECTION, pKeyIndex);
03658         }
03659     }
03660 }
03661 
03662 KFBX_FCURVE_INLINE kFCurveTangeantVisibility KFCurve::KeyGetTangeantVisibility (kFCurveIndex pKeyIndex) const
03663 {
03664     K_ASSERT(pKeyIndex >= 0);
03665     K_ASSERT(pKeyIndex < KeyGetCount());
03666 
03667     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetTangeantVisibility();
03668 }
03669 
03670 KFBX_FCURVE_INLINE void KFCurve::KeySetBreak(kFCurveIndex pKeyIndex, bool pVal)
03671 {
03672     K_ASSERT(pKeyIndex >= 0);
03673     K_ASSERT(pKeyIndex < KeyGetCount());
03674 
03675     KPriFCurveKey* lKey = InternalPriKeyGetPtr(pKeyIndex);
03676     K_ASSERT(lKey->mAttr != NULL);
03677     if (lKey->mAttr)
03678     {   
03679         if (lKey->mAttr->GetBreak() != pVal)
03680         {
03681             KeyAttrSeparateCheck(pKeyIndex);
03682             lKey->mAttr->SetBreak(pVal);
03683             CallbackAddEvent(KFCURVEEVENT_KEY | KFCURVEEVENT_EDITOTHER, pKeyIndex);
03684         }
03685     }
03686 }
03687 
03688 KFBX_FCURVE_INLINE bool KFCurve::KeyGetBreak(kFCurveIndex pKeyIndex) const
03689 {
03690     K_ASSERT(pKeyIndex >= 0);
03691     K_ASSERT(pKeyIndex < KeyGetCount());
03692 
03693     return InternalPriKeyAttrGetPtr(pKeyIndex)->GetBreak();
03694 }
03695 
03696 KFBX_FCURVE_INLINE void KFCurve::KeyAttrSeparateCheck(kFCurveIndex pKeyIndex)
03697 {
03698     KPriFCurveKeyAttr* lCurKeyAttr = InternalPriKeyAttrGetPtr(pKeyIndex);
03699     if (! lCurKeyAttr || lCurKeyAttr->GetRefCount() > 1 )
03700         KeyAttrSeparate(pKeyIndex);
03701 }
03702 
03703 
03706 KFBX_DLL HKFCurve KFCurveCreate();
03707 
03708 // Create a function curve, FBX SDK internal use only.
03709 KFBX_DLL HKFCurve KFCurveCreate(KFbx* pFbx, bool pOnlyDefaults = false, bool pColor = false);
03710 
03711 // Create a function curve, FBX SDK internal use only.
03712 KFBX_DLL HKFCurve KFCurveCreate(KFbx* pFbx, HKFCurve pCurve, bool pOnlyDefaults = false, bool pColor = false);
03713 
03714 #include <fbxfilesdk/fbxfilesdk_nsend.h>
03715 
03716 
03717 #endif // FBXFILESDK_COMPONENTS_KFCURVE_KFCURVE_H
03718