diff options
Diffstat (limited to 'indra/llmath/xform.h')
-rw-r--r-- | indra/llmath/xform.h | 630 |
1 files changed, 315 insertions, 315 deletions
diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index a301e4ca47..0b583ce189 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -1,315 +1,315 @@ -/** - * @file xform.h - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_XFORM_H -#define LL_XFORM_H - -#include "v3math.h" -#include "m4math.h" -#include "llquaternion.h" - -constexpr F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f -constexpr F32 MIN_OBJECT_Z = -256.f; -constexpr F32 DEFAULT_MAX_PRIM_SCALE = 64.f; -constexpr F32 DEFAULT_MAX_PRIM_SCALE_NO_MESH = 10.f; -constexpr F32 MIN_PRIM_SCALE = 0.01f; -constexpr F32 MAX_PRIM_SCALE = 65536.f; // something very high but not near FLT_MAX - -class LLXform -{ -protected: - LLVector3 mPosition; - LLQuaternion mRotation; - LLVector3 mScale; - - //RN: TODO: move these world transform members to LLXformMatrix - // as they are *never* updated or accessed in the base class - LLVector3 mWorldPosition; - LLQuaternion mWorldRotation; - - LLXform* mParent; - U32 mChanged; - - bool mScaleChildOffset; - -public: - typedef enum e_changed_flags - { - UNCHANGED = 0x00, - TRANSLATED = 0x01, - ROTATED = 0x02, - SCALED = 0x04, - SHIFTED = 0x08, - GEOMETRY = 0x10, - TEXTURE = 0x20, - MOVED = TRANSLATED|ROTATED|SCALED, - SILHOUETTE = 0x40, - ALL_CHANGED = 0x7f - }EChangedFlags; - - void init() - { - mParent = NULL; - mChanged = UNCHANGED; - mPosition.setVec(0,0,0); - mRotation.loadIdentity(); - mScale. setVec(1,1,1); - mWorldPosition.clearVec(); - mWorldRotation.loadIdentity(); - mScaleChildOffset = false; - } - - LLXform(); - virtual ~LLXform(); - - void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); } - - inline bool setParent(LLXform *parent); - - inline void setPosition(const LLVector3& pos); - inline void setPosition(const F32 x, const F32 y, const F32 z); - inline void setPositionX(const F32 x); - inline void setPositionY(const F32 y); - inline void setPositionZ(const F32 z); - inline void addPosition(const LLVector3& pos); - - - inline void setScale(const LLVector3& scale); - inline void setScale(const F32 x, const F32 y, const F32 z); - inline void setRotation(const LLQuaternion& rot); - inline void setRotation(const F32 x, const F32 y, const F32 z); - inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s); - - // Above functions must be inline for speed, but also - // need to emit warnings. LL_WARNS() causes inline LLError::CallSite - // static objects that make more work for the linker. - // Avoid inline LL_WARNS() by calling this function. - void warn(const char* const msg); - - void setChanged(const U32 bits) { mChanged |= bits; } - bool isChanged() const { return mChanged; } - bool isChanged(const U32 bits) const { return mChanged & bits; } - void clearChanged() { mChanged = 0; } - void clearChanged(U32 bits) { mChanged &= ~bits; } - - void setScaleChildOffset(bool scale) { mScaleChildOffset = scale; } - bool getScaleChildOffset() { return mScaleChildOffset; } - - LLXform* getParent() const { return mParent; } - LLXform* getRoot() const; - virtual bool isRoot() const; - virtual bool isRootEdit() const; - - const LLVector3& getPosition() const { return mPosition; } - const LLVector3& getScale() const { return mScale; } - const LLQuaternion& getRotation() const { return mRotation; } - const LLVector3& getPositionW() const { return mWorldPosition; } - const LLQuaternion& getWorldRotation() const { return mWorldRotation; } - const LLVector3& getWorldPosition() const { return mWorldPosition; } -}; - -class LLXformMatrix : public LLXform -{ -public: - LLXformMatrix() : LLXform() {}; - virtual ~LLXformMatrix(); - - const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; } - void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; } - - void init() - { - mWorldMatrix.setIdentity(); - mMin.clearVec(); - mMax.clearVec(); - - LLXform::init(); - } - - void update(); - void updateMatrix(bool update_bounds = true); - void getMinMax(LLVector3& min,LLVector3& max) const; - -protected: - LLMatrix4 mWorldMatrix; - LLVector3 mMin; - LLVector3 mMax; - -}; - -bool LLXform::setParent(LLXform* parent) -{ - // Validate and make sure we're not creating a loop - if (parent == mParent) - { - return true; - } - if (parent) - { - LLXform *cur_par = parent->mParent; - while (cur_par) - { - if (cur_par == this) - { - //warn("LLXform::setParent Creating loop when setting parent!"); - return false; - } - cur_par = cur_par->mParent; - } - } - mParent = parent; - return true; -} - -void LLXform::setPosition(const LLVector3& pos) -{ - setChanged(TRANSLATED); - if (pos.isFinite()) - mPosition = pos; - else - { - mPosition.clearVec(); - warn("Non Finite in LLXform::setPosition(LLVector3)"); - } -} - -void LLXform::setPosition(const F32 x, const F32 y, const F32 z) -{ - setChanged(TRANSLATED); - if (llfinite(x) && llfinite(y) && llfinite(z)) - mPosition.setVec(x,y,z); - else - { - mPosition.clearVec(); - warn("Non Finite in LLXform::setPosition(F32,F32,F32)"); - } -} - -void LLXform::setPositionX(const F32 x) -{ - setChanged(TRANSLATED); - if (llfinite(x)) - mPosition.mV[VX] = x; - else - { - mPosition.mV[VX] = 0.f; - warn("Non Finite in LLXform::setPositionX"); - } -} - -void LLXform::setPositionY(const F32 y) -{ - setChanged(TRANSLATED); - if (llfinite(y)) - mPosition.mV[VY] = y; - else - { - mPosition.mV[VY] = 0.f; - warn("Non Finite in LLXform::setPositionY"); - } -} - -void LLXform::setPositionZ(const F32 z) -{ - setChanged(TRANSLATED); - if (llfinite(z)) - mPosition.mV[VZ] = z; - else - { - mPosition.mV[VZ] = 0.f; - warn("Non Finite in LLXform::setPositionZ"); - } -} - -void LLXform::addPosition(const LLVector3& pos) -{ - setChanged(TRANSLATED); - if (pos.isFinite()) - mPosition += pos; - else - warn("Non Finite in LLXform::addPosition"); -} - -void LLXform::setScale(const LLVector3& scale) -{ - setChanged(SCALED); - if (scale.isFinite()) - mScale = scale; - else - { - mScale.setVec(1.f, 1.f, 1.f); - warn("Non Finite in LLXform::setScale"); - } -} -void LLXform::setScale(const F32 x, const F32 y, const F32 z) -{ - setChanged(SCALED); - if (llfinite(x) && llfinite(y) && llfinite(z)) - mScale.setVec(x,y,z); - else - { - mScale.setVec(1.f, 1.f, 1.f); - warn("Non Finite in LLXform::setScale"); - } -} -void LLXform::setRotation(const LLQuaternion& rot) -{ - setChanged(ROTATED); - if (rot.isFinite()) - mRotation = rot; - else - { - mRotation.loadIdentity(); - warn("Non Finite in LLXform::setRotation"); - } -} -void LLXform::setRotation(const F32 x, const F32 y, const F32 z) -{ - setChanged(ROTATED); - if (llfinite(x) && llfinite(y) && llfinite(z)) - { - mRotation.setQuat(x,y,z); - } - else - { - mRotation.loadIdentity(); - warn("Non Finite in LLXform::setRotation"); - } -} -void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) -{ - setChanged(ROTATED); - if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s)) - { - mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s; - } - else - { - mRotation.loadIdentity(); - warn("Non Finite in LLXform::setRotation"); - } -} - -#endif +/**
+ * @file xform.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_XFORM_H
+#define LL_XFORM_H
+
+#include "v3math.h"
+#include "m4math.h"
+#include "llquaternion.h"
+
+constexpr F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f
+constexpr F32 MIN_OBJECT_Z = -256.f;
+constexpr F32 DEFAULT_MAX_PRIM_SCALE = 64.f;
+constexpr F32 DEFAULT_MAX_PRIM_SCALE_NO_MESH = 10.f;
+constexpr F32 MIN_PRIM_SCALE = 0.01f;
+constexpr F32 MAX_PRIM_SCALE = 65536.f; // something very high but not near FLT_MAX
+
+class LLXform
+{
+protected:
+ LLVector3 mPosition;
+ LLQuaternion mRotation;
+ LLVector3 mScale;
+
+ //RN: TODO: move these world transform members to LLXformMatrix
+ // as they are *never* updated or accessed in the base class
+ LLVector3 mWorldPosition;
+ LLQuaternion mWorldRotation;
+
+ LLXform* mParent;
+ U32 mChanged;
+
+ bool mScaleChildOffset;
+
+public:
+ typedef enum e_changed_flags
+ {
+ UNCHANGED = 0x00,
+ TRANSLATED = 0x01,
+ ROTATED = 0x02,
+ SCALED = 0x04,
+ SHIFTED = 0x08,
+ GEOMETRY = 0x10,
+ TEXTURE = 0x20,
+ MOVED = TRANSLATED|ROTATED|SCALED,
+ SILHOUETTE = 0x40,
+ ALL_CHANGED = 0x7f
+ }EChangedFlags;
+
+ void init()
+ {
+ mParent = NULL;
+ mChanged = UNCHANGED;
+ mPosition.setVec(0,0,0);
+ mRotation.loadIdentity();
+ mScale. setVec(1,1,1);
+ mWorldPosition.clearVec();
+ mWorldRotation.loadIdentity();
+ mScaleChildOffset = false;
+ }
+
+ LLXform();
+ virtual ~LLXform();
+
+ void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); }
+
+ inline bool setParent(LLXform *parent);
+
+ inline void setPosition(const LLVector3& pos);
+ inline void setPosition(const F32 x, const F32 y, const F32 z);
+ inline void setPositionX(const F32 x);
+ inline void setPositionY(const F32 y);
+ inline void setPositionZ(const F32 z);
+ inline void addPosition(const LLVector3& pos);
+
+
+ inline void setScale(const LLVector3& scale);
+ inline void setScale(const F32 x, const F32 y, const F32 z);
+ inline void setRotation(const LLQuaternion& rot);
+ inline void setRotation(const F32 x, const F32 y, const F32 z);
+ inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s);
+
+ // Above functions must be inline for speed, but also
+ // need to emit warnings. LL_WARNS() causes inline LLError::CallSite
+ // static objects that make more work for the linker.
+ // Avoid inline LL_WARNS() by calling this function.
+ void warn(const char* const msg);
+
+ void setChanged(const U32 bits) { mChanged |= bits; }
+ bool isChanged() const { return mChanged; }
+ bool isChanged(const U32 bits) const { return mChanged & bits; }
+ void clearChanged() { mChanged = 0; }
+ void clearChanged(U32 bits) { mChanged &= ~bits; }
+
+ void setScaleChildOffset(bool scale) { mScaleChildOffset = scale; }
+ bool getScaleChildOffset() { return mScaleChildOffset; }
+
+ LLXform* getParent() const { return mParent; }
+ LLXform* getRoot() const;
+ virtual bool isRoot() const;
+ virtual bool isRootEdit() const;
+
+ const LLVector3& getPosition() const { return mPosition; }
+ const LLVector3& getScale() const { return mScale; }
+ const LLQuaternion& getRotation() const { return mRotation; }
+ const LLVector3& getPositionW() const { return mWorldPosition; }
+ const LLQuaternion& getWorldRotation() const { return mWorldRotation; }
+ const LLVector3& getWorldPosition() const { return mWorldPosition; }
+};
+
+class LLXformMatrix : public LLXform
+{
+public:
+ LLXformMatrix() : LLXform() {};
+ virtual ~LLXformMatrix();
+
+ const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; }
+ void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; }
+
+ void init()
+ {
+ mWorldMatrix.setIdentity();
+ mMin.clearVec();
+ mMax.clearVec();
+
+ LLXform::init();
+ }
+
+ void update();
+ void updateMatrix(bool update_bounds = true);
+ void getMinMax(LLVector3& min,LLVector3& max) const;
+
+protected:
+ LLMatrix4 mWorldMatrix;
+ LLVector3 mMin;
+ LLVector3 mMax;
+
+};
+
+bool LLXform::setParent(LLXform* parent)
+{
+ // Validate and make sure we're not creating a loop
+ if (parent == mParent)
+ {
+ return true;
+ }
+ if (parent)
+ {
+ LLXform *cur_par = parent->mParent;
+ while (cur_par)
+ {
+ if (cur_par == this)
+ {
+ //warn("LLXform::setParent Creating loop when setting parent!");
+ return false;
+ }
+ cur_par = cur_par->mParent;
+ }
+ }
+ mParent = parent;
+ return true;
+}
+
+void LLXform::setPosition(const LLVector3& pos)
+{
+ setChanged(TRANSLATED);
+ if (pos.isFinite())
+ mPosition = pos;
+ else
+ {
+ mPosition.clearVec();
+ warn("Non Finite in LLXform::setPosition(LLVector3)");
+ }
+}
+
+void LLXform::setPosition(const F32 x, const F32 y, const F32 z)
+{
+ setChanged(TRANSLATED);
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ mPosition.setVec(x,y,z);
+ else
+ {
+ mPosition.clearVec();
+ warn("Non Finite in LLXform::setPosition(F32,F32,F32)");
+ }
+}
+
+void LLXform::setPositionX(const F32 x)
+{
+ setChanged(TRANSLATED);
+ if (llfinite(x))
+ mPosition.mV[VX] = x;
+ else
+ {
+ mPosition.mV[VX] = 0.f;
+ warn("Non Finite in LLXform::setPositionX");
+ }
+}
+
+void LLXform::setPositionY(const F32 y)
+{
+ setChanged(TRANSLATED);
+ if (llfinite(y))
+ mPosition.mV[VY] = y;
+ else
+ {
+ mPosition.mV[VY] = 0.f;
+ warn("Non Finite in LLXform::setPositionY");
+ }
+}
+
+void LLXform::setPositionZ(const F32 z)
+{
+ setChanged(TRANSLATED);
+ if (llfinite(z))
+ mPosition.mV[VZ] = z;
+ else
+ {
+ mPosition.mV[VZ] = 0.f;
+ warn("Non Finite in LLXform::setPositionZ");
+ }
+}
+
+void LLXform::addPosition(const LLVector3& pos)
+{
+ setChanged(TRANSLATED);
+ if (pos.isFinite())
+ mPosition += pos;
+ else
+ warn("Non Finite in LLXform::addPosition");
+}
+
+void LLXform::setScale(const LLVector3& scale)
+{
+ setChanged(SCALED);
+ if (scale.isFinite())
+ mScale = scale;
+ else
+ {
+ mScale.setVec(1.f, 1.f, 1.f);
+ warn("Non Finite in LLXform::setScale");
+ }
+}
+void LLXform::setScale(const F32 x, const F32 y, const F32 z)
+{
+ setChanged(SCALED);
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ mScale.setVec(x,y,z);
+ else
+ {
+ mScale.setVec(1.f, 1.f, 1.f);
+ warn("Non Finite in LLXform::setScale");
+ }
+}
+void LLXform::setRotation(const LLQuaternion& rot)
+{
+ setChanged(ROTATED);
+ if (rot.isFinite())
+ mRotation = rot;
+ else
+ {
+ mRotation.loadIdentity();
+ warn("Non Finite in LLXform::setRotation");
+ }
+}
+void LLXform::setRotation(const F32 x, const F32 y, const F32 z)
+{
+ setChanged(ROTATED);
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ {
+ mRotation.setQuat(x,y,z);
+ }
+ else
+ {
+ mRotation.loadIdentity();
+ warn("Non Finite in LLXform::setRotation");
+ }
+}
+void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
+{
+ setChanged(ROTATED);
+ if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s))
+ {
+ mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s;
+ }
+ else
+ {
+ mRotation.loadIdentity();
+ warn("Non Finite in LLXform::setRotation");
+ }
+}
+
+#endif
|