control.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 1998-2006 Autodesk, Inc.
00003 // All rights reserved.
00004 // 
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //**************************************************************************/
00011 // FILE:        control.h
00012 // DESCRIPTION: Control definitions
00013 // AUTHOR:      Dan Silva and Rolf Berteig
00014 // HISTORY:     created 9 September 1994
00015 //**************************************************************************/
00016 
00017 #pragma once
00018 
00019 #include "maxheap.h"
00020 #include "plugapi.h"
00021 #include "assert1.h"
00022 #include "matrix3.h"
00023 #include "quat.h"
00024 #include "interval.h"
00025 #include "ref.h"
00026 #include "box3.h"
00027 #include "bitarray.h"
00028 #include "AnimPropertyID.h"
00029 
00030 // forward declarations
00031 class ScaleValue;
00032 class ViewExp;
00033 class INode;
00034 class XFormModes;
00035 class INodeTab;
00036 class View;
00037 class Control;
00038 class Object;
00039 class SubObjAxisCallback;
00040 
00041 extern CoreExport void ApplyScaling(Matrix3& m, const ScaleValue& v);
00042 extern CoreExport void InitControlLists();
00043 
00044 
00045 
00046 
00049 CoreExport ScaleValue operator+(const ScaleValue& s0, const ScaleValue& s1);
00051 CoreExport ScaleValue operator-(const ScaleValue& s0, const ScaleValue& s1);
00053 CoreExport ScaleValue operator*(const ScaleValue& s, float f);
00055 CoreExport ScaleValue operator*(float f, const ScaleValue& s);
00058 CoreExport ScaleValue operator+(const ScaleValue& s, float f);
00060 CoreExport ScaleValue operator+(float f, const ScaleValue& s);
00061 
00073 class ScaleValue: public MaxHeapOperators {
00074    public:
00075    Point3 s;
00076    Quat q;
00078    ScaleValue() { /* NO INIT! */ }
00081    ScaleValue(const Point3& as) { s = as; q = IdentQuat(); }
00086    ScaleValue(const Point3& as, const Quat& aq) {s = as; q = aq; }
00088    ScaleValue& operator+=(const ScaleValue& s) 
00089       { (*this)=(*this)+s; return (*this);}
00092    ScaleValue& operator*=(const float s) 
00093       { (*this)=(*this)*s; return (*this);}
00094    ScaleValue& operator=(const ScaleValue &v) {s=v.s;q=v.q; return (*this);}
00101    float& operator[](int el) {return s[el];}
00102    };
00103 
00104 // Types of ORTs
00105 #define ORT_BEFORE   1
00106 #define ORT_AFTER 2
00107 
00108 // Out-of-Range Types
00116 #define ORT_CONSTANT       1    //!< Tracks values before or after the range of keys remains constant.
00117 #define ORT_CYCLE          2    //!< Causes the key pattern to repeat cyclically.
00118 #define ORT_LOOP           3    //!< The same as ORT_CYCLE with continuity.
00119 
00120 #define ORT_OSCILLATE      4    //!< Referred to as "Ping-Pong" in the 3ds Max user interface.
00121 #define ORT_LINEAR         5    //!< Takes the slope at the end key in the range and extrapolate with that slope.
00122 
00124 #define ORT_IDENTITY       6    //!< 3ds Max will only set this ORT for Ease Curves.
00125 #define ORT_RELATIVE_REPEAT 7   //!< Causes the key pattern to repeat with the first key taking off where the last key left off.
00126 
00127 
00128 //keh set key define 
00129 #define KEY_MODE_NO_BUFFER    1
00130 
00137 struct TMComponentsArg: public MaxHeapOperators {
00139   TMComponentsArg():position(0),rotation(0),scale(0),rotRep(kUnknown) {}
00141   TMComponentsArg(Point3* pos, Interval* posInv, float* rot, Interval* rotInv,
00142             ScaleValue* scl, Interval* sclInv)
00143    : position(pos),posValidity(posInv),rotation(rot),rotValidity(rotInv)
00144    , scale(scl),sclValidity(sclInv) {}
00145   enum RotationRep {
00146    // kXYZ should equals EULERTYPE_XYZ, which is 0.(c.f. euler.h)
00147    kXYZ,
00148    kXZY,
00149    kYZX,
00150    kYXZ,
00151    kZXY,
00152    kZYX,
00153    kXYX,
00154    kYZY,
00155    kZXZ,
00156    kQuat,
00157    kUnknown
00158   };
00160   Point3*      position;
00162   Interval*    posValidity;
00164   float*    rotation;
00166   Interval*    rotValidity;
00181   RotationRep  rotRep;
00183   ScaleValue*  scale;
00185   Interval*    sclValidity;
00186 };
00187 
00188 // An object of this class represents a Matrix3. However, its value can be
00189 // obtained only by invoking the operator(). Derived classes may override
00190 // this operator to delay its computation until operator() is called.
00191 //
00202 class Matrix3Indirect: public MaxHeapOperators {
00203 public:
00207   Matrix3Indirect(){}
00211   Matrix3Indirect(const Matrix3& m):mat(m){}
00215   virtual ~Matrix3Indirect(){}
00219   virtual const Matrix3& operator()() const { return mat; }
00226   virtual void Set(const Matrix3& m) { mat = m; }
00231   CoreExport virtual Matrix3Indirect* Clone() const;
00238   virtual void PreTranslate(const Point3& p){ mat.PreTranslate(p);}
00245   virtual void PreRotateX(float x){ mat.PreRotateX(x); }
00252   virtual void PreRotateY(float y){ mat.PreRotateY(y); }
00259   virtual void PreRotateZ(float z){ mat.PreRotateZ(z); }
00266   virtual void PreRotate(const Quat& q){PreRotateMatrix(mat,q);}
00267 protected:
00268   Matrix3   mat;
00269 };
00270 
00271 class DelayedMatrix3 : public Matrix3Indirect {
00272 public:
00273    typedef Matrix3Indirect BaseClass;
00274    struct DelayedOp : public MaxHeapOperators {
00275       enum OpCode {
00276          kPreTrans,
00277          kPreRotateX,
00278          kPreRotateY,
00279          kPreRotateZ,
00280          kPreRotate
00281       };
00282       OpCode code;
00283       Quat   arg;
00284       DelayedOp() {}
00285       DelayedOp(const Point3& p) : code(kPreTrans), arg(p.x, p.y, p.z, 0.0f) {}
00286       DelayedOp(const Quat& q) : code(kPreRotate), arg(q) {}
00287       DelayedOp(float x) : code(kPreRotateX), arg(x, 0.0f, 0.0f, 0.0f) {}
00288       DelayedOp(int, float y)
00289          : code(kPreRotateY), arg(0.0f, y, 0.0f, 0.0f) {}
00290       DelayedOp(int, int, float z)
00291          : code(kPreRotateZ), arg(0.0f, 0.0f, z, 0.0f) {}
00292    };
00293    struct OpQueue : public Tab<DelayedOp> {
00294       typedef Tab<DelayedOp> BaseClass;
00295       int head;
00296       OpQueue() : BaseClass(), head(0) {}
00297       void Clear() { ZeroCount(); head = 0; }
00298       int QCount() const { return BaseClass::Count() - head; }
00299       DelayedOp& Shift() { return BaseClass::operator[](head++); }
00300       void Push(DelayedOp& op) { Append(1, &op, 4); }
00301    };
00302 
00303    DelayedMatrix3::DelayedMatrix3()
00304       : Matrix3Indirect()
00305       , mMatInitialized(false)
00306       , mOpQueue()
00307       {}
00308    DelayedMatrix3::DelayedMatrix3(const DelayedMatrix3& src)
00309       : Matrix3Indirect(src.mat)
00310       , mMatInitialized(src.mMatInitialized) {
00311       mOpQueue = src.mOpQueue; }
00312 
00313    void EvalMat() {
00314       if (!mMatInitialized) {
00315          InitializeMat();
00316          mMatInitialized = true;
00317       }
00318       while (mOpQueue.QCount() > 0) {
00319          DelayedOp& op = mOpQueue.Shift();
00320          switch (op.code) {
00321          case DelayedOp::kPreTrans:
00322             mat.PreTranslate(op.arg.Vector());
00323             break;
00324          case DelayedOp::kPreRotateX:
00325             mat.PreRotateX(op.arg.x);
00326             break;
00327          case DelayedOp::kPreRotateY:
00328             mat.PreRotateY(op.arg.y);
00329             break;
00330          case DelayedOp::kPreRotateZ:
00331             mat.PreRotateZ(op.arg.z);
00332             break;
00333          case DelayedOp::kPreRotate:
00334             PreRotateMatrix(mat, op.arg);
00335             break;
00336          }
00337       }
00338       return; }
00339    void EvalMat() const { const_cast<DelayedMatrix3*>(this)->EvalMat(); }
00340    size_t PendingOps() const { return mOpQueue.QCount(); }
00341    virtual void InitializeMat() {
00342       mat.IdentityMatrix();
00343       mMatInitialized = true; };
00344 
00345    // Methods of Matrix3Indirect:
00346    void Set(const Matrix3& m) {
00347       mat = m;
00348       mMatInitialized = true;
00349       mOpQueue.Clear(); }
00350    CoreExport Matrix3Indirect* Clone() const;
00351    const Matrix3& operator()() const { EvalMat(); return mat; }
00352    void PreTranslate(const Point3& p) { DelayedOp op(p); mOpQueue.Push(op); }
00353    void PreRotateX(float x){ DelayedOp op(x); mOpQueue.Push(op); }
00354    void PreRotateY(float y){ DelayedOp op(0, y); mOpQueue.Push(op); }
00355    void PreRotateZ(float z){ DelayedOp op(0, 0, z); mOpQueue.Push(op); }
00356    void PreRotate(const Quat& q){ DelayedOp op(q); mOpQueue.Push(op); }
00357 
00358 private:
00359    mutable bool mMatInitialized;
00360    mutable OpQueue mOpQueue;
00361 };
00362 
00363 class DelayedNodeMat : public DelayedMatrix3 {
00364 public:
00365    DelayedNodeMat(INode& n, TimeValue t0)
00366       : DelayedMatrix3()
00367       , node(n)
00368       , t(t0)
00369       {}
00370    DelayedNodeMat(const DelayedNodeMat& src)
00371       : DelayedMatrix3(src)
00372       , node(src.node)
00373       , t(src.t)
00374       {}
00375    // of Matrix3Indirect:
00376    void Set(const Matrix3&) {}
00377    CoreExport Matrix3Indirect* Clone() const;
00378 
00379    // of DelayedMatrix3:
00380    CoreExport void InitializeMat();
00381 private:
00382     DelayedNodeMat& operator=(const DelayedNodeMat& );
00383    TimeValue t;
00384    INode&   node;
00385 };
00386 
00387 /*---------------------------------------------------------------------*/
00388 
00389 // A list of ease curves.
00406 #pragma warning(push)
00407 #pragma warning(disable:4100 4239)
00408 
00409 class EaseCurveList : public ReferenceTarget {
00410       friend class AddEaseRestore;
00411       friend class DeleteEaseRestore;
00412 
00413    private:
00414       Tab<Control*> eases;
00415       
00416    public:
00418       EaseCurveList() {OpenTreeEntry(TRACKVIEW_ANIM, ALL_TRACK_VIEWS);}
00421       CoreExport ~EaseCurveList();
00422 
00432       CoreExport TimeValue ApplyEase(TimeValue t,Interval& valid);
00438       CoreExport void AppendEaseCurve(Control *cont);
00443       CoreExport void DeleteEaseCurve(int i);
00448       CoreExport void DisableEaseCurve(int i);
00453       CoreExport void EnableEaseCurve(int i);
00459       CoreExport BOOL IsEaseEnabled(int i);
00461       int NumEaseCurves() {return eases.Count();}
00462 
00463       // Animatable
00464       void GetClassName(MSTR& s) { s= MSTR(_M("EaseCurve")); }  
00465       Class_ID ClassID() { return Class_ID(EASE_LIST_CLASS_ID,0); }
00466       SClass_ID SuperClassID() { return EASE_LIST_CLASS_ID; }     
00467       CoreExport int NumSubs();
00468       CoreExport Animatable* SubAnim(int i);
00469       CoreExport MSTR SubAnimName(int i);
00470       int SubNumToRefNum(int subNum) {return subNum;}
00471       BOOL BypassTreeView() { return TRUE; }
00472       CoreExport void DeleteThis();
00473       ParamDimension* GetParamDimension(int i) {return stdTimeDim;}
00474       CoreExport BOOL AssignController(Animatable *control,int subAnim);
00475 
00476         using ReferenceTarget::GetInterface;
00477       CoreExport void* GetInterface(ULONG id);
00478 
00479       CoreExport IOResult Save(ISave *isave);
00480       CoreExport IOResult Load(ILoad *iload);
00481       
00482       // Reference
00483       CoreExport int NumRefs();
00484       CoreExport RefTargetHandle GetReference(int i);
00485 protected:
00486       CoreExport virtual void SetReference(int i, RefTargetHandle rtarg);
00487 public:
00488       CoreExport RefTargetHandle Clone(RemapDir &remap);
00489       CoreExport RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, 
00490             PartID& partID,  RefMessage message);     
00491    };
00492 
00493 class EaseCurveAnimProp : public AnimProperty {
00494    public:
00495       EaseCurveList *el;
00496       EaseCurveAnimProp() { el=NULL; }
00497       DWORD ID() {return PROPID_EASELIST;}
00498    };
00499 
00500 #define GetEaseListInterface(anim)  ((EaseCurveList*)anim->GetInterface(I_EASELIST))
00501 
00502 /*---------------------------------------------------------------------*/
00503 // A list of multiplier curves.
00519 class MultCurveList : public ReferenceTarget {
00520       friend class AddMultRestore;
00521       friend class DeleteMultRestore;
00522    private:
00523       Tab<Control*> mults;
00524       
00525    public:
00527       MultCurveList() {OpenTreeEntry(TRACKVIEW_ANIM, ALL_TRACK_VIEWS);}
00529       CoreExport ~MultCurveList();
00530 
00540       CoreExport float GetMultVal(TimeValue t,Interval& valid);
00546       CoreExport void AppendMultCurve(Control *cont);
00551       CoreExport void DeleteMultCurve(int i);
00556       CoreExport void DisableMultCurve(int i);
00561       CoreExport void EnableMultCurve(int i);
00567       CoreExport BOOL IsMultEnabled(int i);
00569       int NumMultCurves() {return mults.Count();}
00570 
00571       // Animatable
00572       void GetClassName(MSTR& s) { s= MSTR(_M("MultCurve")); }  
00573       Class_ID ClassID() { return Class_ID(MULT_LIST_CLASS_ID,0); }
00574       SClass_ID SuperClassID() { return MULT_LIST_CLASS_ID; }     
00575       CoreExport int NumSubs();
00576       CoreExport Animatable* SubAnim(int i);
00577       CoreExport MSTR SubAnimName(int i);
00578       int SubNumToRefNum(int subNum) {return subNum;}
00579       BOOL BypassTreeView() { return TRUE; }
00580       CoreExport void DeleteThis();
00581       ParamDimension* GetParamDimension(int i) {return stdNormalizedDim;}
00582       CoreExport BOOL AssignController(Animatable *control,int subAnim);
00583 
00584         using ReferenceTarget::GetInterface;
00585       CoreExport void* GetInterface(ULONG id);
00586 
00587       CoreExport IOResult Save(ISave *isave);
00588       CoreExport IOResult Load(ILoad *iload);
00589       
00590       // Reference
00591       CoreExport int NumRefs();
00592       CoreExport RefTargetHandle GetReference(int i);
00593 protected:
00594       CoreExport virtual void SetReference(int i, RefTargetHandle rtarg);
00595 public:
00596       CoreExport RefTargetHandle Clone(RemapDir &remap);
00597       CoreExport RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, 
00598             PartID& partID,  RefMessage message);     
00599    };
00600 
00601 class MultCurveAnimProp : public AnimProperty {
00602    public:
00603       MultCurveList *ml;
00604       MultCurveAnimProp() { ml=NULL; }
00605       DWORD ID() {return PROPID_MULTLIST;}
00606    };
00607 
00608 #define GetMultListInterface(anim)  ((MultCurveList*)anim->GetInterface(I_MULTLIST))
00609 
00610 /*---------------------------------------------------------------------*/
00611 
00612 
00613 //
00614 // For hit testing controller apparatus 
00615 //
00616 
00638 class CtrlHitRecord: public MaxHeapOperators {
00639    friend class CtrlHitLog;
00640    CtrlHitRecord *next;
00641    public:
00642       INode *nodeRef;
00643       DWORD distance;
00644       ulong hitInfo;
00645       DWORD infoExtra;     
00649       CtrlHitRecord() {next=NULL; distance=0; hitInfo=0; nodeRef=NULL;}
00652       CtrlHitRecord(CtrlHitRecord *nxt,INode *nr, DWORD d, ulong inf, DWORD extra) {
00653          next=nxt;nodeRef=nr;distance=d;hitInfo=inf;infoExtra=extra;}
00656       CtrlHitRecord *Next() {return next;}      
00657    };                
00658 
00665 class CtrlHitLog: public MaxHeapOperators {
00666    CtrlHitRecord *first;
00667    int hitIndex;
00668    bool hitIndexReady;        // CAL-07/10/03: hitIndex is ready to be increased.
00669    public:
00671       CtrlHitLog()  { first = NULL; hitIndex = 0; hitIndexReady = false; }
00672       ~CtrlHitLog() { Clear(); }
00674       CoreExport void Clear();
00675       CoreExport void ClearHitIndex(bool ready = false)     { hitIndex = 0; hitIndexReady = ready; }
00676       CoreExport void IncrHitIndex()      { if (hitIndexReady) hitIndex++; else hitIndexReady = true; }
00678       CtrlHitRecord* First() { return first; }
00681       CoreExport CtrlHitRecord* ClosestHit();
00702       CoreExport void LogHit(INode *nr,DWORD dist,ulong info,DWORD infoExtra); 
00703    };
00704 
00705 
00706 // For enumerating IK paramaters
00712 class IKEnumCallback: public MaxHeapOperators {
00713    public:
00724       virtual void proc(Control *c, int index)=0;
00725    };
00726 
00732 class IKDeriv: public MaxHeapOperators {
00733    public:
00742       virtual int NumEndEffectors()=0;
00750       virtual Point3 EndEffectorPos(int index)=0;
00760       virtual void DP(Point3 dp,int index)=0;
00769       virtual void DR(Point3 dr,int index)=0;
00773       virtual void NextDOF()=0;
00774    };
00775 
00776 // Flags passed to CompDerivs
00777 #define POSITION_DERIV  (1<<0)
00778 #define ROTATION_DERIV  (1<<1)
00779 
00780 
00781 // This class is used to store IK parameters that have been
00782 // copied to a clipboard.
00789 class IKClipObject: public MaxHeapOperators {
00790    public:
00792       virtual ~IKClipObject() { }
00793       // Identifies the creator of the clip object
00795       virtual SClass_ID    SuperClassID()=0;
00797       virtual Class_ID  ClassID()=0;
00798       
00801       virtual void DeleteThis()=0;
00802    };
00803 
00804 // Values for 'which' pasted to Copy/PasteIKParams
00805 #define COPYPASTE_IKPOS    1
00806 #define COPYPASTE_IKROT    2
00807 
00808 // Passed to InitIKJoints() which is called when importing
00809 // R4 3DS files that have IK joint data.
00823 class InitJointData: public MaxHeapOperators {
00824    public:
00825       BOOL active[3];
00826       BOOL limit[3];
00827       BOOL ease[3];
00828       Point3 min, max, damping;
00829    };
00830 
00831 // New for R4: include preferred angle
00842 class InitJointData2 : public InitJointData {
00843    public:     
00844       Point3 preferredAngle;
00845       DWORD flags; // not used (must be 0) - for future expansion
00847       InitJointData2() {flags=0;}
00848    };
00849 
00850 // The following member been added
00851 // in 3ds max 4.2.  If your plugin utilizes this new
00852 // mechanism, be sure that your clients are aware that they
00853 // must run your plugin with 3ds max version 4.2 or higher.
00854 //
00855 // Extend to include Spring parameters that are missing in InitJointData
00856 // and InitJointData2. It is designed for arguments of type InitJointData2.
00857 // A pointer of InitJointData2 can be tested and downcast to InitJointData3
00858 // via the following two inlines: IsInitJointData3(InitJointData2*) and
00859 // DowncastToJointData3(InitJointData2*).
00860 // 
00861 const DWORD bJointData3 = (1 << 0);
00889 class InitJointData3 : public InitJointData2 {
00890    public:
00891    InitJointData3() : InitJointData2() {
00892    active[0] = active[1] = active[2] = FALSE;
00893    limit[0] = limit[1] = limit[2] = FALSE;
00894    ease[0] = ease[1] = ease[2] = FALSE;
00895    min.Set(0.0f, 0.0f, 0.0f);
00896    max.Set(0.0f, 0.0f, 0.0f);
00897    damping.Set(0.0f, 0.0f, 0.0f);
00898    flags |= bJointData3;
00899    preferredAngle.Set(0.0f, 0.0f, 0.0f);
00900    springOn[0] = springOn[1] = springOn[2] = false;
00901    spring.Set(0.0f, 0.0f, 0.0f);
00902    // from interpik.h:
00903 #define DEF_SPRINGTENS  (0.02f)
00904    springTension.Set(DEF_SPRINGTENS, DEF_SPRINGTENS, DEF_SPRINGTENS);
00905 #undef DEF_SPRINGTENS
00906     }
00907   bool  springOn[3];
00908   Point3 spring;
00909   Point3 springTension;
00910 };
00911 
00912 inline bool IsInitJointData3(InitJointData2* jd)
00913 {
00914   return (jd->flags & bJointData3);
00915 }
00916 
00917 inline InitJointData3* DowncastToJointData3(InitJointData2* jd)
00918 {
00919   return IsInitJointData3(jd) ? (InitJointData3*)jd : NULL;
00920 }
00921 // End of 3ds max 4.2 Extension
00922 
00923 // This structure is passed to GetDOFParams().
00924 // Controllers that support IK can provide info about their DOFs
00925 // so that bones can display this information.
00926 // The first 3 DOFs are assumed to be position
00927 // and the next 3 are assumed to be rotation
00956 class DOFParams: public MaxHeapOperators {
00957    public:
00958       BOOL display[6];     // Should this DOF be displayed?
00959       Point3 axis[6];         // DOF axis
00960       Point3 pos[6];       // Base of axis
00961       BOOL limit[6];          // is joint limited?
00962       float min[6];        // min limit
00963       float max[6];           // max limit
00964       float curval[6];     // Current value of the parameter
00965       BOOL sel[6];         // should DOF be highlighted
00966       BOOL endEffector;    // is there an end effector for this controller
00967       Matrix3 eeTM;        // world TM of the end effector if present
00968    };
00969 
00970 
00971 // These two ways values can be retreived or set.
00972 // For get:
00973 //    RELATIVE = Apply
00974 //    ABSOLUTE = Just get the value
00975 // For set:
00976 //    RELATIVE = Add the value to the existing value (i.e Move/Rotate/Scale)
00977 //    ABSOLUTE = Just set the value
00978 enum GetSetMethod {CTRL_RELATIVE,CTRL_ABSOLUTE};
00979 
00980 
00981 // Control class provides default implementations for load and save which save the ORT type in these chunks:
00982 #define CONTROLBASE_CHUNK     0x8499
00983 #define INORT_CHUNK           0x3000
00984 #define OUTORT_CHUNK       0x3001
00985 #define CONT_DISABLED_CHUNK      0x3002
00986 #define CONT_FLAGS_CHUNK      0x3003
00987 
00988 // Inheritance flags.
00989 #define INHERIT_POS_X   (1<<0)
00990 #define INHERIT_POS_Y   (1<<1)
00991 #define INHERIT_POS_Z   (1<<2)
00992 #define INHERIT_ROT_X   (1<<3)
00993 #define INHERIT_ROT_Y   (1<<4)
00994 #define INHERIT_ROT_Z   (1<<5)
00995 #define INHERIT_SCL_X   (1<<6)
00996 #define INHERIT_SCL_Y   (1<<7)
00997 #define INHERIT_SCL_Z   (1<<8)
00998 #define INHERIT_ALL     511
00999 
01028 class Control : public ReferenceTarget {
01029    public:
01030       // aszabo|MAr.25.02|Prevents GetInterface(ULONG id) from hiding GetInterface(Interface_ID)
01031       using ReferenceTarget::GetInterface;
01032 
01033       CoreExport Control();
01034       virtual ~Control() {};
01035 
01043       virtual void Copy(Control *from)=0;
01055       virtual void CommitValue(TimeValue t) {}
01070       virtual void RestoreValue(TimeValue t) {}
01075       virtual INode* GetTarget() { return NULL; } 
01085       virtual RefResult SetTarget(INode *targ) {return REF_SUCCEED;}
01086 
01087       // Implemented by transform controllers that have position controller
01088       // that can be edited in the trajectory branch
01094       virtual Control *GetPositionController() {return NULL;}
01101       virtual Control *GetRotationController() {return NULL;}
01108       virtual Control *GetScaleController() {return NULL;}
01115       virtual BOOL SetPositionController(Control *c) {return FALSE;}
01122       virtual BOOL SetRotationController(Control *c) {return FALSE;}
01129       virtual BOOL SetScaleController(Control *c) {return FALSE;}
01130 
01131       // If a controller has an 'X', 'Y', 'Z', or 'W' controller, it can implement
01132       // these methods so that its sub controllers can respect track view filters
01140       virtual Control *GetXController() {return NULL;}
01148       virtual Control *GetYController() {return NULL;}
01156       virtual Control *GetZController() {return NULL;}
01157       virtual Control *GetWController() {return NULL;}
01158 
01159       // Implemented by look at controllers that have a float valued roll
01160       // controller so that the roll can be edited via the transform type-in
01166       virtual Control *GetRollController() {return NULL;}
01173       virtual BOOL SetRollController(Control *c) {return FALSE;}
01174 
01175       // Implemented by any Point3/Point4 controller that wishes to indicate that it is intended
01176       // to control floating point RGB color values
01182       virtual BOOL IsColorController() {return FALSE;}
01183 
01184       // Implemented by TM controllers that support 
01185       // filtering out inheritance
01207       virtual DWORD GetInheritanceFlags() {return INHERIT_ALL;}
01230       virtual BOOL SetInheritanceFlags(DWORD f,BOOL keepPos) {return FALSE;} // return TRUE if TM controller supports inheritance
01231 
01241       virtual BOOL IsLeaf() {return TRUE;}
01249       virtual int IsKeyable() {return 1;}
01250 
01251       // If a controller does not want to allow another controller
01252       // to be assigned on top of it, it can return FALSE to this method.
01260       virtual BOOL IsReplaceable() {return TRUE;}     
01261 
01262       // This is called on TM, pos, rot, and scale controllers when their
01263       // input matrix is about to change. If they return FALSE, the node will
01264       // call SetValue() to make the necessary adjustments.
01331       virtual BOOL ChangeParents(TimeValue t,const Matrix3& oldP,const Matrix3& newP,const Matrix3& tm) {return FALSE;}
01332 
01333       // val points to an instance of a data type that corresponds with the controller
01334       // type. float for float controllers, etc.
01335       // Note that for SetValue on Rotation controllers, if the SetValue is
01336       // relative, val points to an AngAxis while if it is absolute it points
01337       // to a Quat.
01505       virtual void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE)=0;
01506       
01621       virtual  void SetValue(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE)=0;
01622 
01651       CoreExport virtual bool GetLocalTMComponents(TimeValue t, TMComponentsArg& cmpts, Matrix3Indirect& parentMatrix);
01652 
01653       // Transform controllers that do not inherit their parent's  transform 
01654       // should override this method. Returning FALSE will cause SetValue 
01655       // to be called even in the case when the parent is also being transformed.
01678       virtual BOOL InheritsParentTransform() { return TRUE; }
01679 
01689       virtual int GetORT(int type) {return (aflag>>(type==ORT_BEFORE?A_ORT_BEFORESHIFT:A_ORT_AFTERSHIFT))&A_ORT_MASK;}
01690       
01699       CoreExport virtual void SetORT(int ort,int type);
01700       
01701       // Sets the enabled/disabled state for ORTs
01708       CoreExport virtual void EnableORTs(BOOL enable);
01709 
01710       // Default implementations of load and save handle loading and saving of out of range type.
01711       // Call these from derived class load and save.
01712       // NOTE: Must call these before any of the derived class chunks are loaded or saved.
01726       CoreExport IOResult Save(ISave *isave);
01740       CoreExport IOResult Load(ILoad *iload);
01741 
01742       // For IK
01743       // Note: IK params must be given in the order they are applied to
01744       // the parent matrix. When derivatives are computed for a parameter
01745       // that parameter will apply itself to the parent matrix so the next
01746       // parameter has the appropriate reference frame. If a controller isn't
01747       // participating in IK then it should return FALSE and the client (usually PRS)
01748       // will apply the controller's value to the parent TM.
01782       virtual void EnumIKParams(IKEnumCallback &callback) {}
01840       virtual BOOL CompDeriv(TimeValue t,Matrix3& ptm,IKDeriv& derivs,DWORD flags) {return FALSE;}
01903       virtual float IncIKParam(TimeValue t,int index,float delta) {return 0.0f;}
01912       virtual void ClearIKParam(Interval iv,int index) {return;}
01922       virtual BOOL CanCopyIKParams(int which) {return FALSE;}
01933       virtual IKClipObject *CopyIKParams(int which) {return NULL;}
01947       virtual BOOL CanPasteIKParams(IKClipObject *co,int which) {return FALSE;}
01956       virtual void PasteIKParams(IKClipObject *co,int which) {}
01964       virtual void InitIKJoints(InitJointData *posData,InitJointData *rotData) {}
01971       virtual BOOL GetIKJoints(InitJointData *posData,InitJointData *rotData) {return FALSE;}
01981       virtual BOOL GetDOFParams(TimeValue t,Matrix3 &ptm,DOFParams &dofs,BOOL nodeSel) {return FALSE;}
01994       virtual BOOL CreateLockKey(TimeValue t, int which) {return FALSE;}
02010       virtual void MirrorIKConstraints(int axis,int which,BOOL pasteMirror=FALSE) {}
02016       virtual BOOL TerminateIK() {return FALSE;} // controllers can act as terminators.
02017 
02018       // New for R4
02026       virtual void InitIKJoints2(InitJointData2 *posData,InitJointData2 *rotData) {}
02033       virtual BOOL GetIKJoints2(InitJointData2 *posData,InitJointData2 *rotData) {return FALSE;}
02034 
02035       // Called on a transform controller when the a message is received from a pin node
02055       virtual RefResult PinNodeChanged(RefMessage message,Interval changeInt, PartID &partID) {return REF_SUCCEED;}
02056 
02057       // Called on a transform controller when one of the node level IK parameters has been changed
02066       virtual void NodeIKParamsChanged() {}
02067 
02068       // Called in a transform controller when a node invalidates its TM cache
02073       virtual void TMInvalidated() {}
02074 
02075       // Let's the TM controller determine if it's OK to bind (IK bind) to a particular node.
02082       virtual BOOL OKToBindToNode(INode *node) {return TRUE;}
02083 
02084       // Ease curves
02093       virtual BOOL CanApplyEaseMultCurves() {return TRUE;}
02100       CoreExport TimeValue ApplyEase(TimeValue t,Interval &valid);
02104       CoreExport void AppendEaseCurve(Control *cont);
02108       CoreExport void DeleteEaseCurve(int i);
02111       CoreExport int NumEaseCurves();
02112 
02113       // Multiplier curves    
02121       CoreExport float GetMultVal(TimeValue t,Interval &valid);
02125       CoreExport void AppendMultCurve(Control *cont);
02129       CoreExport void DeleteMultCurve(int i);
02132       CoreExport int NumMultCurves();
02133 
02134       // These are implemented to handle ease curves. If a controller
02135       // is a leaf controller, then it MUST NOT BY DEFINITION have any
02136       // sub controllers or references. If it is a leaf controller, then
02137       // these are implemented to handle the ease curve list.
02138       // If it is NOT a leaf controller, then these can be overridden.
02139       CoreExport int NumRefs();
02140       CoreExport RefTargetHandle GetReference(int i);
02141 protected:
02142       CoreExport virtual void SetReference(int i, RefTargetHandle rtarg);
02143 public:
02144       CoreExport int NumSubs();
02145       CoreExport Animatable* SubAnim(int i);
02146       CoreExport MSTR SubAnimName(int i);
02147 
02148       // Default implementations of some Animatable methods
02149       CoreExport void* GetInterface(ULONG id);
02150       CoreExport int PaintFCurves(        
02151          ParamDimensionBase *dim,
02152          HDC hdc,
02153          Rect& rcGraph,
02154          Rect& rcPaint,
02155          float tzoom,
02156          int tscroll,
02157          float vzoom,
02158          int vscroll,
02159          DWORD flags );
02160       CoreExport int GetFCurveExtents(
02161          ParamDimensionBase *dim,
02162          float &min, float &max, DWORD flags);
02164       CoreExport virtual void BaseClone(ReferenceTarget *from, ReferenceTarget *to, RemapDir &remap);
02165 
02166 
02167       // This is called on transform controller after a node is
02168       // cloned and the clone process has finished
02174       virtual void PostCloneNode() {}
02175 
02176       // Slave TM controllers can implement this to prevent plug-ins
02177       // deleting their node via the DeleteNode API.
02185       virtual BOOL PreventNodeDeletion() {return FALSE;}
02186 
02187       // New interface for visibility float controllers to allow view dependent visibility
02188       // The default implementation will call GetValue()
02211       CoreExport virtual float EvalVisibility(TimeValue t, View& view, Box3 pbox, Interval& valid);
02212       
02213       // Called on visibility controllers. Gives them the option to completely hide an object in the viewports
02220       virtual BOOL VisibleInViewports() {return TRUE;}
02221 
02222       // Called on transform controllers or visibility controllers when a node is cloned and the user has chosen to instance
02228       virtual BOOL CanInstanceController() {return TRUE;}
02229 
02230       // Should be called by any leaf controller's clone method so
02231       // that ease and multipier curves are cloned.
02246       CoreExport void CloneControl(Control *ctrl,RemapDir &remap);
02247 
02248       //-------------------------------------------------------
02249       // Controllers that wish to have an apparatus available in
02250       // the scene will implement these methods:
02251       // NOTE: Most of these methods are duplicated in BaseObject or Object
02252       // (see object.h for descriptions).
02268       virtual int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) { return 0; };
02282       virtual int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) { return 0; }
02283       
02292       virtual  void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box) {}
02293 
02311       virtual void ActivateSubobjSel(int level, XFormModes& modes ) {}
02312 
02326       virtual void SelectSubComponent(CtrlHitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE) {}
02332       virtual void ClearSelection(int selLevel) {}
02346       virtual int SubObjectIndex(CtrlHitRecord *hitRec) {return 0;}     
02353       virtual void SelectAll(int selLevel) {}
02361       virtual void InvertSelection(int selLevel) {}
02362 
02375       virtual void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node) {}
02389       virtual void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node) {}
02390 
02391       // Modify sub object apparatuses
02403       virtual void SubMove( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}
02434       virtual void SubRotate( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin=FALSE ){}
02447       virtual void SubScale( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}      
02448       
02449       // Schematic View Animatable Overides...
02450       CoreExport virtual SvGraphNodeReference SvTraverseAnimGraph(IGraphObjectManager *gom, Animatable *object, int id, DWORD flags);
02451       CoreExport virtual MSTR SvGetName(IGraphObjectManager *gom, IGraphNode *gNode, bool isBeingEdited);
02452       CoreExport virtual bool SvHandleDoubleClick(IGraphObjectManager *gom, IGraphNode *gNode);
02453       CoreExport virtual bool SvCanInitiateLink(IGraphObjectManager *gom, IGraphNode *gNode);
02454       CoreExport virtual bool SvCanConcludeLink(IGraphObjectManager *gom, IGraphNode *gNode, IGraphNode *gNodeChild);
02455       CoreExport virtual bool SvLinkChild(IGraphObjectManager *gom, IGraphNode *gNodeThis, IGraphNode *gNodeChild);
02456       CoreExport virtual bool SvEditProperties(IGraphObjectManager *gom, IGraphNode *gNode);
02457 
02458       // Called when the user rescales time in the time configuration dialog. If FALSE
02459       // is returned from this method then MapKeys() will be used to perform the scaling. 
02460       // Controllers can override this method to handle things like rescaling tagents that 
02461       // MapKeys() won't affect and return TRUE if they don't want map keys to be called.
02472       virtual BOOL RescaleTime(Interval oseg, Interval nseg) {return FALSE;}
02473 
02474 //watje these are to allow a control to get sampled at a different rate than
02475 //what trackview does by default so the controller can speed up redraws
02476 //this is the pixel sample rate for when the curve is drawn
02486       virtual int GetDrawPixelStep() {return 5;}
02487 //this is the ticks sample rate for when the curve is checked for its y extents
02496       virtual int GetExtentTimeStep() {return 40;}
02497    };
02498 
02499 // Any controller that does not evaluate itself as a function of it's
02500 // input can subclass off this class.
02501 // GetValueLocalTime() will never ask the controller to apply the value,
02502 // it will always ask for it absolute.
02537 class StdControl : public Control {
02538    public:     
02567       virtual void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE)=0;
02586       virtual  void SetValueLocalTime(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE)=0;
02590       CoreExport void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
02594       CoreExport void SetValue(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE);
02595       // Computes the local components without calling parentMatrix
02596       // for position, rotation, and Scale controllers.
02597       CoreExport bool GetLocalTMComponents(TimeValue t, TMComponentsArg& cmpts, Matrix3Indirect& parentMatrix);
02598 
02655       virtual void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type)=0;
02656       
02663       virtual void *CreateTempValue()=0;
02667       virtual void DeleteTempValue(void *val)=0;
02675       virtual void ApplyValue(void *val, void *delta)=0;
02681       virtual void MultiplyValue(void *val, float m)=0;
02682    };
02683 
02684 // Each super class of controller may have a specific packet defined that
02685 // the 'val' pointer will point to instead of a literal value.
02686 // In reality, probably only the Transform controller will do this.
02687 enum SetXFormCommand { XFORM_MOVE, XFORM_ROTATE, XFORM_SCALE, XFORM_SET };
02739 class SetXFormPacket: public MaxHeapOperators {
02740    public:
02741       SetXFormCommand command;
02742       Matrix3 tmParent;
02743       Matrix3 tmAxis;      // if command is XFORM_SET, this will contain the new value for the XFORM.    
02744       Point3 p;
02745       Quat q;
02746       AngAxis aa;
02747       BOOL localOrigin;    
02748       
02749       // XFORM_SET
02756       SetXFormPacket(const Matrix3& mat,const Matrix3& par=Matrix3(1))
02757          {command=XFORM_SET,tmParent=par,tmAxis=mat;}
02758 
02759       // XFORM_MOVE
02768       SetXFormPacket(Point3 pt, const Matrix3& par=Matrix3(1), 
02769                   const Matrix3& a=Matrix3(1))
02770          {command=XFORM_MOVE;tmParent=par;tmAxis=a;p=pt;localOrigin=FALSE;}
02771 
02772       // XFORM_ROTATE
02783       SetXFormPacket(Quat qt, BOOL l, const Matrix3& par=Matrix3(1),
02784                   const Matrix3& a=Matrix3(1))
02785          {command=XFORM_ROTATE;tmParent=par;tmAxis=a;q=qt;aa=AngAxis(q);localOrigin=l;}
02796       SetXFormPacket(AngAxis aA, BOOL l, const Matrix3& par=Matrix3(1),
02797                   const Matrix3& a=Matrix3(1))
02798          {command=XFORM_ROTATE;tmParent=par;tmAxis=a;q=Quat(aA);aa=aA;localOrigin=l;}
02799 
02800       // XFORM_SCALE
02811       SetXFormPacket(Point3 pt, BOOL l, const Matrix3& par=Matrix3(1),
02812                   const Matrix3& a=Matrix3(1))
02813          {command=XFORM_SCALE;tmParent=par;tmAxis=a;p=pt;localOrigin=l;}
02814 
02815       // Just in case you want to do it by hand...
02818       SetXFormPacket() {};
02819    };
02820 
02821 
02822 
02823 // This is a special control base class for controllers that control
02824 // morphing of geomoetry.
02825 //
02826 // The 'val' pointer used with GetValue will point to an object state.
02827 // This would be the result of evaluating a combination of targets and
02828 // producing a new object that is some combination of the targets.
02829 //
02830 // The 'val' pointer used with SetValue will point to a 
02831 // SetMorphTargetPacket data structure. This has a pointer to
02832 // an object (entire pipeline) and the name of the target.
02833 
02834 // A pointer to one of these is passed to SetValue
02849 class SetMorphTargetPacket: public MaxHeapOperators {
02850    public:
02851       Matrix3 tm;
02852       Object* obj;
02853       MSTR name;
02854       BOOL forceCreate; // Make sure the key is created even if it is at frame 0
02857       SetMorphTargetPacket(Object *o,MSTR n,Matrix3 &m,BOOL fc=FALSE) {obj = o;name = n;tm = m;forceCreate=fc;}
02860       SetMorphTargetPacket(Object *o,MSTR n,BOOL fc=FALSE) {obj = o;name = n;tm = Matrix3(1);forceCreate=fc;}
02861    };
02862 
02891 class MorphControl : public Control {
02892    public:
02893       
02894       // Access the object pipelines of the controller's targets. Note
02895       // that these are pointers to the pipelines, not the result of
02896       // evaluating the pipelines.
02901       virtual int NumMorphTargs() {return 0;}
02911       virtual Object *GetMorphTarg(int i) {return NULL;}
02919       virtual void DeleteMorphTarg(int i) {}
02929       virtual void GetMorphTargName(int i,MSTR &name) {name.printf(_M("Target #%d"),i);}
02939       virtual void SetMorphTargName(int i,MSTR name) {}
02948       virtual Matrix3 GetMorphTargTM(int i) {return Matrix3(1);}
02949 
02950       // Checks an object to see if it is an acceptable target.
02961       virtual BOOL ValidTarget(TimeValue t,Object *obj) {return FALSE;}
02962 
02963       // When a \ref REFMSG_SELECT_BRANCH message is received the morph controller should
02964       // mark the target indicated and be prepared to return its ID from this method.
02972       virtual int GetFlaggedTarget() {return -1;}
02973 
02974       // Should call these methods on targets
02975       virtual BOOL HasUVW() { return 1; }
02976       virtual void SetGenUVW(BOOL sw) {  }
02977    };
02978 
02979 //-------------------------------------------------------------
02980 // Control base class for Master Controllers
02981 //
02982 
02989 class MasterPointControl : public Control {
02990    public:
02991       // Set the number of sub-controllers
03001       virtual  void SetNumSubControllers(int num, BOOL keep=FALSE) {}
03002       // Return the number of sub-controllers
03006       virtual  int    GetNumSubControllers() { return 0; }
03007       // Delete all the sub-controllers that are set to TRUE in the BitArray
03016       virtual void DeleteControlSet (BitArray set) {}
03017       // Add a new sub-controller
03025       virtual int  AddSubController(Control* ctrl) { return 0; }
03026       // Return i'th of sub-controller
03033       virtual Control* GetSubController(int i) { return NULL; }
03034       // Set the i'th sub-controller
03043       virtual  void SetSubController(int i, Control* ctrl) {}
03044 };
03045 
03046 #pragma warning(pop) // C4100 C4239
03047 
03048 //----------------------------------------------------------------//
03049 //
03050 // Some stuff to help with ORTs - these could actually be Interval methods
03051 
03052 inline TimeValue CycleTime(Interval i,TimeValue t)
03053    {
03054    int res, dur = i.Duration()-1;
03055    if (dur<=0) return t;      
03056    res   = (t-i.Start())%dur;
03057    if (t<i.Start()) {
03058       return i.End()+res;
03059    } else {
03060       return i.Start()+res;
03061       }
03062    }
03063 
03064 inline int NumCycles(Interval i,TimeValue t)
03065    {
03066    int dur = i.Duration()-1;
03067    if (dur<=0) return 1;
03068    if (t<i.Start()) {
03069       return (abs(t-i.Start())/dur)+1;
03070    } else 
03071    if (t>i.End()) {
03072       return (abs(t-i.End())/dur)+1;
03073    } else {
03074       return 0;
03075       }
03076    }
03077 
03078 
03079 
03080 // Types that use this template must support:
03081 //  T + T, T - T, T * float, T + float 
03082 
03083 template <class T> T LinearExtrapolate(TimeValue t0, TimeValue t1, T &val0, T &val1, T &endVal)
03084 {
03085     return (T)(endVal + (val1-val0) * float(t1-t0));
03086 }
03087 
03088 template <class T> T RepeatExtrapolate(Interval range, 
03089                                        TimeValue t, 
03090                                        T& startVal, 
03091                                        T& endVal, 
03092                                        T& cycleVal)
03093 {
03094     int cycles = NumCycles(range,t);
03095     T delta;
03096     if (t<range.Start()) {
03097         delta = startVal - endVal;
03098     } else {
03099         delta = endVal - startVal;
03100     }
03101     return (T)(cycleVal + delta * float(cycles));
03102 }
03103 
03104 template <class T> T IdentityExtrapolate(TimeValue endPoint, TimeValue t, T &endVal )
03105 {
03106     return (T)(endVal + float(t-endPoint));
03107 }
03108 
03109 CoreExport Quat LinearExtrapolate(TimeValue t0, TimeValue t1, Quat &val0, Quat &val1, Quat &endVal);
03110 CoreExport Quat RepeatExtrapolate(Interval range, TimeValue t, Quat &startVal, Quat &endVal, Quat &cycleVal);
03111 CoreExport Quat IdentityExtrapolate(TimeValue endPoint, TimeValue t, Quat &endVal );
03112 
03113 CoreExport ScaleValue LinearExtrapolate(TimeValue t0, TimeValue t1, ScaleValue &val0, ScaleValue &val1, ScaleValue &endVal);
03114 CoreExport ScaleValue RepeatExtrapolate(Interval range, TimeValue t, ScaleValue &startVal, ScaleValue &endVal, ScaleValue &cycleVal);
03115 CoreExport ScaleValue IdentityExtrapolate(TimeValue endPoint, TimeValue t, ScaleValue &endVal);
03116 
03117 
03118 template <class T> T LinearInterpolate(const T& v0,const T& v1,float u)
03119 {
03120     return (T)((1.0f-u)*v0 + u*v1);
03121 }
03122 
03123 inline Quat 
03124 LinearInterpolate(const Quat& v0,const Quat& v1,float u)
03125    {
03126    return Slerp(v0,v1,u);
03127    }
03128 
03129 inline ScaleValue 
03130 LinearInterpolate(const ScaleValue &v0,const ScaleValue &v1,float u)
03131    {
03132    ScaleValue res;
03133    res.s = ((float)1.0-u)*v0.s + u*v1.s;
03134    res.q = Slerp(v0.q,v1.q,u);
03135    return res;
03136    }
03137 
03138 
03139 inline Interval TestInterval(Interval iv, DWORD flags)
03140    {
03141    TimeValue start = iv.Start();
03142    TimeValue end = iv.End();
03143    if (!(flags&TIME_INCLEFT)) {
03144       start++;
03145       }  
03146    if (!(flags&TIME_INCRIGHT)) {
03147       end--;
03148       }
03149    if (end<start) {
03150       iv.SetEmpty();
03151    } else {
03152       iv.Set(start,end);
03153       }
03154    return iv;  
03155    }
03156 
03157 inline Quat ScaleQuat(Quat q, float s)
03158    {
03159    float angle;
03160    Point3 axis;
03161    AngAxisFromQ(q,&angle,axis);
03162    return QFromAngAxis(angle*s,axis);
03163    }
03164 
03165 //-------------------------------------------------------------------
03166 // A place to store values during Hold/Restore periods
03167 //
03168 //********************************************************
03169 // TempStore:  This is a temporary implementation:
03170 //  It uses a linear search-
03171 //  A hash-coded dictionary would be faster.
03172 //  (if there are ever a lot of entries)
03173 //********************************************************
03174 
03179 struct Slot: public MaxHeapOperators {
03180    void *key;
03181    void *pdata;
03182    int nbytes;
03183    Slot *next;
03184    public:
03186       Slot() { pdata = NULL; }
03188       CoreExport ~Slot();
03189 
03190    };
03191 
03202 class TempStore: public MaxHeapOperators {
03203    Slot *slotList;            
03204    Slot* Find(int n, void *data, void *ptr);
03205    public:
03207       TempStore() {  slotList = NULL;  }
03209       ~TempStore() { ClearAll(); }
03211       CoreExport void ClearAll();   // empty out the store 
03220       CoreExport void PutBytes(int n, void *data, void *ptr);
03229       CoreExport void GetBytes(int n, void *data, void *ptr);
03234       CoreExport void Clear(void *ptr);  // Remove single entry
03241       void PutFloat(float  f, void *ptr) {
03242           PutBytes(sizeof(float),(void *)&f,ptr);
03243           }
03249       CoreExport void PutInt(int i, void *ptr) {
03250           PutBytes(sizeof(int),(void *)&i,ptr);
03251           }
03258       CoreExport void GetFloat(float *f, void *ptr) { 
03259          GetBytes(sizeof(float),(void *)f,ptr);
03260          }
03267       CoreExport void GetInt(int *i, void *ptr) { 
03268          GetBytes(sizeof(int),(void *)i,ptr);
03269          }
03276       CoreExport void PutPoint3(Point3  f, void *ptr) {
03277           PutBytes(sizeof(Point3),(void *)&f,ptr);
03278           }
03285       CoreExport void GetPoint3(Point3 *f, void *ptr) { 
03286          GetBytes(sizeof(Point3),(void *)f,ptr);
03287          }
03288       CoreExport void PutPoint4(Point4  f, void *ptr) {
03289          PutBytes(sizeof(Point4),(void *)&f,ptr);
03290          }
03291       CoreExport void GetPoint4(Point4 *f, void *ptr) { 
03292          GetBytes(sizeof(Point4),(void *)f,ptr);
03293          }
03300       CoreExport void PutQuat( Quat  f, void *ptr) {
03301           PutBytes(sizeof(Quat),(void *)&f,ptr);
03302           }
03309       CoreExport void GetQuat( Quat *f, void *ptr) { 
03310          GetBytes(sizeof(Quat),(void *)f,ptr);
03311          }
03318       CoreExport void PutScaleValue( ScaleValue  f, void *ptr) {
03319           PutBytes(sizeof(ScaleValue),(void *)&f,ptr);
03320           }
03327       CoreExport void GetScaleValue( ScaleValue *f, void *ptr) { 
03328          GetBytes(sizeof(ScaleValue),(void *)f,ptr);
03329          }
03330    };
03331 
03332 
03333 extern CoreExport TempStore tmpStore;   // this should be in the scene data struct.
03334 
03335 
03336 CoreExport int Animating();    // is the animate switch on??
03337 CoreExport void AnimateOn();  // turn animate on
03338 CoreExport void AnimateOff();  // turn animate off
03339 CoreExport void SuspendAnimate(); // suspend animation (uses stack)
03340 CoreExport void ResumeAnimate();   // resume animation ( " )
03341 
03342 CoreExport BOOL AreWeAnimating(const TimeValue &t);
03343 CoreExport BOOL AreWeKeying(const TimeValue &t);
03344 
03345 
03346 CoreExport TimeValue GetAnimStart();
03347 CoreExport TimeValue GetAnimEnd();
03348 CoreExport void SetAnimStart(TimeValue s);
03349 CoreExport void SetAnimEnd(TimeValue e);
03350 
03351 CoreExport Control *NewDefaultFloatController();
03352 CoreExport Control *NewDefaultPoint3Controller();
03353 CoreExport Control *NewDefaultMatrix3Controller();
03354 CoreExport Control *NewDefaultPositionController();
03355 CoreExport Control *NewDefaultRotationController();
03356 CoreExport Control *NewDefaultScaleController();
03357 CoreExport Control *NewDefaultBoolController();
03358 CoreExport Control *NewDefaultColorController();
03359 CoreExport Control *NewDefaultMasterPointController();
03360 CoreExport Control *NewDefaultPoint4Controller();
03361 CoreExport Control *NewDefaultFRGBAController();
03362 CoreExport Control *NewDefaultPoint2Controller();
03363 
03364 CoreExport Control* CreateInterpFloat();
03365 CoreExport Control* CreateInterpPosition();
03366 CoreExport Control* CreateInterpPoint3();
03367 CoreExport Control* CreateInterpRotation();
03368 CoreExport Control* CreateInterpScale();
03369 CoreExport Control* CreatePRSControl();
03370 CoreExport Control* CreateLookatControl();
03371 CoreExport Control* CreateMasterPointControl();
03372 CoreExport Control* CreateInterpPoint4();
03373 CoreExport Control* CreateInterpPoint2();
03374 
03375 CoreExport void SetDefaultController(SClass_ID sid, ClassDesc *desc);
03376 CoreExport ClassDesc *GetDefaultController(SClass_ID sid);
03377 
03378 CoreExport void SetDefaultColorController(ClassDesc *desc);
03379 CoreExport void SetDefaultFRGBAController(ClassDesc *desc);
03380 CoreExport void SetDefaultBoolController(ClassDesc *desc);
03381 
03382 CoreExport BOOL GetSetKeyMode();
03383 CoreExport void SetSetKeyMode(BOOL onOff);
03384 
03385 CoreExport void SuspendSetKeyMode();
03386 CoreExport void ResumeSetKeyMode();
03387 CoreExport BOOL GetSetKeySuspended();
03388 CoreExport BOOL GetSetKeyModeStatus();
03389 
03390 CoreExport BOOL IsSetKeyModeFeatureEnabled();
03391