summaryrefslogtreecommitdiff
path: root/indra/llmath/llcamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath/llcamera.cpp')
-rw-r--r--indra/llmath/llcamera.cpp127
1 files changed, 96 insertions, 31 deletions
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 2ec9ba8503..3b9ba9d0f7 100644
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -43,7 +43,8 @@ LLCamera::LLCamera() :
mViewHeightInPixels( -1 ), // invalid height
mNearPlane(DEFAULT_NEAR_PLANE),
mFarPlane(DEFAULT_FAR_PLANE),
- mFixedDistance(-1.f)
+ mFixedDistance(-1.f),
+ mPlaneCount(6)
{
calculateFrustumPlanes();
}
@@ -56,7 +57,8 @@ LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pix
mViewHeightInPixels(view_height_in_pixels),
mNearPlane(near_plane),
mFarPlane(far_plane),
- mFixedDistance(-1.f)
+ mFixedDistance(-1.f),
+ mPlaneCount(6)
{
if (mView < MIN_FIELD_OF_VIEW) { mView = MIN_FIELD_OF_VIEW; }
else if (mView > MAX_FIELD_OF_VIEW) { mView = MAX_FIELD_OF_VIEW; }
@@ -78,6 +80,18 @@ LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pix
// ---------------- LLCamera::setFoo() member functions ----------------
+void LLCamera::setUserClipPlane(LLPlane plane)
+{
+ mPlaneCount = 7;
+ mAgentPlanes[6].p = plane;
+ mAgentPlanes[6].mask = calcPlaneMask(plane);
+}
+
+void LLCamera::disableUserClipPlane()
+{
+ mPlaneCount = 6;
+}
+
void LLCamera::setView(F32 field_of_view)
{
mView = field_of_view;
@@ -150,7 +164,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
// ---------------- test methods ----------------
-int LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
+S32 LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
{
static const LLVector3 scaler[] = {
LLVector3(-1,-1,-1),
@@ -166,10 +180,56 @@ int LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
U8 mask = 0;
S32 result = 2;
- for (int i = 0; i < 6; i++)
+ 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;
+}
+
+S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 &center, const LLVector3& radius)
+{
+ static const LLVector3 scaler[] = {
+ LLVector3(-1,-1,-1),
+ LLVector3( 1,-1,-1),
+ LLVector3(-1, 1,-1),
+ LLVector3( 1, 1,-1),
+ LLVector3(-1,-1, 1),
+ LLVector3( 1,-1, 1),
+ LLVector3(-1, 1, 1),
+ LLVector3( 1, 1, 1)
+ };
+
+ U8 mask = 0;
+ S32 result = 2;
+
+ for (U32 i = 0; i < mPlaneCount; i++)
{
- mask = mAgentPlaneMask[i];
- LLPlane p = mAgentPlanes[i];
+ if (i == 5)
+ {
+ continue;
+ }
+
+ mask = mAgentPlanes[i].mask;
+ LLPlane p = mAgentPlanes[i].p;
LLVector3 n = LLVector3(p);
float d = p.mV[3];
LLVector3 rscale = radius.scaledVec(scaler[mask]);
@@ -312,7 +372,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius)
int res = 2;
for (int i = 0; i < 6; i++)
{
- float d = mAgentPlanes[i].dist(sphere_center);
+ float d = mAgentPlanes[i].p.dist(sphere_center);
if (d > radius)
{
@@ -477,6 +537,25 @@ 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::calcAgentFrustumPlanes(LLVector3* frust)
{
@@ -486,48 +565,34 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
mAgentFrustum[i] = frust[i];
}
+ mFrustumCornerDist = (frust[5] - getOrigin()).magVec();
+
//frust contains the 8 points of the frustum, calculate 6 planes
//order of planes is important, keep most likely to fail in the front of the list
//near - frust[0], frust[1], frust[2]
- mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]);
+ mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]);
//far
- mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]);
+ mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]);
//left
- mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]);
+ mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]);
//right
- mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]);
+ mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]);
//top
- mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]);
+ mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]);
//bottom
- mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]);
+ mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]);
//cache plane octant facing mask for use in AABBInFrustum
- for (int i = 0; i < 6; i++)
+ for (U32 i = 0; i < mPlaneCount; i++)
{
- U8 mask = 0;
- LLPlane p = mAgentPlanes[i];
- LLVector3 n = LLVector3(p);
-
- if (n.mV[0] >= 0)
- {
- mask |= 1;
- }
- if (n.mV[1] >= 0)
- {
- mask |= 2;
- }
- if (n.mV[2] >= 0)
- {
- mask |= 4;
- }
- mAgentPlaneMask[i] = mask;
+ mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p);
}
}