xform.h

Go to the documentation of this file.
00001 
00031 #ifndef LL_XFORM_H
00032 #define LL_XFORM_H
00033 
00034 #include "v3math.h"
00035 #include "m4math.h"
00036 #include "llquaternion.h"
00037 
00038 const F32 MAX_OBJECT_Z          = 768.f;
00039 const F32 MIN_OBJECT_Z          = -256.f;
00040 const F32 MIN_OBJECT_SCALE      = 0.01f;
00041 const F32 MAX_OBJECT_SCALE      = 10.f;
00042 
00043 class LLXform
00044 {
00045 protected:
00046         LLVector3         mPosition;
00047         LLQuaternion  mRotation; 
00048         LLVector3         mScale;
00049         
00050         //RN: TODO: move these world transform members to LLXformMatrix
00051         // as they are *never* updated or accessed in the base class
00052         LLVector3         mWorldPosition;
00053         LLQuaternion  mWorldRotation;
00054 
00055         LLXform*      mParent;
00056         U32                       mChanged;
00057 
00058         BOOL              mScaleChildOffset;
00059 
00060 public:
00061         typedef enum e_changed_flags
00062         {
00063                 UNCHANGED       = 0x00,
00064                 TRANSLATED      = 0x01,
00065                 ROTATED         = 0x02,
00066                 SCALED          = 0x04,
00067                 SHIFTED         = 0x08,
00068                 GEOMETRY        = 0x10,
00069                 TEXTURE         = 0x20,
00070                 MOVED       = TRANSLATED|ROTATED|SCALED,
00071                 SILHOUETTE      = 0x40,
00072                 ALL_CHANGED = 0x7f
00073         }EChangedFlags;
00074 
00075         void init()
00076         {
00077                 mParent  = NULL;
00078                 mChanged = UNCHANGED;
00079                 mPosition.setVec(0,0,0);
00080                 mRotation.loadIdentity();
00081                 mScale.   setVec(1,1,1);
00082                 mWorldPosition.clearVec();
00083                 mWorldRotation.loadIdentity();
00084                 mScaleChildOffset = FALSE;
00085         }
00086 
00087          LLXform();
00088         virtual ~LLXform();
00089 
00090         void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); }
00091 
00092         inline BOOL setParent(LLXform *parent);
00093 
00094         inline void setPosition(const LLVector3& pos);
00095         inline void setPosition(const F32 x, const F32 y, const F32 z);
00096         inline void setPositionX(const F32 x);
00097         inline void setPositionY(const F32 y);
00098         inline void setPositionZ(const F32 z);
00099         inline void addPosition(const LLVector3& pos);
00100 
00101 
00102         inline void setScale(const LLVector3& scale);
00103         inline void setScale(const F32 x, const F32 y, const F32 z);
00104         inline void setRotation(const LLQuaternion& rot);
00105         inline void setRotation(const F32 x, const F32 y, const F32 z);
00106         inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s);
00107         
00108         void            setChanged(const U32 bits)                                      { mChanged |= bits; }
00109         BOOL            isChanged() const                                                       { return mChanged; }
00110         BOOL            isChanged(const U32 bits) const                         { return mChanged & bits; }
00111         void            clearChanged()                                                          { mChanged = 0; }
00112         void        clearChanged(U32 bits)                      { mChanged &= ~bits; }
00113 
00114         void            setScaleChildOffset(BOOL scale)                         { mScaleChildOffset = scale; }
00115         BOOL            getScaleChildOffset()                                           { return mScaleChildOffset; }
00116 
00117         LLXform* getParent() const { return mParent; }
00118         LLXform* getRoot() const;
00119         virtual BOOL isRoot() const;
00120         virtual BOOL isRootEdit() const;
00121 
00122         const LLVector3&        getPosition()  const        { return mPosition; }
00123         const LLVector3&        getScale() const                        { return mScale; }
00124         const LLQuaternion& getRotation() const                 { return mRotation; }
00125         const LLVector3&        getPositionW() const            { return mWorldPosition; }
00126         const LLQuaternion& getWorldRotation() const    { return mWorldRotation; }
00127         const LLVector3&        getWorldPosition() const        { return mWorldPosition; }
00128 };
00129 
00130 class LLXformMatrix : public LLXform
00131 {
00132 public:
00133         LLXformMatrix() : LLXform() {};
00134         virtual ~LLXformMatrix();
00135 
00136         const LLMatrix4&    getWorldMatrix() const      { return mWorldMatrix; }
00137         void setWorldMatrix (const LLMatrix4& mat)   { mWorldMatrix = mat; }
00138 
00139         void init()
00140         {
00141                 mWorldMatrix.identity();
00142                 mMin.clearVec();
00143                 mMax.clearVec();
00144 
00145                 LLXform::init();
00146         }
00147 
00148         void update();
00149         void updateMatrix(BOOL update_bounds = TRUE);
00150         void getMinMax(LLVector3& min,LLVector3& max) const;
00151 
00152 protected:
00153         LLMatrix4       mWorldMatrix;
00154         LLVector3       mMin;
00155         LLVector3       mMax;
00156 
00157 };
00158 
00159 BOOL LLXform::setParent(LLXform* parent)
00160 {
00161         // Validate and make sure we're not creating a loop
00162         if (parent == mParent)
00163         {
00164                 return TRUE;
00165         }
00166         if (parent)
00167         {
00168                 LLXform *cur_par = parent->mParent;
00169                 while (cur_par)
00170                 {
00171                         if (cur_par == this)
00172                         {
00173                                 llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl;
00174                                 return FALSE;
00175                         }
00176                         cur_par = cur_par->mParent;
00177                 }
00178         }
00179         mParent = parent;
00180         return TRUE;
00181 }
00182 
00183 void LLXform::setPosition(const LLVector3& pos)                 
00184 {
00185         setChanged(TRANSLATED);
00186         if (pos.isFinite())
00187                 mPosition = pos; 
00188         else
00189         {
00190                 mPosition.clearVec();
00191                 llwarns << "Non Finite in LLXform::setPosition(LLVector3)" << llendl;
00192         }
00193 }
00194 
00195 void LLXform::setPosition(const F32 x, const F32 y, const F32 z)
00196 {
00197         setChanged(TRANSLATED);
00198         if (llfinite(x) && llfinite(y) && llfinite(z))
00199                 mPosition.setVec(x,y,z); 
00200         else
00201         {
00202                 mPosition.clearVec();
00203                 llwarns << "Non Finite in LLXform::setPosition(F32,F32,F32)" << llendl;
00204         }
00205 }
00206 
00207 void LLXform::setPositionX(const F32 x)
00208 { 
00209         setChanged(TRANSLATED);
00210         if (llfinite(x))
00211                 mPosition.mV[VX] = x; 
00212         else
00213         {
00214                 mPosition.mV[VX] = 0.f;
00215                 llwarns << "Non Finite in LLXform::setPositionX" << llendl;
00216         }
00217 }
00218 
00219 void LLXform::setPositionY(const F32 y)
00220 { 
00221         setChanged(TRANSLATED);
00222         if (llfinite(y))
00223                 mPosition.mV[VY] = y; 
00224         else
00225         {
00226                 mPosition.mV[VY] = 0.f;
00227                 llwarns << "Non Finite in LLXform::setPositionY" << llendl;
00228         }
00229 }
00230 
00231 void LLXform::setPositionZ(const F32 z)
00232 { 
00233         setChanged(TRANSLATED);
00234         if (llfinite(z))
00235                 mPosition.mV[VZ] = z; 
00236         else
00237         {
00238                 mPosition.mV[VZ] = 0.f;
00239                 llwarns << "Non Finite in LLXform::setPositionZ" << llendl;
00240         }
00241 }
00242 
00243 void LLXform::addPosition(const LLVector3& pos)
00244 { 
00245         setChanged(TRANSLATED);
00246         if (pos.isFinite())
00247                 mPosition += pos; 
00248         else
00249                 llwarns << "Non Finite in LLXform::addPosition" << llendl;
00250 }
00251 
00252 void LLXform::setScale(const LLVector3& scale)
00253 { 
00254         setChanged(SCALED);
00255         if (scale.isFinite())
00256                 mScale = scale; 
00257         else
00258         {
00259                 mScale.setVec(1.f, 1.f, 1.f);
00260                 llwarns << "Non Finite in LLXform::setScale" << llendl;
00261         }
00262 }
00263 void LLXform::setScale(const F32 x, const F32 y, const F32 z)
00264 { 
00265         setChanged(SCALED);
00266         if (llfinite(x) && llfinite(y) && llfinite(z))
00267                 mScale.setVec(x,y,z); 
00268         else
00269         {
00270                 mScale.setVec(1.f, 1.f, 1.f);
00271                 llwarns << "Non Finite in LLXform::setScale" << llendl;
00272         }
00273 }
00274 void LLXform::setRotation(const LLQuaternion& rot)
00275 { 
00276         setChanged(ROTATED);
00277         if (rot.isFinite())
00278                 mRotation = rot; 
00279         else
00280         {
00281                 mRotation.loadIdentity();
00282                 llwarns << "Non Finite in LLXform::setRotation" << llendl;
00283         }
00284 }
00285 void LLXform::setRotation(const F32 x, const F32 y, const F32 z) 
00286 { 
00287         setChanged(ROTATED);
00288         if (llfinite(x) && llfinite(y) && llfinite(z))
00289         {
00290                 mRotation.setQuat(x,y,z); 
00291         }
00292         else
00293         {
00294                 mRotation.loadIdentity();
00295                 llwarns << "Non Finite in LLXform::setRotation" << llendl;
00296         }
00297 }
00298 void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) 
00299 { 
00300         setChanged(ROTATED);
00301         if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s))
00302         {
00303                 mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s; 
00304         }
00305         else
00306         {
00307                 mRotation.loadIdentity();
00308                 llwarns << "Non Finite in LLXform::setRotation" << llendl;
00309         }
00310 }
00311 
00312 #endif

Generated on Thu Jul 1 06:10:03 2010 for Second Life Viewer by  doxygen 1.4.7