summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/CMakeLists.txt5
-rw-r--r--indra/llmath/llbbox.cpp160
-rw-r--r--indra/llmath/llbbox.h103
-rw-r--r--indra/llmath/llbboxlocal.h3
-rw-r--r--indra/llmath/llmath.h4
-rw-r--r--indra/llmath/lloctree.h10
-rw-r--r--indra/llmath/llrect.h50
-rw-r--r--indra/llmath/llsdutil_math.cpp5
-rw-r--r--indra/llmath/llvolume.cpp8
-rw-r--r--indra/llmath/llvolume.h12
-rw-r--r--indra/llmath/llvolumemgr.h6
-rw-r--r--indra/llmath/v3color.cpp36
-rw-r--r--indra/llmath/v3color.h1
-rw-r--r--indra/llmath/v3dmath.h8
-rw-r--r--indra/llmath/v3math.cpp6
-rw-r--r--indra/llmath/v3math.h4
-rw-r--r--indra/llmath/v4color.cpp70
-rw-r--r--indra/llmath/v4color.h24
-rw-r--r--indra/llmath/v4coloru.h14
-rw-r--r--indra/llmath/xform.h2
20 files changed, 438 insertions, 93 deletions
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 075d3b3af0..2bb3800144 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -10,6 +10,7 @@ include_directories(
)
set(llmath_SOURCE_FILES
+ llbbox.cpp
llbboxlocal.cpp
llcamera.cpp
llcoordframe.cpp
@@ -39,6 +40,7 @@ set(llmath_HEADER_FILES
camera.h
coordframe.h
+ llbbox.h
llbboxlocal.h
llcamera.h
llcoord.h
@@ -83,7 +85,8 @@ add_library (llmath ${llmath_SOURCE_FILES})
include(LLAddBuildTest)
SET(llmath_TEST_SOURCE_FILES
- # WARNING: Please don't write tests against LLCommon or LLMath until this issue is resolved: https://jira.lindenlab.com/jira/browse/DEV-29456
+ # nat 2009-08-28: found this commented out and considered implementing it
+ # using LL_ADD_INTEGRATION_TEST, but there's no llvolume_test.cpp source?
# llvolume.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llmath "${llmath_TEST_SOURCE_FILES}")
diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp
new file mode 100644
index 0000000000..acf93a2a38
--- /dev/null
+++ b/indra/llmath/llbbox.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llbbox.cpp
+ * @brief General purpose bounding box class (Not axis aligned)
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// self include
+#include "llbbox.h"
+
+// library includes
+#include "m4math.h"
+
+void LLBBox::addPointLocal(const LLVector3& p)
+{
+ if (mEmpty)
+ {
+ mMinLocal = p;
+ mMaxLocal = p;
+ mEmpty = FALSE;
+ }
+ else
+ {
+ mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] );
+ mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] );
+ mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] );
+ mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] );
+ mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] );
+ mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] );
+ }
+}
+
+void LLBBox::addPointAgent( LLVector3 p)
+{
+ p -= mPosAgent;
+ p.rotVec( ~mRotation );
+ addPointLocal( p );
+}
+
+
+void LLBBox::addBBoxAgent(const LLBBox& b)
+{
+ if (mEmpty)
+ {
+ mPosAgent = b.mPosAgent;
+ mRotation = b.mRotation;
+ mMinLocal.clearVec();
+ mMaxLocal.clearVec();
+ }
+ LLVector3 vertex[8];
+ vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+
+ LLMatrix4 m( b.mRotation );
+ m.translate( b.mPosAgent );
+ m.translate( -mPosAgent );
+ m.rotate( ~mRotation );
+
+ for( S32 i=0; i<8; i++ )
+ {
+ addPointLocal( vertex[i] * m );
+ }
+}
+
+
+void LLBBox::expand( F32 delta )
+{
+ mMinLocal.mV[VX] -= delta;
+ mMinLocal.mV[VY] -= delta;
+ mMinLocal.mV[VZ] -= delta;
+ mMaxLocal.mV[VX] += delta;
+ mMaxLocal.mV[VY] += delta;
+ mMaxLocal.mV[VZ] += delta;
+}
+
+LLVector3 LLBBox::localToAgent(const LLVector3& v) const
+{
+ LLMatrix4 m( mRotation );
+ m.translate( mPosAgent );
+ return v * m;
+}
+
+LLVector3 LLBBox::agentToLocal(const LLVector3& v) const
+{
+ LLMatrix4 m;
+ m.translate( -mPosAgent );
+ m.rotate( ~mRotation ); // inverse rotation
+ return v * m;
+}
+
+LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const
+{
+ LLMatrix4 m( mRotation );
+ return v * m;
+}
+
+LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const
+{
+ LLMatrix4 m( ~mRotation ); // inverse rotation
+ return v * m;
+}
+
+BOOL LLBBox::containsPointLocal(const LLVector3& p) const
+{
+ if ( (p.mV[VX] < mMinLocal.mV[VX])
+ ||(p.mV[VX] > mMaxLocal.mV[VX])
+ ||(p.mV[VY] < mMinLocal.mV[VY])
+ ||(p.mV[VY] > mMaxLocal.mV[VY])
+ ||(p.mV[VZ] < mMinLocal.mV[VZ])
+ ||(p.mV[VZ] > mMaxLocal.mV[VZ]))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL LLBBox::containsPointAgent(const LLVector3& p) const
+{
+ LLVector3 point_local = agentToLocal(p);
+ return containsPointLocal(point_local);
+}
+
+
+/*
+LLBBox operator*(const LLBBox &a, const LLMatrix4 &b)
+{
+ return LLBBox( a.mMin * b, a.mMax * b );
+}
+*/
diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h
new file mode 100644
index 0000000000..cd29551b01
--- /dev/null
+++ b/indra/llmath/llbbox.h
@@ -0,0 +1,103 @@
+/**
+ * @file llbbox.h
+ * @brief General purpose bounding box class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_BBOX_H
+#define LL_BBOX_H
+
+#include "v3math.h"
+#include "llquaternion.h"
+
+// Note: "local space" for an LLBBox is defined relative to agent space in terms of
+// a translation followed by a rotation. There is no scale term since the LLBBox's min and
+// max are not necessarily symetrical and define their own extents.
+
+class LLBBox
+{
+public:
+ LLBBox() {mEmpty = TRUE;}
+ LLBBox( const LLVector3& pos_agent,
+ const LLQuaternion& rot,
+ const LLVector3& min_local,
+ const LLVector3& max_local )
+ :
+ mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE )
+ {}
+
+ // Default copy constructor is OK.
+
+ const LLVector3& getPositionAgent() const { return mPosAgent; }
+ const LLQuaternion& getRotation() const { return mRotation; }
+
+ const LLVector3& getMinLocal() const { return mMinLocal; }
+ void setMinLocal( const LLVector3& min ) { mMinLocal = min; }
+
+ const LLVector3& getMaxLocal() const { return mMaxLocal; }
+ void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; }
+
+ LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; }
+ LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); }
+
+ LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; }
+
+ BOOL containsPointLocal(const LLVector3& p) const;
+ BOOL containsPointAgent(const LLVector3& p) const;
+
+ void addPointAgent(LLVector3 p);
+ void addBBoxAgent(const LLBBox& b);
+
+ void addPointLocal(const LLVector3& p);
+ void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); }
+
+ void expand( F32 delta );
+
+ LLVector3 localToAgent( const LLVector3& v ) const;
+ LLVector3 agentToLocal( const LLVector3& v ) const;
+
+ // Changes rotation but not position
+ LLVector3 localToAgentBasis(const LLVector3& v) const;
+ LLVector3 agentToLocalBasis(const LLVector3& v) const;
+
+
+// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b);
+
+private:
+ LLVector3 mMinLocal;
+ LLVector3 mMaxLocal;
+ LLVector3 mPosAgent; // Position relative to Agent's Region
+ LLQuaternion mRotation;
+ BOOL mEmpty; // Nothing has been added to this bbox yet
+};
+
+//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b);
+
+
+#endif // LL_BBOX_H
diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h
index d69028e3aa..0d1e5a3ae5 100644
--- a/indra/llmath/llbboxlocal.h
+++ b/indra/llmath/llbboxlocal.h
@@ -53,9 +53,6 @@ public:
LLVector3 getCenter() const { return (mMax - mMin) * 0.5f + mMin; }
LLVector3 getExtent() const { return mMax - mMin; }
- BOOL containsPoint(const LLVector3& p) const;
- BOOL intersects(const LLBBoxLocal& b) const;
-
void addPoint(const LLVector3& p);
void addBBox(const LLBBoxLocal& b) { addPoint( b.mMin ); addPoint( b.mMax ); }
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 66451b1a27..f85c4f39f4 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -36,8 +36,8 @@
#include <cmath>
#include <cstdlib>
#include "lldefs.h"
-#include "llstl.h" // *TODO: Remove when LLString is gone
-#include "llstring.h" // *TODO: Remove when LLString is gone
+//#include "llstl.h" // *TODO: Remove when LLString is gone
+//#include "llstring.h" // *TODO: Remove when LLString is gone
// lltut.h uses is_approx_equal_fraction(). This was moved to its own header
// file in llcommon so we can use lltut.h for llcommon tests without making
// llcommon depend on llmath.
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index bced84cb1c..ba8776690a 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -65,11 +65,10 @@ public:
};
template <class T>
-class LLOctreeTraveler : public LLTreeTraveler<T>
+class LLOctreeTraveler
{
public:
- virtual void traverse(const LLTreeNode<T>* node);
- virtual void visit(const LLTreeNode<T>* state) { }
+ virtual void traverse(const LLOctreeNode<T>* node);
virtual void visit(const LLOctreeNode<T>* branch) = 0;
};
@@ -700,19 +699,16 @@ public:
}
};
-
//========================
// LLOctreeTraveler
//========================
template <class T>
-void LLOctreeTraveler<T>::traverse(const LLTreeNode<T>* tree_node)
+void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
{
- const LLOctreeNode<T>* node = (const LLOctreeNode<T>*) tree_node;
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
{
traverse(node->getChild(i));
}
}
-
#endif
diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h
index 9eb58dbbe9..c03a331aff 100644
--- a/indra/llmath/llrect.h
+++ b/indra/llmath/llrect.h
@@ -64,23 +64,17 @@ public:
mLeft(left), mTop(top), mRight(right), mBottom(bottom)
{}
- LLRectBase(const LLSD& sd)
+ explicit LLRectBase(const LLSD& sd)
{
setValue(sd);
}
- const LLRectBase& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
void setValue(const LLSD& sd)
{
- mLeft = sd[0].asInteger();
- mTop = sd[1].asInteger();
- mRight = sd[2].asInteger();
- mBottom = sd[3].asInteger();
+ mLeft = (Type)sd[0].asInteger();
+ mTop = (Type)sd[1].asInteger();
+ mRight = (Type)sd[2].asInteger();
+ mBottom = (Type)sd[3].asInteger();
}
LLSD getValue() const
@@ -147,10 +141,20 @@ public:
// Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect
// returns TRUE if any part of rect is is inside this LLRect
- BOOL rectInRect(const LLRectBase* rect) const
+ BOOL overlaps(const LLRectBase& rect) const
+ {
+ return !(mLeft > rect.mRight
+ || mRight < rect.mLeft
+ || mBottom > rect.mTop
+ || mTop < rect.mBottom);
+ }
+
+ BOOL contains(const LLRectBase& rect) const
{
- return mLeft <= rect->mRight && rect->mLeft <= mRight &&
- mBottom <= rect->mTop && rect->mBottom <= mTop ;
+ return mLeft <= rect.mLeft
+ && mRight >= rect.mRight
+ && mBottom <= rect.mBottom
+ && mTop >= rect.mTop;
}
LLRectBase& set(Type left, Type top, Type right, Type bottom)
@@ -229,26 +233,25 @@ public:
return mLeft <= mRight && mBottom <= mTop;
}
- bool isNull() const
+ bool isEmpty() const
{
return mLeft == mRight || mBottom == mTop;
}
- bool notNull() const
+ bool notEmpty() const
{
- return !isNull();
+ return !isEmpty();
}
- LLRectBase& unionWith(const LLRectBase &other)
+ void unionWith(const LLRectBase &other)
{
mLeft = llmin(mLeft, other.mLeft);
mRight = llmax(mRight, other.mRight);
mBottom = llmin(mBottom, other.mBottom);
mTop = llmax(mTop, other.mTop);
- return *this;
}
- LLRectBase& intersectWith(const LLRectBase &other)
+ void intersectWith(const LLRectBase &other)
{
mLeft = llmax(mLeft, other.mLeft);
mRight = llmin(mRight, other.mRight);
@@ -262,7 +265,6 @@ public:
{
mBottom = mTop;
}
- return *this;
}
friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect)
@@ -271,8 +273,8 @@ public:
<< " W " << rect.getWidth() << " H " << rect.getHeight() << " }";
return s;
}
-
- bool operator==(const LLRectBase &b)
+
+ bool operator==(const LLRectBase &b) const
{
return ((mLeft == b.mLeft) &&
(mTop == b.mTop) &&
@@ -280,7 +282,7 @@ public:
(mBottom == b.mBottom));
}
- bool operator!=(const LLRectBase &b)
+ bool operator!=(const LLRectBase &b) const
{
return ((mLeft != b.mLeft) ||
(mTop != b.mTop) ||
diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp
index 073cb2e3bd..c5176681ce 100644
--- a/indra/llmath/llsdutil_math.cpp
+++ b/indra/llmath/llsdutil_math.cpp
@@ -165,9 +165,6 @@ LLSD ll_sd_from_color4(const LLColor4& c)
LLColor4 ll_color4_from_sd(const LLSD& sd)
{
LLColor4 c;
- c.mV[0] = (F32)sd[0].asReal();
- c.mV[1] = (F32)sd[1].asReal();
- c.mV[2] = (F32)sd[2].asReal();
- c.mV[3] = (F32)sd[3].asReal();
+ c.setValue(sd);
return c;
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 1250f539f5..a0357a32cc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -3370,7 +3370,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<S32> &segments,
const LLVector3& obj_cam_vec,
const LLMatrix4& mat,
- const LLMatrix3& norm_mat)
+ const LLMatrix3& norm_mat,
+ S32 face_mask)
{
LLMemType m1(LLMemType::MTYPE_VOLUME);
@@ -3378,12 +3379,17 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
normals.clear();
segments.clear();
+ S32 cur_index = 0;
//for each face
for (face_list_t::iterator iter = mVolumeFaces.begin();
iter != mVolumeFaces.end(); ++iter)
{
const LLVolumeFace& face = *iter;
+ if (!(face_mask & (0x1 << cur_index++)))
+ {
+ continue;
+ }
if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index e55fe52c91..871b334452 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -52,7 +52,7 @@ class LLVolume;
#include "llquaternion.h"
#include "llstrider.h"
#include "v4coloru.h"
-#include "llmemory.h"
+#include "llrefcount.h"
#include "llfile.h"
//============================================================================
@@ -902,9 +902,13 @@ public:
// returns number of triangle indeces required for path/profile mesh
S32 getNumTriangleIndices() const;
- void generateSilhouetteVertices(std::vector<LLVector3> &vertices, std::vector<LLVector3> &normals, std::vector<S32> &segments, const LLVector3& view_vec,
- const LLMatrix4& mat,
- const LLMatrix3& norm_mat);
+ void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
+ std::vector<LLVector3> &normals,
+ std::vector<S32> &segments,
+ const LLVector3& view_vec,
+ const LLMatrix4& mat,
+ const LLMatrix3& norm_mat,
+ S32 face_index);
//get the face index of the face that intersects with the given line segment at the point
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h
index e10ad94dba..a78ea76a1a 100644
--- a/indra/llmath/llvolumemgr.h
+++ b/indra/llmath/llvolumemgr.h
@@ -36,7 +36,7 @@
#include <map>
#include "llvolume.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llthread.h"
class LLVolumeParams;
@@ -92,8 +92,8 @@ public:
// whatever calls getVolume() never owns the LLVolume* and
// cannot keep references for long since it may be deleted
// later. For best results hold it in an LLPointer<LLVolume>.
- LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
- void unrefVolume(LLVolume *volumep);
+ virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
+ virtual void unrefVolume(LLVolume *volumep);
void dump();
diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp
index fa7b61cd75..e76607a91f 100644
--- a/indra/llmath/v3color.cpp
+++ b/indra/llmath/v3color.cpp
@@ -75,6 +75,42 @@ std::ostream& operator<<(std::ostream& s, const LLColor3 &a)
return s;
}
+static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
+{
+ if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
+ if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
+ if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
+ if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
+ if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
+ return ( val1In );
+}
+
+void LLColor3::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
+{
+ if ( sValIn < 0.00001f )
+ {
+ mV[VRED] = lValIn;
+ mV[VGREEN] = lValIn;
+ mV[VBLUE] = lValIn;
+ }
+ else
+ {
+ F32 interVal1;
+ F32 interVal2;
+
+ if ( lValIn < 0.5f )
+ interVal2 = lValIn * ( 1.0f + sValIn );
+ else
+ interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
+
+ interVal1 = 2.0f * lValIn - interVal2;
+
+ mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
+ mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
+ mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
+ }
+}
+
void LLColor3::calcHSL(F32* hue, F32* saturation, F32* luminance) const
{
F32 var_R = mV[VRED];
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 179687a32e..1915d80502 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -79,6 +79,7 @@ public:
mV[2] = (F32) sd[2].asReal();;
}
+ void setHSL(F32 hue, F32 saturation, F32 luminance);
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0)
diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h
index a99bf5b4a6..6ab31e8a41 100644
--- a/indra/llmath/v3dmath.h
+++ b/indra/llmath/v3dmath.h
@@ -53,7 +53,7 @@ class LLVector3d
inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
inline explicit LLVector3d(const LLVector3 &vec);
- LLVector3d(const LLSD& sd)
+ explicit LLVector3d(const LLSD& sd)
{
setValue(sd);
}
@@ -65,12 +65,6 @@ class LLVector3d
mdV[2] = sd[2].asReal();
}
- const LLVector3d& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
LLSD getValue() const
{
LLSD ret;
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index 101e9d075a..f392ac448b 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -314,12 +314,6 @@ void LLVector3::setValue(const LLSD& sd)
mV[2] = (F32) sd[2].asReal();
}
-const LLVector3& LLVector3::operator=(const LLSD& sd)
-{
- setValue(sd);
- return *this;
-}
-
const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot)
{
const F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ];
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 7f96800e21..805d7e6384 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -67,14 +67,12 @@ class LLVector3
explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0)
explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
- LLVector3(const LLSD& sd);
+ explicit LLVector3(const LLSD& sd);
LLSD getValue() const;
void setValue(const LLSD& sd);
- const LLVector3& operator=(const LLSD& sd);
-
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed
BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value
diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp
index 0cbfce07c9..219b06ec74 100644
--- a/indra/llmath/v4color.cpp
+++ b/indra/llmath/v4color.cpp
@@ -227,6 +227,40 @@ const LLColor4& LLColor4::setVec(const LLColor3 &vec, F32 a)
return (*this);
}
+void LLColor4::setValue(const LLSD& sd)
+{
+#if 0
+ // Clamping on setValue from LLSD is inconsistent with other set behavior
+ F32 val;
+ bool out_of_range = false;
+ val = sd[0].asReal();
+ mV[0] = llclamp(val, 0.f, 1.f);
+ out_of_range = mV[0] != val;
+
+ val = sd[1].asReal();
+ mV[1] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[1] != val;
+
+ val = sd[2].asReal();
+ mV[2] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[2] != val;
+
+ val = sd[3].asReal();
+ mV[3] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[3] != val;
+
+ if (out_of_range)
+ {
+ llwarns << "LLSD color value out of range!" << llendl;
+ }
+#else
+ mV[0] = (F32) sd[0].asReal();
+ mV[1] = (F32) sd[1].asReal();
+ mV[2] = (F32) sd[2].asReal();
+ mV[3] = (F32) sd[3].asReal();
+#endif
+}
+
const LLColor4& LLColor4::operator=(const LLColor3 &a)
{
mV[VX] = a.mV[VX];
@@ -271,6 +305,42 @@ LLColor4 vec3to4(const LLColor3 &vec)
return temp;
}
+static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
+{
+ if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
+ if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
+ if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
+ if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
+ if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
+ return ( val1In );
+}
+
+void LLColor4::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
+{
+ if ( sValIn < 0.00001f )
+ {
+ mV[VRED] = lValIn;
+ mV[VGREEN] = lValIn;
+ mV[VBLUE] = lValIn;
+ }
+ else
+ {
+ F32 interVal1;
+ F32 interVal2;
+
+ if ( lValIn < 0.5f )
+ interVal2 = lValIn * ( 1.0f + sValIn );
+ else
+ interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
+
+ interVal1 = 2.0f * lValIn - interVal2;
+
+ mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
+ mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
+ mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
+ }
+}
+
void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const
{
F32 var_R = mV[VRED];
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 785b47dd37..d6fbdec61e 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -58,7 +58,7 @@ class LLColor4
LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
- LLColor4(const LLSD& sd);
+ explicit LLColor4(const LLSD& sd);
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion
@@ -72,14 +72,9 @@ class LLColor4
return ret;
}
- void setValue(const LLSD& sd)
- {
- mV[0] = (F32) sd[0].asReal();
- mV[1] = (F32) sd[1].asReal();
- mV[2] = (F32) sd[2].asReal();
- mV[3] = (F32) sd[3].asReal();
- }
+ void setValue(const LLSD& sd);
+ void setHSL(F32 hue, F32 saturation, F32 luminance);
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1)
@@ -118,7 +113,6 @@ class LLColor4
F32 &operator[](int idx) { return mV[idx]; }
const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4
- const LLColor4& operator=(const LLSD& sd);
friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a
friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b
@@ -249,7 +243,7 @@ inline LLColor4::LLColor4(void)
inline LLColor4::LLColor4(const LLSD& sd)
{
- *this = sd;
+ this->setValue(sd);
}
inline LLColor4::LLColor4(F32 r, F32 g, F32 b)
@@ -639,15 +633,5 @@ void LLColor4::clamp()
}
}
-inline const LLColor4& LLColor4::operator=(const LLSD& sd)
-{
- mV[0] = (F32) sd[0].asReal();
- mV[1] = (F32) sd[1].asReal();
- mV[2] = (F32) sd[2].asReal();
- mV[3] = (F32) sd[3].asReal();
-
- return *this;
-}
-
#endif
diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h
index 082d0efbb1..4ec5a345eb 100644
--- a/indra/llmath/v4coloru.h
+++ b/indra/llmath/v4coloru.h
@@ -66,7 +66,7 @@ public:
LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1)
LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a)
LLColor4U(const U8 *vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1)
- LLColor4U(const LLSD& sd)
+ explicit LLColor4U(const LLSD& sd)
{
setValue(sd);
}
@@ -79,12 +79,6 @@ public:
mV[3] = sd[3].asInteger();
}
- const LLColor4U& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
LLSD getValue() const
{
LLSD ret;
@@ -138,6 +132,12 @@ public:
static BOOL parseColor4U(const std::string& buf, LLColor4U* value);
+ // conversion
+ operator const LLColor4() const
+ {
+ return LLColor4(*this);
+ }
+
static LLColor4U white;
static LLColor4U black;
static LLColor4U red;
diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h
index d3be28f41d..5b7b1900bc 100644
--- a/indra/llmath/xform.h
+++ b/indra/llmath/xform.h
@@ -173,7 +173,7 @@ BOOL LLXform::setParent(LLXform* parent)
{
if (cur_par == this)
{
- llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl;
+ //llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl;
return FALSE;
}
cur_par = cur_par->mParent;