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;
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;
00043
00044
00045 class LLXform
00046 {
00047 protected:
00048 LLVector3 mPosition;
00049 LLQuaternion mRotation;
00050 LLVector3 mScale;
00051
00052
00053
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
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