diff options
Diffstat (limited to 'indra/llmath')
-rw-r--r-- | indra/llmath/llcamera.cpp | 95 | ||||
-rw-r--r-- | indra/llmath/llmath.h | 8 |
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 ¢er, 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 |