summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/llcamera.cpp95
-rw-r--r--indra/llmath/llmath.h8
2 files changed, 89 insertions, 14 deletions
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index b782d4f3b9..0f343bcefe 100644
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -178,28 +178,95 @@ S32 LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
U8 mask = 0;
S32 result = 2;
- for (U32 i = 0; i < mPlaneCount; i++)
- {
- mask = mAgentPlanes[i].mask;
- LLPlane p = mAgentPlanes[i].p;
- LLVector3 n = LLVector3(p);
- float d = p.mV[3];
- LLVector3 rscale = radius.scaledVec(scaler[mask]);
+ if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist)
+ { //box is larger than frustum, check frustum quads against box planes
- LLVector3 minp = center - rscale;
- LLVector3 maxp = center + rscale;
-
- if (n * minp > -d)
+ static const LLVector3 dir[] =
{
- return 0;
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+ };
+
+ U32 quads[] =
+ {
+ 0, 1, 2, 3,
+ 0, 1, 5, 4,
+ 2, 3, 7, 6,
+ 3, 0, 7, 4,
+ 1, 2, 6, 4,
+ 4, 5, 6, 7
+ };
+
+ result = 0;
+
+ BOOL total_inside = TRUE;
+ for (U32 i = 0; i < 6; i++)
+ {
+ LLVector3 p = center + radius.scaledVec(dir[i]);
+ F32 d = -p*dir[i];
+
+ for (U32 j = 0; j < 6; j++)
+ { //for each quad
+ F32 dist = mAgentFrustum[quads[j*4+0]]*dir[i] + d;
+ if (dist > 0)
+ { //at least one frustum point is outside the AABB
+ total_inside = FALSE;
+ for (U32 k = 1; k < 4; k++)
+ { //for each other point on quad
+ if ( mAgentFrustum[quads[j*4+k]]*dir[i]+d <= 0.f)
+ { //quad is straddling some plane of AABB
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ for (U32 k = 1; k < 4; k++)
+ {
+ if (mAgentFrustum[quads[j*4+k]]*dir[i]+d > 0.f)
+ {
+ return 1;
+ }
+ }
+ }
+ }
}
-
- if (n * maxp > -d)
+
+ if (total_inside)
{
result = 1;
}
}
+ else
+ {
+ for (U32 i = 0; i < mPlaneCount; i++)
+ {
+ mask = mAgentPlanes[i].mask;
+ LLPlane p = mAgentPlanes[i].p;
+ LLVector3 n = LLVector3(p);
+ float d = p.mV[3];
+ LLVector3 rscale = radius.scaledVec(scaler[mask]);
+
+ LLVector3 minp = center - rscale;
+ LLVector3 maxp = center + rscale;
+
+ if (n * minp > -d)
+ {
+ return 0;
+ }
+
+ if (n * maxp > -d)
+ {
+ result = 1;
+ }
+ }
+ }
+
return result;
}
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 5e987f3193..12fc116714 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -86,6 +86,8 @@ const F32 GRAVITY = -9.8f;
const F32 F_PI = 3.1415926535897932384626433832795f;
const F32 F_TWO_PI = 6.283185307179586476925286766559f;
const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f;
+const F32 F_SQRT_TWO_PI = 2.506628274631000502415765284811f;
+const F32 F_E = 2.71828182845904523536f;
const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
const F32 F_SQRT3 = 1.73205080756888288657986402541f;
const F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
@@ -548,4 +550,10 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two)
return val;
}
+//get the gaussian value given the linear distance from axis x and guassian value o
+inline F32 llgaussian(F32 x, F32 o)
+{
+ return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));
+}
+
#endif