summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/lloctree.h79
-rw-r--r--indra/llmath/lltreenode.h5
-rw-r--r--indra/llmath/llvolume.cpp159
-rw-r--r--indra/llmath/llvolume.h3
-rw-r--r--indra/llmath/m3math.cpp95
-rw-r--r--indra/llmath/m3math.h9
-rw-r--r--indra/llmath/m4math.h9
-rw-r--r--indra/llmath/v2math.h15
-rw-r--r--indra/llmath/v3math.cpp4
-rw-r--r--indra/llmath/v3math.h14
-rw-r--r--indra/llmath/v4math.h11
11 files changed, 217 insertions, 186 deletions
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index bea21e22c6..e5b2a5f312 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -21,6 +21,7 @@
#endif
#define LL_OCTREE_PARANOIA_CHECK 0
+#define LL_OCTREE_MAX_CAPACITY 256
template <class T> class LLOctreeState;
template <class T> class LLOctreeNode;
@@ -88,7 +89,8 @@ public:
virtual void removeByAddress(T* data) { getOctState()->removeByAddress(data); }
virtual bool hasLeafState() const { return getOctState()->isLeaf(); }
virtual void destroy() { getOctState()->destroy(); }
- virtual oct_node* getNodeAt(T* data) { return getOctState()->getNodeAt(data); }
+ virtual oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
+ virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { return getOctState()->getNodeAt(pos, rad); }
virtual U8 getOctant() const { return mOctant; }
virtual void setOctant(U8 octant) { mOctant = octant; }
virtual const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; }
@@ -117,9 +119,14 @@ public:
return ret;
}
+ virtual bool isInside(const LLVector3d& pos, const F64& rad) const
+ {
+ return rad <= mSize.mdV[0]*2.0 && isInside(pos);
+ }
+
virtual bool isInside(T* data) const
{
- return data->getBinRadius() <= mSize.mdV[0]*2.0 && isInside(data->getPositionGroup());
+ return isInside(data->getPositionGroup(), data->getBinRadius());
}
virtual bool isInside(const LLVector3d& pos) const
@@ -155,6 +162,11 @@ public:
bool contains(T* xform)
{
+ return contains(xform->getBinRadius());
+ }
+
+ bool contains(F64 radius)
+ {
if (mParent == NULL)
{ //root node contains nothing
return false;
@@ -162,7 +174,6 @@ public:
F64 size = mSize.mdV[0];
F64 p_size = size * 2.0;
- F64 radius = xform->getBinRadius();
return (radius <= 0.001 && size <= 0.001) ||
(radius <= p_size && radius > size);
@@ -247,11 +258,15 @@ public:
oct_node* getOctNode() { return (oct_node*) BaseType::getNode(); }
virtual oct_node* getNodeAt(T* data)
+ {
+ return getNodeAt(data->getPositionGroup(), data->getBinRadius());
+ }
+
+ virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad)
{
- const LLVector3d& pos = data->getPositionGroup();
LLOctreeNode<T>* node = getOctNode();
- if (node->isInside(data))
+ if (node->isInside(pos, rad))
{
//do a quick search by octant
U8 octant = node->getOctant(pos.mdV);
@@ -261,7 +276,7 @@ public:
//at the appropriate octant or is smaller than the object.
//by definition, that node is the smallest node that contains
// the data
- while (keep_going && node->getSize().mdV[0] >= data->getBinRadius())
+ while (keep_going && node->getSize().mdV[0] >= rad)
{
keep_going = FALSE;
for (U32 i = 0; i < node->getChildCount() && !keep_going; i++)
@@ -275,9 +290,9 @@ public:
}
}
}
- else if (!node->contains(data) && node->getParent())
+ else if (!node->contains(rad) && node->getParent())
{ //if we got here, data does not exist in this node
- return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(data);
+ return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad);
}
return node;
@@ -291,22 +306,15 @@ public:
return false;
}
LLOctreeNode<T>* node = getOctNode();
+ LLOctreeNode<T>* parent = node->getOctParent();
- if (data->getBinRadius() <= node->getSize().mdV[0])
- {
- oct_node* dest = getNodeAt(data);
-
- if (dest != node)
- {
- dest->insert(data);
- return false;
- }
- }
-
- //no kid found, is it even here?
- if (node->isInside(data))
+ //is it here?
+ if (node->isInside(data->getPositionGroup()))
{
- if (node->contains(data))
+ if (getElementCount() < LL_OCTREE_MAX_CAPACITY &&
+ (node->contains(data->getBinRadius()) ||
+ (data->getBinRadius() > node->getSize().mdV[0] &&
+ parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
{ //it belongs here
if (data == NULL)
{
@@ -327,7 +335,19 @@ public:
return true;
}
else
- {
+ {
+ //find a child to give it to
+ oct_node* child = NULL;
+ for (U32 i = 0; i < getChildCount(); i++)
+ {
+ child = getChild(i);
+ if (child->isInside(data->getPositionGroup()))
+ {
+ child->insert(data);
+ return false;
+ }
+ }
+
//it's here, but no kids are in the right place, make a new kid
LLVector3d center(node->getCenter());
LLVector3d size(node->getSize()*0.5);
@@ -359,7 +379,7 @@ public:
//make the new kid
LLOctreeState<T>* newstate = new LLOctreeState<T>();
- oct_node* child = new LLOctreeNode<T>(center, size, newstate, node);
+ child = new LLOctreeNode<T>(center, size, newstate, node);
addChild(child);
child->insert(data);
@@ -367,8 +387,15 @@ public:
}
else
{
- //it's not in here, give it to the parent
- node->getOctParent()->insert(data);
+ //it's not in here, give it to the root
+ LLOctreeNode<T>* parent = node->getOctParent();
+ while (parent)
+ {
+ node = parent;
+ parent = node->getOctParent();
+ }
+
+ node->insert(data);
}
return false;
diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h
index dd0c73c00c..cdc52cf90a 100644
--- a/indra/llmath/lltreenode.h
+++ b/indra/llmath/lltreenode.h
@@ -22,7 +22,6 @@ class LLTreeState
public:
LLTreeState(LLTreeNode<T>* node) { setNode(node); }
virtual ~LLTreeState() { };
-
virtual bool insert(T* data) = 0;
virtual bool remove(T* data) = 0;
virtual void setNode(LLTreeNode<T>* node);
@@ -35,7 +34,7 @@ private:
};
template <class T>
-class LLTreeListener
+class LLTreeListener: public LLRefCount
{
public:
virtual ~LLTreeListener() { };
@@ -75,7 +74,7 @@ protected:
LLTreeState<T>* mState;
public:
- std::vector<LLTreeListener<T>*> mListeners;
+ std::vector<LLPointer<LLTreeListener<T> > > mListeners;
};
template <class T>
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 75e4042f07..5354de783c 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1765,9 +1765,6 @@ void LLVolume::createVolumeFaces()
mVolumeFaces[i].create();
}
}
-
- mBounds[1] = LLVector3(0,0,0);
- mBounds[0] = LLVector3(512,512,512);
}
@@ -1812,21 +1809,28 @@ void LLVolumeParams::copyParams(const LLVolumeParams &params)
mPathParams.copyParams(params.mPathParams);
}
+// Less restricitve approx 0 for volumes
+const F32 APPROXIMATELY_ZERO = 0.001f;
+bool approx_zero( F32 f, F32 tolerance = APPROXIMATELY_ZERO)
+{
+ return (f >= -tolerance) && (f <= tolerance);
+}
+
// return true if in range (or nearly so)
-static bool limit_range(F32& v, F32 min, F32 max)
+static bool limit_range(F32& v, F32 min, F32 max, F32 tolerance = APPROXIMATELY_ZERO)
{
F32 min_delta = v - min;
if (min_delta < 0.f)
{
v = min;
- if (!is_approx_zero(min_delta))
+ if (!approx_zero(min_delta, tolerance))
return false;
}
F32 max_delta = max - v;
if (max_delta < 0.f)
{
v = max;
- if (!is_approx_zero(max_delta))
+ if (!approx_zero(max_delta, tolerance))
return false;
}
return true;
@@ -1841,9 +1845,10 @@ bool LLVolumeParams::setBeginAndEndS(const F32 b, const F32 e)
valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA);
F32 end = e;
+ if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error
valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
- valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA);
+ valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
// Now set them.
mProfileParams.setBegin(begin);
@@ -1863,7 +1868,7 @@ bool LLVolumeParams::setBeginAndEndT(const F32 b, const F32 e)
F32 end = e;
valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
- valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA);
+ valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
// Now set them.
mPathParams.setBegin(begin);
@@ -2020,7 +2025,7 @@ bool LLVolumeParams::setRadiusOffset(const F32 offset)
{
radius_offset = max_radius_mag;
}
- valid = is_approx_zero(delta);
+ valid = approx_zero(delta, .1f);
}
mPathParams.setRadiusOffset(radius_offset);
@@ -2054,7 +2059,7 @@ bool LLVolumeParams::setSkew(const F32 skew_value)
{
skew = min_skew_mag;
}
- valid = is_approx_zero(delta);
+ valid = approx_zero(delta);
}
mPathParams.setSkew(skew);
@@ -2980,10 +2985,15 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
S32 v2 = face.mIndices[j*3+((k+1)%3)];
vertices.push_back(face.mVertices[v1].mPosition*mat);
- normals.push_back(face.mVertices[v1].mNormal*norm_mat);
+ LLVector3 norm1 = face.mVertices[v1].mNormal * norm_mat;
+ norm1.normVec();
+ normals.push_back(norm1);
vertices.push_back(face.mVertices[v2].mPosition*mat);
- normals.push_back(face.mVertices[v2].mNormal*norm_mat);
+ LLVector3 norm2 = face.mVertices[v2].mNormal * norm_mat;
+ norm2.normVec();
+ normals.push_back(norm2);
+
segments.push_back(vertices.size());
}
}
@@ -3747,6 +3757,9 @@ BOOL LLVolumeFace::createUnCutCubeCap()
num_vertices = (grid_size+1)*(grid_size+1);
num_indices = quad_count * 4;
+ LLVector3& min = mExtents[0];
+ LLVector3& max = mExtents[1];
+
S32 offset = 0;
if (mTypeMask & TOP_MASK)
offset = (max_t-1) * max_s;
@@ -3786,32 +3799,6 @@ BOOL LLVolumeFace::createUnCutCubeCap()
}
S32 vtop = mVertices.size();
-// S32 itop = mIndices.size();
-/// vector_append(mVertices,4);
-// vector_append(mIndices,4);
-// LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
-#if 0
- for(int t=0;t<4;t++){
- VertexData vd;
- vd.mPosition = corners[t].mPosition;
- vd.mNormal =
- ((corners[(t+1)%4].mPosition-corners[t].mPosition)%
- (corners[(t+2)%4].mPosition-corners[(t+1)%4].mPosition));
- vd.mNormal.normVec();
-
- if (mTypeMask & TOP_MASK)
- vd.mNormal *= -1.0f;
- vd.mBinormal = vd.mNormal;
- vd.mTexCoord = corners[t].mTexCoord;
- mVertices.push_back(vd);
- }
- int idxs[] = {0,1,2,2,3,0};
- if (mTypeMask & TOP_MASK){
- for(int i=0;i<6;i++)mIndices.push_back(vtop+idxs[i]);
- }else{
- for(int i=5;i>=0;i--)mIndices.push_back(vtop+idxs[i]);
- }
-#else
for(int gx = 0;gx<grid_size+1;gx++){
for(int gy = 0;gy<grid_size+1;gy++){
VertexData newVert;
@@ -3823,8 +3810,20 @@ BOOL LLVolumeFace::createUnCutCubeCap()
(F32)gx/(F32)grid_size,
(F32)gy/(F32)grid_size);
mVertices.push_back(newVert);
+
+ if (gx == 0 && gy == 0)
+ {
+ min = max = newVert.mPosition;
+ }
+ else
+ {
+ update_min_max(min,max,newVert.mPosition);
+ }
}
}
+
+ mCenter = (min + max) * 0.5f;
+
int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
for(int gx = 0;gx<grid_size;gx++){
for(int gy = 0;gy<grid_size;gy++){
@@ -3835,7 +3834,7 @@ BOOL LLVolumeFace::createUnCutCubeCap()
}
}
}
-#endif
+
return TRUE;
}
@@ -3882,12 +3881,15 @@ BOOL LLVolumeFace::createCap()
// Figure out the normal, assume all caps are flat faces.
// Cross product to get normals.
- LLVector2 cuv = LLVector2(0,0);
-
+ LLVector2 cuv;
+ LLVector2 min_uv, max_uv;
+
+ LLVector3& min = mExtents[0];
+ LLVector3& max = mExtents[1];
+
// Copy the vertices into the array
for (i = 0; i < num_vertices; i++)
{
-
if (mTypeMask & TOP_MASK)
{
mVertices[i].mTexCoord.mV[0] = profile[i].mV[0]+0.5f;
@@ -3900,17 +3902,22 @@ BOOL LLVolumeFace::createCap()
mVertices[i].mTexCoord.mV[1] = 0.5f - profile[i].mV[1];
}
- if(i){
- //Dont include the first point of the profile in the average
- cuv += mVertices[i].mTexCoord;
- mCenter += mVertices[i].mPosition = mesh[i + offset].mPos;
+ mVertices[i].mPosition = mesh[i + offset].mPos;
+
+ if (i == 0)
+ {
+ min = max = mVertices[i].mPosition;
+ min_uv = max_uv = mVertices[i].mTexCoord;
+ }
+ else
+ {
+ update_min_max(min,max, mVertices[i].mPosition);
+ update_min_max(min_uv, max_uv, mVertices[i].mTexCoord);
}
- else mVertices[i].mPosition = mesh[i + offset].mPos;
- //mVertices[i].mNormal = normal;
}
- mCenter /= (F32)(num_vertices-1);
- cuv /= (F32)(num_vertices-1);
+ mCenter = (min+max)*0.5f;
+ cuv = (min_uv + max_uv)*0.5f;
LLVector3 binormal = calc_binormal_from_triangle(
mCenter, cuv,
@@ -4215,13 +4222,11 @@ BOOL LLVolumeFace::createCap()
return TRUE;
}
-
BOOL LLVolumeFace::createSide()
{
BOOL flat = mTypeMask & FLAT_MASK;
S32 num_vertices, num_indices;
-
const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh();
const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile;
const std::vector<LLPath::PathPt>& path_data = mVolumep->getPath().mPath;
@@ -4237,6 +4242,9 @@ BOOL LLVolumeFace::createSide()
vector_append(mIndices,num_indices);
vector_append(mEdge, num_indices);
+ LLVector3& face_min = mExtents[0];
+ LLVector3& face_max = mExtents[1];
+
mCenter.clearVec();
S32 begin_stex = llfloor( profile[mBeginS].mV[2] );
@@ -4284,17 +4292,26 @@ BOOL LLVolumeFace::createSide()
i = mBeginS + s + max_s*t;
}
- mCenter += mVertices[cur_vertex].mPosition = mesh[i].mPos;
+ mVertices[cur_vertex].mPosition = mesh[i].mPos;
mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt);
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
+ if (cur_vertex == 0)
+ {
+ face_min = face_max = mesh[i].mPos;
+ }
+ else
+ {
+ update_min_max(face_min, face_max, mesh[i].mPos);
+ }
+
cur_vertex++;
if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0)
{
- mCenter += mVertices[cur_vertex].mPosition = mesh[i].mPos;
+ mVertices[cur_vertex].mPosition = mesh[i].mPos;
mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt);
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
@@ -4316,15 +4333,19 @@ BOOL LLVolumeFace::createSide()
i = mBeginS + s + max_s*t;
ss = profile[mBeginS + s].mV[2] - begin_stex;
- mCenter += mVertices[cur_vertex].mPosition = mesh[i].mPos;
+ mVertices[cur_vertex].mPosition = mesh[i].mPos;
mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt);
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
+
+ update_min_max(face_min,face_max,mesh[i].mPos);
+
cur_vertex++;
}
}
- mCenter /= (F32)num_vertices;
+
+ mCenter = (face_min + face_max) * 0.5f;
S32 cur_index = 0;
S32 cur_edge = 0;
@@ -4448,32 +4469,14 @@ BOOL LLVolumeFace::createSide()
}
}
- //this loop would LOVE OpenMP
- LLVector3 min = mVolumep->mBounds[0] - mVolumep->mBounds[1];
- LLVector3 max = mVolumep->mBounds[0] + mVolumep->mBounds[1];
-
- if (min == max && min == LLVector3(512,512,512))
+ //normalize normals and binormals here so the meshes that reference
+ //this volume data don't have to
+ for (U32 i = 0; i < mVertices.size(); i++)
{
- min = max = mVertices[0].mPosition;
- }
-
- for (U32 i = 0; i < mVertices.size(); i++) {
mVertices[i].mNormal.normVec();
mVertices[i].mBinormal.normVec();
-
- for (U32 j = 0; j < 3; j++) {
- if (mVertices[i].mPosition.mV[j] > max.mV[j]) {
- max.mV[j] = mVertices[i].mPosition.mV[j];
- }
- if (mVertices[i].mPosition.mV[j] < min.mV[j]) {
- min.mV[j] = mVertices[i].mPosition.mV[j];
- }
- }
}
- mVolumep->mBounds[0] = (min + max) * 0.5f; //center
- mVolumep->mBounds[1] = (max - min) * 0.5f; //half-height
-
return TRUE;
}
@@ -4572,7 +4575,7 @@ LLVector3 calc_binormal_from_triangle(
-r0.mV[VZ] / r0.mV[VX],
-r1.mV[VZ] / r1.mV[VX],
-r2.mV[VZ] / r2.mV[VX]);
- //binormal.normVec();
+ // binormal.normVec();
return binormal;
}
else
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index cf9ae00f21..97aeeb9589 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -756,6 +756,8 @@ public:
S32 mNumS;
S32 mNumT;
+ LLVector3 mExtents[2]; //minimum and maximum point of face
+
std::vector<VertexData> mVertices;
std::vector<S32> mIndices;
std::vector<S32> mEdge;
@@ -849,7 +851,6 @@ public:
const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
U32 mFaceMask; // bit array of which faces exist in this volume
- LLVector3 mBounds[2]; // bounding box (center, half-height)
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
protected:
diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp
index 523acb4dcf..6483f2adbe 100644
--- a/indra/llmath/m3math.cpp
+++ b/indra/llmath/m3math.cpp
@@ -33,14 +33,14 @@
LLMatrix3::LLMatrix3(const LLQuaternion &q)
{
- *this = q.getMatrix3();
+ setRot(q);
}
LLMatrix3::LLMatrix3(const F32 angle, const LLVector3 &vec)
{
LLQuaternion quat(angle, vec);
- *this = setRot(quat);
+ setRot(quat);
}
LLMatrix3::LLMatrix3(const F32 angle, const LLVector3d &vec)
@@ -48,60 +48,25 @@ LLMatrix3::LLMatrix3(const F32 angle, const LLVector3d &vec)
LLVector3 vec_f;
vec_f.setVec(vec);
LLQuaternion quat(angle, vec_f);
- *this = setRot(quat);
+ setRot(quat);
}
LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)
{
LLQuaternion quat(angle, vec);
- *this = setRot(quat);
+ 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);
- *this = setRot(quat);
+ setRot(quat);
}
LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)
{
- // Rotates RH about x-axis by 'roll' then
- // rotates RH about the old y-axis by 'pitch' then
- // rotates RH about the original z-axis by 'yaw'.
- // .
- // /|\ yaw axis
- // | __.
- // ._ ___| /| pitch axis
- // _||\ \\ |-. /
- // \|| \_______\_|__\_/_______
- // | _ _ o o o_o_o_o o /_\_ ________\ roll axis
- // // /_______/ /__________> /
- // /_,-' // /
- // /__,-'
-
- F32 cx, sx, cy, sy, cz, sz;
- F32 cxsy, sxsy;
-
- cx = (F32)cos(roll); //A
- sx = (F32)sin(roll); //B
- cy = (F32)cos(pitch); //C
- sy = (F32)sin(pitch); //D
- cz = (F32)cos(yaw); //E
- sz = (F32)sin(yaw); //F
-
- cxsy = cx * sy; //AD
- sxsy = sx * sy; //BD
-
- mMatrix[0][0] = cy * cz;
- mMatrix[1][0] = -cy * sz;
- mMatrix[2][0] = sy;
- mMatrix[0][1] = sxsy * cz + cx * sz;
- mMatrix[1][1] = -sxsy * sz + cx * cz;
- mMatrix[2][1] = -sx * cy;
- mMatrix[0][2] = -cxsy * cz + sx * sz;
- mMatrix[1][2] = cxsy * sz + sx * cz;
- mMatrix[2][2] = cx * cy;
+ setRot(roll,pitch,yaw);
}
// From Matrix and Quaternion FAQ
@@ -288,34 +253,64 @@ LLQuaternion LLMatrix3::quaternion() const
// These functions take Rotation arguments
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
{
- LLMatrix3 mat(angle, x, y, z);
- *this = mat;
+ setRot(LLQuaternion(angle,x,y,z));
return *this;
}
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
{
- LLMatrix3 mat(angle, vec);
- *this = mat;
+ setRot(LLQuaternion(angle, vec));
return *this;
}
const LLMatrix3& LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 yaw)
{
- LLMatrix3 mat(roll, pitch, yaw);
- *this = mat;
+ // Rotates RH about x-axis by 'roll' then
+ // rotates RH about the old y-axis by 'pitch' then
+ // rotates RH about the original z-axis by 'yaw'.
+ // .
+ // /|\ yaw axis
+ // | __.
+ // ._ ___| /| pitch axis
+ // _||\ \\ |-. /
+ // \|| \_______\_|__\_/_______
+ // | _ _ o o o_o_o_o o /_\_ ________\ roll axis
+ // // /_______/ /__________> /
+ // /_,-' // /
+ // /__,-'
+
+ F32 cx, sx, cy, sy, cz, sz;
+ F32 cxsy, sxsy;
+
+ cx = (F32)cos(roll); //A
+ sx = (F32)sin(roll); //B
+ cy = (F32)cos(pitch); //C
+ sy = (F32)sin(pitch); //D
+ cz = (F32)cos(yaw); //E
+ sz = (F32)sin(yaw); //F
+
+ cxsy = cx * sy; //AD
+ sxsy = sx * sy; //BD
+
+ mMatrix[0][0] = cy * cz;
+ mMatrix[1][0] = -cy * sz;
+ mMatrix[2][0] = sy;
+ mMatrix[0][1] = sxsy * cz + cx * sz;
+ mMatrix[1][1] = -sxsy * sz + cx * cz;
+ mMatrix[2][1] = -sx * cy;
+ mMatrix[0][2] = -cxsy * cz + sx * sz;
+ mMatrix[1][2] = cxsy * sz + sx * cz;
+ mMatrix[2][2] = cx * cy;
return *this;
}
const LLMatrix3& LLMatrix3::setRot(const LLQuaternion &q)
{
- LLMatrix3 mat(q);
- *this = mat;
+ *this = q.getMatrix3();
return *this;
}
-
const LLMatrix3& LLMatrix3::setRows(const LLVector3 &fwd, const LLVector3 &left, const LLVector3 &up)
{
mMatrix[0][0] = fwd.mV[0];
diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h
index ac93ed86fb..c3798fca73 100644
--- a/indra/llmath/m3math.h
+++ b/indra/llmath/m3math.h
@@ -32,9 +32,6 @@ class LLQuaternion;
static const U32 NUM_VALUES_IN_MAT3 = 3;
-#if LL_WINDOWS
-__declspec( align(16) )
-#endif
class LLMatrix3
{
public:
@@ -119,11 +116,7 @@ class LLMatrix3
friend const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b); // Return a * b
friend std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a); // Stream a
-}
-#if LL_DARWIN
-__attribute__ ((aligned (16)))
-#endif
-;
+};
inline LLMatrix3::LLMatrix3(void)
{
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index 4f26d875ff..69463d7718 100644
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -73,9 +73,6 @@ class LLQuaternion;
static const U32 NUM_VALUES_IN_MAT4 = 4;
-#if LL_WINDOWS
-__declspec(align(16))
-#endif
class LLMatrix4
{
public:
@@ -218,11 +215,7 @@ public:
friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b); // Return a * b
friend std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a); // Stream a
-}
-#if LL_DARWIN
-__attribute__ ((aligned (16)))
-#endif
-;
+};
inline LLMatrix4::LLMatrix4()
diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h
index c94333e2a9..863318551e 100644
--- a/indra/llmath/v2math.h
+++ b/indra/llmath/v2math.h
@@ -298,6 +298,21 @@ inline LLVector2 operator-(const LLVector2 &a)
return LLVector2( -a.mV[0], -a.mV[1] );
}
+inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos)
+{
+ for (U32 i = 0; i < 2; i++)
+ {
+ if (min.mV[i] > pos.mV[i])
+ {
+ min.mV[i] = pos.mV[i];
+ }
+ if (max.mV[i] < pos.mV[i])
+ {
+ max.mV[i] = pos.mV[i];
+ }
+ }
+}
+
inline std::ostream& operator<<(std::ostream& s, const LLVector2 &a)
{
s << "{ " << a.mV[VX] << ", " << a.mV[VY] << " }";
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index 9e6084565e..c68e72bb97 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -118,7 +118,7 @@ const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec)
{
if ( !vec.isExactlyZero() && angle )
{
- *this = *this * LLMatrix3(angle, vec);
+ *this = *this * LLQuaternion(angle, vec);
}
return *this;
}
@@ -128,7 +128,7 @@ const LLVector3& LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z)
LLVector3 vec(x, y, z);
if ( !vec.isExactlyZero() && angle )
{
- *this = *this * LLMatrix3(angle, vec);
+ *this = *this * LLQuaternion(angle, vec);
}
return *this;
}
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 72372c07e9..f787fa2ac1 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -396,6 +396,20 @@ inline BOOL LLVector3::isNull() const
return FALSE;
}
+inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
+{
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (min.mV[i] > pos.mV[i])
+ {
+ min.mV[i] = pos.mV[i];
+ }
+ if (max.mV[i] < pos.mV[i])
+ {
+ max.mV[i] = pos.mV[i];
+ }
+ }
+}
inline F32 angle_between(const LLVector3& a, const LLVector3& b)
{
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index abdc66e0b1..e9b8d5b71f 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -21,10 +21,6 @@ class LLQuaternion;
static const U32 LENGTHOFVECTOR4 = 4;
-#if LL_WINDOWS
-__declspec( align(16) )
-#endif
-
class LLVector4
{
public:
@@ -95,12 +91,7 @@ class LLVector4
friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k
friend LLVector4 operator-(const LLVector4 &a); // Return vector -a
-}
-#if LL_DARWIN
-__attribute__ ((aligned (16)))
-#endif
-;
-
+};
// Non-member functions
F32 angle_between(const LLVector4 &a, const LLVector4 &b); // Returns angle (radians) between a and b