summaryrefslogtreecommitdiff
path: root/indra/llmath/llcamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath/llcamera.cpp')
-rwxr-xr-xindra/llmath/llcamera.cpp90
1 files changed, 86 insertions, 4 deletions
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 33cf185196..ff90532f75 100755
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -183,8 +183,30 @@ static const LLVector4a sFrustumScaler[] =
LLVector4a( 1, 1, 1) // 8 entries
};
-S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
+bool LLCamera::isChanged()
{
+ bool changed = false;
+ for (U32 i = 0; i < mPlaneCount; i++)
+ {
+ U8 mask = mPlaneMask[i];
+ if (mask != 0xff && !changed)
+ {
+ changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]);
+ }
+ mLastAgentPlanes[i].set(mAgentPlanes[i]);
+ }
+
+ return changed;
+}
+
+S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius, const LLPlane* planes)
+{
+ if(!planes)
+ {
+ //use agent space
+ planes = mAgentPlanes;
+ }
+
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -195,7 +217,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
mask = mPlaneMask[i];
if (mask < PLANE_MASK_NUM)
{
- const LLPlane& p(mAgentPlanes[i]);
+ const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
@@ -216,9 +238,21 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
return result?1:2;
}
+//exactly same as the function AABBInFrustum(...)
+//except uses mRegionPlanes instead of mAgentPlanes.
+S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)
+{
+ return AABBInFrustum(center, radius, mRegionPlanes);
+}
-S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
+S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)
{
+ if(!planes)
+ {
+ //use agent space
+ planes = mAgentPlanes;
+ }
+
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -229,7 +263,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
mask = mPlaneMask[i];
if ((i != 5) && (mask < PLANE_MASK_NUM))
{
- const LLPlane& p(mAgentPlanes[i]);
+ const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
@@ -250,6 +284,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
return result?1:2;
}
+//exactly same as the function AABBInFrustumNoFarClip(...)
+//except uses mRegionPlanes instead of mAgentPlanes.
+S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
+{
+ return AABBInFrustumNoFarClip(center, radius, mRegionPlanes);
+}
+
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
{
LLVector3 dist = sphere_center-mFrustCenter;
@@ -586,6 +627,47 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
}
}
+//calculate regional planes from mAgentPlanes.
+//vector "shift" is the vector of the region origin in the agent space.
+void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance)
+{
+ F32 far_w;
+ {
+ LLVector3 p = getOrigin();
+ LLVector3 n(mAgentPlanes[5][0], mAgentPlanes[5][1], mAgentPlanes[5][2]);
+ F32 dd = n * p;
+ if(dd + mAgentPlanes[5][3] < 0) //signed distance
+ {
+ far_w = -far_clip_distance - dd;
+ }
+ else
+ {
+ far_w = far_clip_distance - dd;
+ }
+ far_w += n * shift;
+ }
+
+ F32 d;
+ LLVector3 n;
+ for(S32 i = 0 ; i < 7; i++)
+ {
+ if (mPlaneMask[i] != 0xff)
+ {
+ n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]);
+
+ if(i != 5)
+ {
+ d = mAgentPlanes[i][3] + n * shift;
+ }
+ else
+ {
+ d = far_w;
+ }
+ mRegionPlanes[i].setVec(n, d);
+ }
+ }
+}
+
void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)
{
LLVector3 a, b, c;