summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
authorRoxie Linden <roxie@lindenlab.com>2010-12-23 14:15:03 -0800
committerRoxie Linden <roxie@lindenlab.com>2010-12-23 14:15:03 -0800
commit2b979742f6b28e615b2b36e10257c78711e537c3 (patch)
tree1621e871e6a6056729b33dae48e3d6845942c0ff /indra/llmath
parent8204145ab1c4b8f8a509db15f61bbdd264532508 (diff)
parent57153cf0f1fffe669b9d8871c33f9c4aaba67a2f (diff)
automated merge
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/llcamera.cpp171
-rw-r--r--indra/llmath/llcamera.h11
-rw-r--r--indra/llmath/llplane.h44
-rw-r--r--indra/llmath/llvector4a.h2
4 files changed, 102 insertions, 126 deletions
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index a442a0edb8..a30a50ab2e 100644
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -42,7 +42,6 @@ LLCamera::LLCamera() :
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
- alignPlanes();
calculateFrustumPlanes();
}
@@ -53,7 +52,6 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
- alignPlanes();
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
@@ -67,19 +65,6 @@ LLCamera::~LLCamera()
}
-const LLCamera& LLCamera::operator=(const LLCamera& rhs)
-{
- memcpy(this, &rhs, sizeof(LLCamera));
- alignPlanes();
- LLVector4a::memcpyNonAliased16((F32*) mAgentPlanes, (F32*) rhs.mAgentPlanes, 4*7*sizeof(F32));
- return *this;
-}
-
-void LLCamera::alignPlanes()
-{
- mAgentPlanes = (LLPlane*) LL_NEXT_ALIGNED_ADDRESS<U8>(mAgentPlaneBuffer);
-}
-
// ---------------- LLCamera::getFoo() member functions ----------------
F32 LLCamera::getMinView() const
@@ -104,7 +89,7 @@ void LLCamera::setUserClipPlane(LLPlane plane)
{
mPlaneCount = 7;
mAgentPlanes[6] = plane;
- mPlaneMask[6] = calcPlaneMask(plane);
+ mPlaneMask[6] = plane.calcPlaneMask();
}
void LLCamera::disableUserClipPlane()
@@ -190,38 +175,33 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
};
U8 mask = 0;
- S32 result = 2;
-
+ bool result = false;
+ LLVector4a rscale, maxp, minp;
+ LLSimdScalar d;
for (U32 i = 0; i < mPlaneCount; i++)
{
mask = mPlaneMask[i];
- if (mask == 0xff)
- {
- continue;
- }
-
- const LLPlane& p = mAgentPlanes[i];
- const LLVector4a& n = reinterpret_cast<const LLVector4a&>(p);
- float d = p.mV[3];
- LLVector4a rscale;
- rscale.setMul(radius, scaler[mask]);
-
- LLVector4a minp, maxp;
- minp.setSub(center, rscale);
- maxp.setAdd(center, rscale);
-
- if (n.dot3(minp) > -d)
+ if (mask != 0xff)
{
- return 0;
- }
-
- if (n.dot3(maxp) > -d)
- {
- result = 1;
+ const LLPlane& p(mAgentPlanes[i]);
+ p.getAt<3>(d);
+ rscale.setMul(radius, scaler[mask]);
+ minp.setSub(center, rscale);
+ d = -d;
+ if (p.dot3(minp).getF32() > d)
+ {
+ return 0;
+ }
+
+ if(!result)
+ {
+ maxp.setAdd(center, rscale);
+ result = (p.dot3(maxp).getF32() > d);
+ }
}
}
- return result;
+ return result?1:2;
}
@@ -239,43 +219,33 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
};
U8 mask = 0;
- S32 result = 2;
-
+ bool result = false;
+ LLVector4a rscale, maxp, minp;
+ LLSimdScalar d;
for (U32 i = 0; i < mPlaneCount; i++)
{
- if (i == 5)
- {
- continue;
- }
-
mask = mPlaneMask[i];
- if (mask == 0xff)
- {
- continue;
- }
-
- const LLPlane& p = mAgentPlanes[i];
- const LLVector4a& n = reinterpret_cast<const LLVector4a&>(p);
- float d = p.mV[3];
- LLVector4a rscale;
- rscale.setMul(radius, scaler[mask]);
-
- LLVector4a minp, maxp;
- minp.setSub(center, rscale);
- maxp.setAdd(center, rscale);
-
- if (n.dot3(minp) > -d)
- {
- return 0;
- }
-
- if (n.dot3(maxp) > -d)
+ if ((i != 5) && (mask != 0xff))
{
- result = 1;
+ const LLPlane& p(mAgentPlanes[i]);
+ p.getAt<3>(d);
+ rscale.setMul(radius, scaler[mask]);
+ minp.setSub(center, rscale);
+ d = -d;
+ if (p.dot3(minp).getF32() > d)
+ {
+ return 0;
+ }
+
+ if(!result)
+ {
+ maxp.setAdd(center, rscale);
+ result = (p.dot3(maxp).getF32() > d);
+ }
}
}
- return result;
+ return result?1:2;
}
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
@@ -396,28 +366,22 @@ int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radiu
int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const
{
// Returns 1 if sphere is in frustum, 0 if not.
- int res = 2;
+ bool res = false;
for (int i = 0; i < 6; i++)
{
- if (mPlaneMask[i] == 0xff)
- {
- continue;
- }
-
- float d = mAgentPlanes[i].dist(sphere_center);
-
- if (d > radius)
+ if (mPlaneMask[i] != 0xff)
{
- return 0;
- }
+ float d = mAgentPlanes[i].dist(sphere_center);
- if (d > -radius)
- {
- res = 1;
+ if (d > radius)
+ {
+ return 0;
+ }
+ res |= (d > -radius);
}
}
- return res;
+ return res?1:2;
}
@@ -569,25 +533,6 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3)
return LLPlane(p1, n);
}
-U8 LLCamera::calcPlaneMask(const LLPlane& plane)
-{
- U8 mask = 0;
-
- if (plane.mV[0] >= 0)
- {
- mask |= 1;
- }
- if (plane.mV[1] >= 0)
- {
- mask |= 2;
- }
- if (plane.mV[2] >= 0)
- {
- mask |= 4;
- }
-
- return mask;
-}
void LLCamera::ignoreAgentFrustumPlane(S32 idx)
{
@@ -597,13 +542,12 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx)
}
mPlaneMask[idx] = 0xff;
- mAgentPlanes[idx].clearVec();
+ mAgentPlanes[idx].clear();
}
void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
{
- alignPlanes();
-
+
for (int i = 0; i < 8; i++)
{
mAgentFrustum[i] = frust[i];
@@ -636,7 +580,7 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
//cache plane octant facing mask for use in AABBInFrustum
for (U32 i = 0; i < mPlaneCount; i++)
{
- mPlaneMask[i] = calcPlaneMask(mAgentPlanes[i]);
+ mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask();
}
}
@@ -689,9 +633,10 @@ void LLCamera::calculateWorldFrustumPlanes()
F32 d;
LLVector3 center = mOrigin - mXAxis*mNearPlane;
mWorldPlanePos = center;
+ LLVector3 pnorm;
for (int p=0; p<4; p++)
{
- LLVector3 pnorm = LLVector3(mLocalPlanes[p]);
+ mLocalPlanes[p].getVector3(pnorm);
LLVector3 norm = rotateToAbsolute(pnorm);
norm.normVec();
d = -(center * norm);
@@ -701,13 +646,15 @@ void LLCamera::calculateWorldFrustumPlanes()
LLVector3 zaxis(0, 0, 1.0f);
F32 yaw = getYaw();
{
- LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_LEFT]);
+ LLVector3 tnorm;
+ mLocalPlanes[PLANE_LEFT].getVector3(tnorm);
tnorm.rotVec(yaw, zaxis);
d = -(mOrigin * tnorm);
mHorizPlanes[HORIZ_PLANE_LEFT] = LLPlane(tnorm, d);
}
{
- LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_RIGHT]);
+ LLVector3 tnorm;
+ mLocalPlanes[PLANE_RIGHT].getVector3(tnorm);
tnorm.rotVec(yaw, zaxis);
d = -(mOrigin * tnorm);
mHorizPlanes[HORIZ_PLANE_RIGHT] = LLPlane(tnorm, d);
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index e15bd7ad43..a346322e0e 100644
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -79,8 +79,6 @@ public:
{
*this = rhs;
}
-
- const LLCamera& operator=(const LLCamera& rhs);
enum {
PLANE_LEFT = 0,
@@ -119,6 +117,9 @@ public:
};
private:
+ LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ U8 mPlaneMask[8]; // 8 for alignment
+
F32 mView; // angle between top and bottom frustum planes in radians.
F32 mAspect; // width/height
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
@@ -132,10 +133,6 @@ private:
LLPlane mWorldPlanes[PLANE_NUM];
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
- LLPlane* mAgentPlanes; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
- U8 mAgentPlaneBuffer[sizeof(LLPlane)*8];
- U8 mPlaneMask[7];
-
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
@@ -149,11 +146,9 @@ public:
LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
virtual ~LLCamera();
- void alignPlanes();
void setUserClipPlane(LLPlane plane);
void disableUserClipPlane();
- U8 calcPlaneMask(const LLPlane& plane);
virtual void setView(F32 vertical_fov_rads);
void setViewHeightInPixels(S32 height);
void setAspect(F32 new_aspect);
diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h
index 443f3f46b9..a611894721 100644
--- a/indra/llmath/llplane.h
+++ b/indra/llmath/llplane.h
@@ -36,19 +36,23 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
-class LLPlane : public LLVector4
+class LLPlane
{
public:
+
+ // Constructors
LLPlane() {}; // no default constructor
LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); }
LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); }
- void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); }
- void setVec(const LLVector3 &p0, const LLVector3 &n)
+ inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); }
+
+ // Set
+ inline void setVec(const LLVector3 &p0, const LLVector3 &n)
{
F32 d = -(p0 * n);
setVec(n, d);
}
- void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
+ inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
{
LLVector3 u, v, w;
u = p1 - p0;
@@ -58,8 +62,38 @@ public:
F32 d = -(w * p0);
setVec(w, d);
}
- LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;}
+
+ inline LLPlane& operator=(const LLVector4& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;}
+
+ inline LLPlane& operator=(const LLVector4a& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;}
+
+ inline void set(const LLPlane& p2) { mV = p2.mV; }
+
+ //
F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; }
+
+ inline LLSimdScalar dot3(const LLVector4a& b) const { return mV.dot3(b); }
+
+ // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates
+ // the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead
+ inline F32 operator[](const S32 idx) const { return mV[idx]; }
+
+ // preferable when index is known at compile time
+ template <int N> LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt<N>(); }
+
+ // reset the vector to 0, 0, 0, 1
+ inline void clear() { mV.set(0, 0, 0, 1); }
+
+ inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); }
+
+ // Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero.
+ inline U8 calcPlaneMask()
+ {
+ return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ;
+ }
+
+private:
+ LLVector4a mV;
};
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 79022eade3..596082509d 100644
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -67,7 +67,7 @@ public:
extern const LLVector4a LL_V4A_ZERO;
return LL_V4A_ZERO;
}
-
+
// Return a vector of all epsilon, where epsilon is a small float suitable for approximate equality checks
static inline const LLVector4a& getEpsilon()
{