summaryrefslogtreecommitdiff
path: root/indra/newview/llface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llface.cpp')
-rw-r--r--indra/newview/llface.cpp52
1 files changed, 47 insertions, 5 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index ec7ea398f0..0a2e20fecd 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1571,7 +1571,7 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
skin = mSkinInfo;
}
- //TODO -- cache this (check profile marker above)?
+ //TODO - cache this (check profile marker above)?
glm::mat4 m = glm::make_mat4((F32*)skin->mBindShapeMatrix.getF32ptr());
m = glm::transpose(glm::inverse(m));
mat_normal.loadu(glm::value_ptr(m));
@@ -2259,7 +2259,18 @@ F32 LLFace::getTextureVirtualSize()
face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
}
- face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
+ // Diffuse source area as the dim-aware hint for adjustPixelArea.
+ S32 source_area = 0;
+ if (mTexture[LLRender::DIFFUSE_MAP].notNull())
+ {
+ S32 sw = mTexture[LLRender::DIFFUSE_MAP]->getFullWidth();
+ S32 sh = mTexture[LLRender::DIFFUSE_MAP]->getFullHeight();
+ if (sw > 0 && sh > 0)
+ {
+ source_area = sw * sh;
+ }
+ }
+ face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area, source_area);
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
@@ -2280,6 +2291,8 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
// don't update every frame
if (gFrameTimeSeconds - mLastPixelAreaUpdate < PIXEL_AREA_UPDATE_PERIOD)
{
+ cos_angle_to_view_dir = mLastCosAngleToViewDir;
+ radius = mLastRadius;
return true;
}
@@ -2351,6 +2364,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
// no rigged extents, zero out bounding box and skip update
mRiggedExtents[0] = mRiggedExtents[1] = LLVector4a(0.f, 0.f, 0.f);
+ mInFrustum = false;
return false;
}
@@ -2383,6 +2397,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
F32 dist = lookAt.getLength3().getF32();
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
+ mDistanceToCamera = dist;
lookAt.normalize3fast() ;
@@ -2404,6 +2419,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
if(!camera->AABBInFrustum(center, size))
{
mImportanceToCamera = 0.f ;
+ mInFrustum = false;
return false ;
}
if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum
@@ -2432,6 +2448,24 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
}
+ // On-screen test: does the face's projected disc overlap the screen disc?
+ // (Same construction as adjustPartialOverlapPixelArea.) Behind-camera faces
+ // get acos(cos) near pi and fall out; the generous screen radius errs toward
+ // "on screen" so fetch admission never starves edge content. mFrustumOverflow
+ // is how far past the boundary the disc sits, as a fraction of screen size -
+ // 0 on screen, 0.1 = 10% of a screen out - and feeds the frustum allowance
+ // falloff in computeDesiredDiscard.
+ {
+ F32 center_px = acosf(llclamp(cos_angle_to_view_dir, -1.f, 1.f)) * LLDrawable::sCurPixelAngle;
+ F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+ F32 past_edge = center_px - radius - screen_radius;
+ mInFrustum = past_edge <= 5.f;
+ mFrustumOverflow = llmax(past_edge - 5.f, 0.f) / screen_radius;
+ }
+
+ mLastCosAngleToViewDir = cos_angle_to_view_dir;
+ mLastRadius = radius;
+
return true ;
}
@@ -2507,8 +2541,16 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
}
//static
-F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area)
+F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area, S32 source_area)
{
+ // Dim-aware floor: source_area/256 lowers the "large but unimportant"
+ // clamp proportionally so smaller sources can be pushed past discard 4.
+ F32 large_floor = (F32)LLViewerTexture::sMinLargeImageSize;
+ if (source_area > 0)
+ {
+ large_floor = llmin(large_floor, (F32)source_area / 256.f);
+ }
+
if(pixel_area > LLViewerTexture::sMaxSmallImageSize)
{
if(importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
@@ -2516,11 +2558,11 @@ F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area)
static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ;
pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ;
}
- else if(pixel_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
+ else if(pixel_area > large_floor) //if is large image, shrink face_area by considering the partial overlapping.
{
if(importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
{
- pixel_area = (F32)LLViewerTexture::sMinLargeImageSize ;
+ pixel_area = large_floor ;
}
}
}