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
00051
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
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