summaryrefslogtreecommitdiff
path: root/indra/llmath/xform.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath/xform.h')
-rw-r--r--indra/llmath/xform.h630
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