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

Generated on Fri May 16 08:32:20 2008 for SecondLife by  doxygen 1.5.5