summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2020-04-27 15:16:21 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2020-04-27 15:16:21 +0300
commit94dc8f12f86adb3bf79b44ab0bc98e6c0f6899ee (patch)
tree7434d3d4dde8eedbad54d5b954579029026f1308 /indra/llmath
parenta5eb15da0a89c6f9df7d426c0c3c41df445cfd2f (diff)
parentd7f1c88c35849e56f5b352f13c16a08467d1533b (diff)
Merge branch 'master' into DRTVWR-507-maint
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/CMakeLists.txt1
-rw-r--r--indra/llmath/llcamera.cpp5
-rw-r--r--indra/llmath/llcamera.h1
-rw-r--r--indra/llmath/llcoordframe.cpp186
-rw-r--r--indra/llmath/llmath.h29
-rw-r--r--indra/llmath/llquaternion.cpp25
-rw-r--r--indra/llmath/llquaternion.h27
-rw-r--r--indra/llmath/llvolume.cpp74
-rw-r--r--indra/llmath/llvolume.h6
-rw-r--r--indra/llmath/m3math.cpp24
-rw-r--r--indra/llmath/m3math.h4
-rw-r--r--indra/llmath/m4math.cpp27
-rw-r--r--indra/llmath/m4math.h6
-rw-r--r--indra/llmath/tests/m3math_test.cpp2
-rw-r--r--indra/llmath/v2math.cpp2
-rw-r--r--indra/llmath/v2math.h7
-rw-r--r--indra/llmath/v3color.h34
-rw-r--r--indra/llmath/v3colorutil.h115
-rw-r--r--indra/llmath/v4color.h35
-rw-r--r--indra/llmath/v4math.h46
20 files changed, 439 insertions, 217 deletions
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 379c3ee9ea..999bee0a3f 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -90,6 +90,7 @@ set(llmath_HEADER_FILES
raytrace.h
v2math.h
v3color.h
+ v3colorutil.h
v3dmath.h
v3math.h
v4color.h
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index ff90532f75..9034182072 100644
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -93,6 +93,11 @@ F32 LLCamera::getMaxView() const
: MAX_FIELD_OF_VIEW; // narrow views
}
+LLPlane LLCamera::getUserClipPlane()
+{
+ return mAgentPlanes[AGENT_PLANE_USER_CLIP];
+}
+
// ---------------- LLCamera::setFoo() member functions ----------------
void LLCamera::setUserClipPlane(LLPlane& plane)
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 321b8ddcc4..d0afa0e88f 100644
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -154,6 +154,7 @@ public:
bool isChanged(); //check if mAgentPlanes changed since last frame.
+ LLPlane getUserClipPlane();
void setUserClipPlane(LLPlane& plane);
void disableUserClipPlane();
virtual void setView(F32 vertical_fov_rads);
diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp
index 1bf51ca0eb..b25fd948f5 100644
--- a/indra/llmath/llcoordframe.cpp
+++ b/indra/llmath/llcoordframe.cpp
@@ -34,6 +34,20 @@
#include "llquaternion.h"
#include "llcoordframe.h"
+#define CHECK_FINITE(var) \
+ if (!var.isFinite()) \
+ { \
+ LL_WARNS() << "Non Finite " << std::string(#var) << LL_ENDL; \
+ reset(); \
+ }
+
+#define CHECK_FINITE_OBJ() \
+ if (!isFinite()) \
+ { \
+ LL_WARNS() << "Non Finite in LLCoordFrame " << LL_ENDL; \
+ reset(); \
+ }
+
#ifndef X_AXIS
#define X_AXIS 1.0f,0.0f,0.0f
#define Y_AXIS 0.0f,1.0f,0.0f
@@ -56,11 +70,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin) :
mYAxis(Y_AXIS),
mZAxis(Z_AXIS)
{
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction) :
@@ -68,11 +78,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction)
{
lookDir(direction);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
@@ -83,11 +89,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
mYAxis(y_axis),
mZAxis(z_axis)
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
@@ -99,11 +101,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
mYAxis(y_axis),
mZAxis(z_axis)
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -114,11 +112,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
mYAxis(rotation.mMatrix[VY]),
mZAxis(rotation.mMatrix[VZ])
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
@@ -129,11 +123,7 @@ LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
@@ -144,11 +134,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
@@ -157,11 +143,7 @@ LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
mYAxis(mat.mMatrix[VY]),
mZAxis(mat.mMatrix[VZ])
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -173,11 +155,7 @@ LLCoordFrame::LLCoordFrame(const F32 *origin, const F32 *rotation) :
mYAxis(rotation+3*VY),
mZAxis(rotation+3*VZ)
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
*/
@@ -188,11 +166,7 @@ LLCoordFrame::LLCoordFrame(const F32 *origin_and_rotation) :
mYAxis(origin_and_rotation + 3*(VY+1)),
mZAxis(origin_and_rotation + 3*(VZ+1))
{
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
*/
@@ -217,21 +191,13 @@ void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
{
mOrigin.setVec(x, y, z);
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const LLVector3 &new_origin)
{
mOrigin = new_origin;
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const F32 *origin)
@@ -239,23 +205,13 @@ void LLCoordFrame::setOrigin(const F32 *origin)
mOrigin.mV[VX] = *(origin + VX);
mOrigin.mV[VY] = *(origin + VY);
mOrigin.mV[VZ] = *(origin + VZ);
-
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const LLCoordFrame &frame)
{
mOrigin = frame.getOrigin();
-
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
// setAxes() member functions set the axes, and assume that
@@ -268,11 +224,7 @@ void LLCoordFrame::setAxes(const LLVector3 &x_axis,
mXAxis = x_axis;
mYAxis = y_axis;
mZAxis = z_axis;
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -281,11 +233,7 @@ void LLCoordFrame::setAxes(const LLMatrix3 &rotation_matrix)
mXAxis.setVec(rotation_matrix.mMatrix[VX]);
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -293,11 +241,7 @@ void LLCoordFrame::setAxes(const LLQuaternion &q )
{
LLMatrix3 rotation_matrix(q);
setAxes(rotation_matrix);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -313,11 +257,7 @@ void LLCoordFrame::setAxes( const F32 *rotation_matrix )
mZAxis.mV[VY] = *(rotation_matrix + 3*VZ + VY);
mZAxis.mV[VZ] = *(rotation_matrix + 3*VZ + VZ);
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -326,40 +266,22 @@ void LLCoordFrame::setAxes(const LLCoordFrame &frame)
mXAxis = frame.getXAxis();
mYAxis = frame.getYAxis();
mZAxis = frame.getZAxis();
-
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
-
// translate() member functions move mOrigin to a relative position
-
void LLCoordFrame::translate(F32 x, F32 y, F32 z)
{
mOrigin.mV[VX] += x;
mOrigin.mV[VY] += y;
mOrigin.mV[VZ] += z;
-
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
-
void LLCoordFrame::translate(const LLVector3 &v)
{
mOrigin += v;
-
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
@@ -368,12 +290,7 @@ void LLCoordFrame::translate(const F32 *origin)
mOrigin.mV[VX] += *(origin + VX);
mOrigin.mV[VY] += *(origin + VY);
mOrigin.mV[VZ] += *(origin + VZ);
-
- if( !mOrigin.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
- }
+ CHECK_FINITE(mOrigin);
}
@@ -383,6 +300,7 @@ void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)
{
LLQuaternion q(angle, LLVector3(x,y,z));
rotate(q);
+ CHECK_FINITE_OBJ();
}
@@ -390,6 +308,7 @@ void LLCoordFrame::rotate(F32 angle, const LLVector3 &rotation_axis)
{
LLQuaternion q(angle, rotation_axis);
rotate(q);
+ CHECK_FINITE_OBJ();
}
@@ -397,6 +316,7 @@ void LLCoordFrame::rotate(const LLQuaternion &q)
{
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
+ CHECK_FINITE_OBJ();
}
@@ -405,12 +325,7 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
mXAxis.rotVec(rotation_matrix);
mYAxis.rotVec(rotation_matrix);
orthonormalize();
-
- if( !isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::rotate()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
@@ -419,12 +334,7 @@ void LLCoordFrame::roll(F32 angle)
LLQuaternion q(angle, mXAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
-
- if( !mYAxis.isFinite() || !mZAxis.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::roll()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
void LLCoordFrame::pitch(F32 angle)
@@ -432,12 +342,7 @@ void LLCoordFrame::pitch(F32 angle)
LLQuaternion q(angle, mYAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
-
- if( !mXAxis.isFinite() || !mZAxis.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::pitch()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
void LLCoordFrame::yaw(F32 angle)
@@ -445,12 +350,7 @@ void LLCoordFrame::yaw(F32 angle)
LLQuaternion q(angle, mZAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
-
- if( !mXAxis.isFinite() || !mYAxis.isFinite() )
- {
- reset();
- LL_WARNS() << "Non Finite in LLCoordFrame::yaw()" << LL_ENDL;
- }
+ CHECK_FINITE_OBJ();
}
// get*() routines
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index e508c9a199..8f01ad6c1c 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -537,6 +537,35 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
}
}
+// Converts given value from a linear RGB floating point value (0..1) to a gamma corrected (sRGB) value.
+// Some shaders require color values in linear space, while others require color values in gamma corrected (sRGB) space.
+// Note: in our code, values labeled as sRGB are ALWAYS gamma corrected linear values, NOT linear values with monitor gamma applied
+// Note: stored color values should always be gamma corrected linear (i.e. the values returned from an on-screen color swatch)
+// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses
+inline float linearTosRGB(const float val) {
+ if (val < 0.0031308f) {
+ return val * 12.92f;
+ }
+ else {
+ return 1.055f * pow(val, 1.0f / 2.4f) - 0.055f;
+ }
+}
+
+// Converts given value from a gamma corrected (sRGB) floating point value (0..1) to a linear color value.
+// Some shaders require color values in linear space, while others require color values in gamma corrected (sRGB) space.
+// Note: In our code, values labeled as sRGB are gamma corrected linear values, NOT linear values with monitor gamma applied
+// Note: Stored color values should generally be gamma corrected sRGB.
+// If you're serializing the return value of this function, you're probably doing it wrong.
+// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses.
+inline float sRGBtoLinear(const float val) {
+ if (val < 0.04045f) {
+ return val / 12.92f;
+ }
+ else {
+ return pow((val + 0.055f) / 1.055f, 2.4f);
+ }
+}
+
// Include simd math header
#include "llsimdmath.h"
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 47374c287f..57a976b57a 100644
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
@@ -104,6 +104,11 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
normalize();
}
+LLQuaternion::LLQuaternion(const LLSD &sd)
+{
+ setValue(sd);
+}
+
// Quatizations
void LLQuaternion::quantize16(F32 lower, F32 upper)
{
@@ -860,6 +865,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
}
}
+const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians)
+{
+ // euler angle inputs are complements of azimuth/altitude which are measured from zenith
+ F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO);
+ F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO);
+ setEulerAngles(0.0f, pitch, yaw);
+ return *this;
+}
+
+void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians)
+{
+ F32 rick_roll;
+ F32 pitch;
+ F32 yaw;
+ getEulerAngles(&rick_roll, &pitch, &yaw);
+ // make these measured from zenith
+ altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO);
+ azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO);
+}
+
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index aa0b1752f4..51ce163b4e 100644
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
@@ -28,6 +28,7 @@
#define LLQUATERNION_H
#include <iostream>
+#include "llsd.h"
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
#error "Please include llmath.h first."
@@ -63,6 +64,10 @@ public:
LLQuaternion(const LLVector3 &x_axis,
const LLVector3 &y_axis,
const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
+ explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array.
+
+ LLSD getValue() const;
+ void setValue(const LLSD& sd);
BOOL isIdentity() const;
BOOL isNotIdentity() const;
@@ -79,7 +84,8 @@ public:
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
-
+ const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude);
+
const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
@@ -100,6 +106,7 @@ public:
void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z
void getAngleAxis(F32* angle, LLVector3 &vec) const;
void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
+ void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude);
F32 normalize(); // Normalizes Quaternion and returns magnitude
F32 normQuat(); // deprecated
@@ -166,6 +173,24 @@ public:
//static U32 mMultCount;
};
+inline LLSD LLQuaternion::getValue() const
+{
+ LLSD ret;
+ ret[0] = mQ[0];
+ ret[1] = mQ[1];
+ ret[2] = mQ[2];
+ ret[3] = mQ[3];
+ return ret;
+}
+
+inline void LLQuaternion::setValue(const LLSD& sd)
+{
+ mQ[0] = sd[0].asReal();
+ mQ[1] = sd[1].asReal();
+ mQ[2] = sd[2].asReal();
+ mQ[3] = sd[3].asReal();
+}
+
// checker
inline BOOL LLQuaternion::isFinite() const
{
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 49a186bc87..2ac1eb99ce 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2205,7 +2205,6 @@ BOOL LLVolume::generate()
{
rot_mat.rotate(*profile++, tmp);
dst->setAdd(tmp,offset);
- llassert(dst->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds
++dst;
}
}
@@ -4657,6 +4656,10 @@ LLVolumeFace::LLVolumeFace() :
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ mJustWeights(NULL),
+ mJointIndices(NULL),
+#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
mOptimized(FALSE)
@@ -4683,6 +4686,10 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ mJustWeights(NULL),
+ mJointIndices(NULL),
+#endif
mWeightsScrubbed(FALSE),
mOctree(NULL)
{
@@ -4747,24 +4754,46 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
if (src.mWeights)
{
+ llassert(!mWeights); // don't orphan an old alloc here accidentally
allocateWeights(src.mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
+ LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
+ mWeightsScrubbed = src.mWeightsScrubbed;
}
else
{
- ll_aligned_free_16(mWeights);
- mWeights = NULL;
- }
- mWeightsScrubbed = src.mWeightsScrubbed;
- }
+ ll_aligned_free_16(mWeights);
+ mWeights = NULL;
+ mWeightsScrubbed = FALSE;
+ }
+
+ #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ if (src.mJointIndices)
+ {
+ llassert(!mJointIndices); // don't orphan an old alloc here accidentally
+ allocateJointIndices(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mJointIndices, (F32*) src.mJointIndices, src.mNumVertices * sizeof(U8) * 4);
+ }
+ else*/
+ {
+ ll_aligned_free_16(mJointIndices);
+ mJointIndices = NULL;
+ }
+ #endif
+ }
+
if (mNumIndices)
{
S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);
}
-
+ else
+ {
+ ll_aligned_free_16(mIndices);
+ mIndices = NULL;
+ }
+
mOptimized = src.mOptimized;
//delete
@@ -4796,6 +4825,13 @@ void LLVolumeFace::freeData()
ll_aligned_free_16(mWeights);
mWeights = NULL;
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ ll_aligned_free_16(mJointIndices);
+ mJointIndices = NULL;
+ ll_aligned_free_16(mJustWeights);
+ mJustWeights = NULL;
+#endif
+
delete mOctree;
mOctree = NULL;
}
@@ -5449,11 +5485,17 @@ bool LLVolumeFace::cacheOptimize()
// DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
ll_aligned_free_16(mWeights);
ll_aligned_free_16(mTangents);
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ ll_aligned_free_16(mJointIndices);
+ ll_aligned_free_16(mJustWeights);
+ mJustWeights = NULL;
+ mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration
+#endif
mPositions = pos;
mNormals = norm;
mTexCoords = tc;
- mWeights = wght;
+ mWeights = wght;
mTangents = binorm;
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
@@ -6363,7 +6405,19 @@ void LLVolumeFace::allocateTangents(S32 num_verts)
void LLVolumeFace::allocateWeights(S32 num_verts)
{
ll_aligned_free_16(mWeights);
- mWeights = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+ mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+
+}
+
+void LLVolumeFace::allocateJointIndices(S32 num_verts)
+{
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ ll_aligned_free_16(mJointIndices);
+ ll_aligned_free_16(mJustWeights);
+
+ mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts);
+ mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);
+#endif
}
void LLVolumeFace::resizeIndices(S32 num_indices)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 1d6d35c432..a77e8c08c6 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -875,6 +875,7 @@ public:
void resizeVertices(S32 num_verts);
void allocateTangents(S32 num_verts);
void allocateWeights(S32 num_verts);
+ void allocateJointIndices(S32 num_verts);
void resizeIndices(S32 num_indices);
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
@@ -956,6 +957,11 @@ public:
// mWeights.size() should be empty or match mVertices.size()
LLVector4a* mWeights;
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ LLVector4a* mJustWeights;
+ U8* mJointIndices;
+#endif
+
mutable BOOL mWeightsScrubbed;
// Which joints are rigged to, and the bounding box of any rigged
diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp
index 802ddb9e57..65eb3348de 100644
--- a/indra/llmath/m3math.cpp
+++ b/indra/llmath/m3math.cpp
@@ -75,13 +75,6 @@ LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)
setRot(quat);
}
-LLMatrix3::LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLVector3 vec(x, y, z);
- LLQuaternion quat(angle, vec);
- setRot(quat);
-}
-
LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)
{
setRot(roll,pitch,yaw);
@@ -294,14 +287,6 @@ LLQuaternion LLMatrix3::quaternion() const
return quat;
}
-
-// These functions take Rotation arguments
-const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- setRot(LLQuaternion(angle,x,y,z));
- return *this;
-}
-
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
{
setRot(LLQuaternion(angle, vec));
@@ -394,15 +379,6 @@ const LLMatrix3& LLMatrix3::setCol( U32 colIndex, const LLVector3& col )
return *this;
}
-
-// Rotate exisitng mMatrix
-const LLMatrix3& LLMatrix3::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLMatrix3 mat(angle, x, y, z);
- *this *= mat;
- return *this;
-}
-
const LLMatrix3& LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)
{
diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h
index 2be5452f8d..bf38895855 100644
--- a/indra/llmath/m3math.h
+++ b/indra/llmath/m3math.h
@@ -60,7 +60,6 @@ class LLMatrix3
explicit LLMatrix3(const F32 *mat); // Initializes Matrix to values in mat
explicit LLMatrix3(const LLQuaternion &q); // Initializes Matrix with rotation q
- LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3 &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3d &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector4 &vec); // Initializes Matrix with axis angle
@@ -81,8 +80,7 @@ class LLMatrix3
// Matrix setters - set some properties without modifying others
//
- // These functions take Rotation arguments
- const LLMatrix3& setRot(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix for rotating angle radians about (x, y, z)
+ // These functions take Rotation arguments
const LLMatrix3& setRot(const F32 angle, const LLVector3 &vec); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix3& setRot(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix3& setRot(const LLQuaternion &q); // Transform matrix by Euler angles and translating by pos
diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp
index d89c482804..3baf1bad18 100644
--- a/indra/llmath/m4math.cpp
+++ b/indra/llmath/m4math.cpp
@@ -384,13 +384,6 @@ void LLMatrix4::initRows(const LLVector4 &row0,
}
-const LLMatrix4& LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLMatrix3 mat(angle, x, y, z);
- return initMatrix(mat);
-}
-
-
const LLMatrix4& LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
{
LLMatrix3 mat(angle, vec);
@@ -412,17 +405,6 @@ const LLMatrix4& LLMatrix4::initRotation(const LLQuaternion &q)
}
-// Position and Rotation
-const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
- const F32 tx, const F32 ty, const F32 tz)
-{
- LLMatrix3 mat(angle, rx, ry, rz);
- LLVector3 translation(tx, ty, tz);
- initMatrix(mat);
- setTranslation(translation);
- return (*this);
-}
-
const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
{
LLMatrix3 mat(angle, axis);
@@ -513,15 +495,6 @@ const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &
return (*this);
}
-// Rotate exisitng mMatrix
-const LLMatrix4& LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
-{
- LLVector4 vec4(x, y, z);
- LLMatrix4 mat(angle, vec4);
- *this *= mat;
- return *this;
-}
-
const LLMatrix4& LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
{
LLMatrix4 mat(angle, vec);
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index a77c5bc76d..bf60adb9b6 100644
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -137,7 +137,6 @@ public:
bool isIdentity() const;
const LLMatrix4& setZero(); // Clears matrix to all zeros.
- const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix by rotating angle radians about (x, y, z)
const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position
@@ -148,10 +147,6 @@ public:
// These operation create a matrix that will rotate and translate by the
// specified amounts.
- const LLMatrix4& initRotTrans(const F32 angle,
- const F32 rx, const F32 ry, const F32 rz,
- const F32 px, const F32 py, const F32 pz);
-
const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation); // Rotation from axis angle + translation
const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position
@@ -211,7 +206,6 @@ public:
// Rotate existing matrix
// These are really, really, inefficient as implemented! - djs
- const LLMatrix4& rotate(const F32 angle, const F32 x, const F32 y, const F32 z); // Rotate matrix by rotating angle radians about (x, y, z)
const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec
const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles
const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion
diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp
index 1ca2b005d9..2a0fe76aa7 100644
--- a/indra/llmath/tests/m3math_test.cpp
+++ b/indra/llmath/tests/m3math_test.cpp
@@ -77,7 +77,7 @@ namespace tut
template<> template<>
void m3math_test_object_t::test<2>()
{
- LLMatrix3 llmat3_obj(30, 1, 2, 3);
+ LLMatrix3 llmat3_obj;
llmat3_obj.setZero();
ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] &&
diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp
index a0cd642853..a24571f2c8 100644
--- a/indra/llmath/v2math.cpp
+++ b/indra/llmath/v2math.cpp
@@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const
return ret;
}
-void LLVector2::setValue(LLSD& sd)
+void LLVector2::setValue(const LLSD& sd)
{
mV[0] = (F32) sd[0].asReal();
mV[1] = (F32) sd[1].asReal();
diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h
index 8d5db96f5e..2335a2e327 100644
--- a/indra/llmath/v2math.h
+++ b/indra/llmath/v2math.h
@@ -49,6 +49,7 @@ class LLVector2
LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y)
LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])
+ explicit LLVector2(const LLSD &sd);
// Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec.
void clear();
@@ -61,7 +62,7 @@ class LLVector2
void set(const F32 *vec); // Sets LLVector2 to vec
LLSD getValue() const;
- void setValue(LLSD& sd);
+ void setValue(const LLSD& sd);
void setVec(F32 x, F32 y); // deprecated
void setVec(const LLVector2 &vec); // deprecated
@@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec)
mV[VY] = vec.mV[VY];
}
+inline LLVector2::LLVector2(const LLSD &sd)
+{
+ setValue(sd);
+}
// Clear and Assignment Functions
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index daf3a6857b..43a632408c 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -100,6 +100,23 @@ public:
const LLColor3& operator=(const LLColor4 &a);
+ LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)
+ {
+ return LLColor3(
+ mV[0] / col2.mV[0],
+ mV[1] / col2.mV[1],
+ mV[2] / col2.mV[2] );
+ }
+
+ LL_FORCE_INLINE LLColor3 color_norm()
+ {
+ F32 l = length();
+ return LLColor3(
+ mV[0] / l,
+ mV[1] / l,
+ mV[2] / l );
+ }
+
friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a
friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b
friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b
@@ -458,5 +475,22 @@ inline LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u)
a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
}
+inline const LLColor3 srgbColor3(const LLColor3 &a) {
+ LLColor3 srgbColor;
+ srgbColor.mV[0] = linearTosRGB(a.mV[0]);
+ srgbColor.mV[1] = linearTosRGB(a.mV[1]);
+ srgbColor.mV[2] = linearTosRGB(a.mV[2]);
+
+ return srgbColor;
+}
+
+inline const LLColor3 linearColor3(const LLColor3 &a) {
+ LLColor3 linearColor;
+ linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
+ linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
+ linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
+
+ return linearColor;
+}
#endif
diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h
new file mode 100644
index 0000000000..6d8cd9329b
--- /dev/null
+++ b/indra/llmath/v3colorutil.h
@@ -0,0 +1,115 @@
+/**
+ * @file v3color.h
+ * @brief LLColor3 class header file.
+ *
+ * $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_V3COLORUTIL_H
+#define LL_V3COLORUTIL_H
+
+#include "v3color.h"
+
+inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
+{
+ return LLColor3(left.mV[0] / right.mV[0],
+ left.mV[1] / right.mV[1],
+ left.mV[2] / right.mV[2]);
+}
+
+
+inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
+{
+ return LLColor3(left.mV[0] * right.mV[0],
+ left.mV[1] * right.mV[1],
+ left.mV[2] * right.mV[2]);
+}
+
+
+inline LLColor3 componentExp(LLColor3 const &v)
+{
+ return LLColor3(exp(v.mV[0]),
+ exp(v.mV[1]),
+ exp(v.mV[2]));
+}
+
+inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
+{
+ return LLColor3(pow(v.mV[0], exponent),
+ pow(v.mV[1], exponent),
+ pow(v.mV[2], exponent));
+}
+
+inline LLColor3 componentSaturate(LLColor3 const &v)
+{
+ return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
+ std::max(std::min(v.mV[1], 1.f), 0.f),
+ std::max(std::min(v.mV[2], 1.f), 0.f));
+}
+
+
+inline LLColor3 componentSqrt(LLColor3 const &v)
+{
+ return LLColor3(sqrt(v.mV[0]),
+ sqrt(v.mV[1]),
+ sqrt(v.mV[2]));
+}
+
+inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
+{
+ left.mV[0] *= right.mV[0];
+ left.mV[1] *= right.mV[1];
+ left.mV[2] *= right.mV[2];
+}
+
+inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
+{
+ return (left + ((right - left) * amount));
+}
+
+inline LLColor3 smear(F32 val)
+{
+ return LLColor3(val, val, val);
+}
+
+inline F32 color_intens(const LLColor3 &col)
+{
+ return col.mV[0] + col.mV[1] + col.mV[2];
+}
+
+inline F32 color_max(const LLColor3 &col)
+{
+ return llmax(col.mV[0], col.mV[1], col.mV[2]);
+}
+
+inline F32 color_max(const LLColor4 &col)
+{
+ return llmax(col.mV[0], col.mV[1], col.mV[2]);
+}
+
+
+inline F32 color_min(const LLColor3 &col)
+{
+ return llmin(col.mV[0], col.mV[1], col.mV[2]);
+}
+
+#endif
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 8f353ead5a..175edf1471 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -114,9 +114,11 @@ class LLColor4
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b
friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
+ friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change)
friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change)
+
friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b
friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b
@@ -477,6 +479,15 @@ inline LLColor4 operator*(const LLColor4 &a, F32 k)
a.mV[VW]);
}
+inline LLColor4 operator/(const LLColor4 &a, F32 k)
+{
+ return LLColor4(
+ a.mV[VX] / k,
+ a.mV[VY] / k,
+ a.mV[VZ] / k,
+ a.mV[VW]);
+}
+
inline LLColor4 operator*(F32 k, const LLColor4 &a)
{
// only affects rgb (not a!)
@@ -645,5 +656,29 @@ void LLColor4::clamp()
}
}
+// Return the given linear space color value in gamma corrected (sRGB) space
+inline const LLColor4 srgbColor4(const LLColor4 &a) {
+ LLColor4 srgbColor;
+
+ srgbColor.mV[0] = linearTosRGB(a.mV[0]);
+ srgbColor.mV[1] = linearTosRGB(a.mV[1]);
+ srgbColor.mV[2] = linearTosRGB(a.mV[2]);
+ srgbColor.mV[3] = a.mV[3];
+
+ return srgbColor;
+}
+
+// Return the given gamma corrected (sRGB) color in linear space
+inline const LLColor4 linearColor4(const LLColor4 &a)
+{
+ LLColor4 linearColor;
+ linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
+ linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
+ linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
+ linearColor.mV[3] = a.mV[3];
+
+ return linearColor;
+}
+
#endif
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 623c8b2003..b8835ba2e4 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -30,6 +30,7 @@
#include "llerror.h"
#include "llmath.h"
#include "v3math.h"
+#include "v2math.h"
class LLMatrix3;
class LLMatrix4;
@@ -46,8 +47,11 @@ class LLVector4
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
+ explicit LLVector4(const LLVector2 &vec);
+ explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
+ explicit LLVector4(const LLSD &sd);
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
LLVector4(F32 x, F32 y, F32 z, F32 w);
@@ -61,6 +65,15 @@ class LLVector4
return ret;
}
+ void setValue(const LLSD& sd)
+ {
+ mV[0] = sd[0].asReal();
+ mV[1] = sd[1].asReal();
+ mV[2] = sd[2].asReal();
+ mV[3] = sd[3].asReal();
+ }
+
+
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
@@ -175,6 +188,22 @@ inline LLVector4::LLVector4(const F64 *vec)
mV[VW] = (F32) vec[VW];
}
+inline LLVector4::LLVector4(const LLVector2 &vec)
+{
+ mV[VX] = vec[VX];
+ mV[VY] = vec[VY];
+ mV[VZ] = 0.f;
+ mV[VW] = 0.f;
+}
+
+inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
+{
+ mV[VX] = vec[VX];
+ mV[VY] = vec[VY];
+ mV[VZ] = z;
+ mV[VW] = w;
+}
+
inline LLVector4::LLVector4(const LLVector3 &vec)
{
mV[VX] = vec.mV[VX];
@@ -191,6 +220,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
mV[VW] = w;
}
+inline LLVector4::LLVector4(const LLSD &sd)
+{
+ setValue(sd);
+}
+
inline BOOL LLVector4::isFinite() const
{
@@ -500,6 +534,18 @@ inline F32 LLVector4::normVec(void)
return (mag);
}
+// Because apparently some parts of the viewer use this for color info.
+inline const LLVector4 srgbVector4(const LLVector4 &a) {
+ LLVector4 srgbColor;
+
+ srgbColor.mV[0] = linearTosRGB(a.mV[0]);
+ srgbColor.mV[1] = linearTosRGB(a.mV[1]);
+ srgbColor.mV[2] = linearTosRGB(a.mV[2]);
+ srgbColor.mV[3] = a.mV[3];
+
+ return srgbColor;
+}
+
#endif