summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/app_settings/settings.xml12
-rw-r--r--indra/newview/llvieweroctree.cpp19
-rw-r--r--indra/newview/llvieweroctree.h7
-rwxr-xr-xindra/newview/llviewerregion.cpp17
-rwxr-xr-xindra/newview/llvocache.cpp68
-rwxr-xr-xindra/newview/llvocache.h6
6 files changed, 100 insertions, 29 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7bfca2834b..fb0d9c98d4 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7114,7 +7114,17 @@
<real>0.75</real>
</array>
</map>
-
+ <key>ObjectProjectionAreaCutOFF</key>
+ <map>
+ <key>Comment</key>
+ <string>Threshold in number of pixels of the projection area in screen of object bounding sphere. Objects smaller than this threshold are not rendered.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
<key>ParcelMediaAutoPlayEnable</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index e390249504..425e7fbd1f 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1430,6 +1430,25 @@ S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLViewerOct
return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist);
}
//------------------------------------------
+//check if the objects projection large enough
+bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 projection_cutoff)
+{
+ LLVector3 local_orig = mCamera->getOrigin() - shift;
+ LLVector4a origin;
+ origin.load3(local_orig.mV);
+
+ LLVector4a lookAt;
+ lookAt.setSub(center, origin);
+ F32 squared_dist = lookAt.dot3(lookAt).getF32();
+ F32 squared_rad = size.dot3(size).getF32();
+
+ if(squared_dist > 0.f)
+ {
+ return squared_rad / squared_dist > projection_cutoff;
+ }
+
+ return true;
+}
//virtual
bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLViewerOctreeGroup* group)
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index e673bb6349..6ea6130413 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -362,9 +362,11 @@ class LLViewerOctreeCull : public OctreeTraveler
public:
LLViewerOctreeCull(LLCamera* camera)
: mCamera(camera), mRes(0) { }
-
- virtual bool earlyFail(LLViewerOctreeGroup* group);
+
virtual void traverse(const OctreeNode* n);
+
+protected:
+ virtual bool earlyFail(LLViewerOctreeGroup* group);
//agent space group cull
S32 AABBInFrustumNoFarClipGroupBounds(const LLViewerOctreeGroup* group);
@@ -389,6 +391,7 @@ public:
virtual S32 frustumCheck(const LLViewerOctreeGroup* group) = 0;
virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) = 0;
+ bool checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 projection_cutoff);
virtual bool checkObjects(const OctreeNode* branch, const LLViewerOctreeGroup* group);
virtual void preprocess(LLViewerOctreeGroup* group);
virtual void processGroup(LLViewerOctreeGroup* group);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 0ad4402dcc..e73b4fb62c 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1157,25 +1157,40 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time)
F32 LLViewerRegion::createVisibleObjects(F32 max_time)
{
+ static LLCachedControl<F32> projection_area_cutoff(gSavedSettings,"ObjectProjectionAreaCutOFF");
+
if(mDead)
{
return max_time;
}
if(mImpl->mWaitingList.empty())
{
+ mImpl->mVOCachePartition->setCullHistory(FALSE);
return max_time;
}
+ //object projected area threshold
+ F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
+ F32 projection_threshold = pixel_meter_ratio > 0.f ? projection_area_cutoff / pixel_meter_ratio : 0.f;
+ projection_threshold *= projection_threshold;
+
S32 throttle = sNewObjectCreationThrottle;
+ BOOL has_new_obj = FALSE;
LLTimer update_timer;
for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
iter != mImpl->mWaitingList.end(); ++iter)
{
LLVOCacheEntry* vo_entry = *iter;
+ if(vo_entry->getSceneContribution() < projection_threshold)
+ {
+ break;
+ }
+
if(vo_entry->getState() < LLVOCacheEntry::WAITING)
{
addNewObject(vo_entry);
+ has_new_obj = TRUE;
if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time)
{
break;
@@ -1183,6 +1198,8 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time)
}
}
+ mImpl->mVOCachePartition->setCullHistory(has_new_obj);
+
return max_time - update_timer.getElapsedTimeF32();
}
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 89a49ff1ed..3f2a39ba2b 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -524,9 +524,10 @@ LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
- mCulledTime[i] = 0;
- mCullHistory[i] = -1;
+ mCulledTime[i] = 0;
}
+ mCullHistory = -1;
+
new LLVOCacheGroup(mOctree, this);
}
@@ -548,10 +549,11 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull
{
public:
LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp,
- const LLVector3& shift, bool use_object_cache_occlusion, LLVOCachePartition* part)
+ const LLVector3& shift, bool use_object_cache_occlusion, F32 projection_area_cutoff, LLVOCachePartition* part)
: LLViewerOctreeCull(camera),
mRegionp(regionp),
- mPartition(part)
+ mPartition(part),
+ mProjectionAreaCutOff(projection_area_cutoff)
{
mLocalShift = shift;
mUseObjectCacheOcclusion = use_object_cache_occlusion;
@@ -605,6 +607,14 @@ public:
{
res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift));
}
+
+ if(res != 0)
+ {
+ //check if the objects projection large enough
+ const LLVector4a* exts = group->getObjectExtents();
+ res = checkProjectionArea(exts[0], exts[1], mLocalShift, mProjectionAreaCutOff);
+ }
+
return res;
}
@@ -648,6 +658,7 @@ private:
LLVOCachePartition* mPartition;
LLViewerRegion* mRegionp;
LLVector3 mLocalShift; //shift vector from agent space to local region space.
+ F32 mProjectionAreaCutOff;
bool mUseObjectCacheOcclusion;
};
@@ -655,8 +666,8 @@ private:
class LLVOCacheOctreeBackCull : public LLViewerOctreeCull
{
public:
- LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 back_sphere_radius)
- : LLViewerOctreeCull(camera), mRegionp(regionp)
+ LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 back_sphere_radius, F32 projection_area_cutoff)
+ : LLViewerOctreeCull(camera), mRegionp(regionp), mProjectionAreaCutOff(projection_area_cutoff)
{
mLocalShift = shift;
mSphereRadius = back_sphere_radius;
@@ -671,7 +682,13 @@ public:
virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
{
const LLVector4a* exts = group->getObjectExtents();
- return backSphereCheck(exts[0], exts[1]);
+ if(backSphereCheck(exts[0], exts[1]))
+ {
+ //check if the objects projection large enough
+ const LLVector4a* exts = group->getObjectExtents();
+ return checkProjectionArea(exts[0], exts[1], mLocalShift, mProjectionAreaCutOff);
+ }
+ return false;
}
virtual void processGroup(LLViewerOctreeGroup* base_group)
@@ -691,9 +708,10 @@ private:
F32 mSphereRadius;
LLViewerRegion* mRegionp;
LLVector3 mLocalShift; //shift vector from agent space to local region space.
+ F32 mProjectionAreaCutOff;
};
-void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 back_sphere_radius)
+void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 back_sphere_radius, F32 projection_area_cutoff)
{
if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
{
@@ -714,7 +732,7 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 back_sphere_rad
//localize the camera
LLVector3 region_agent = mRegionp->getOriginAgent();
- LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, back_sphere_radius);
+ LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, back_sphere_radius, projection_area_cutoff);
culler.traverse(mOctree);
mBackSlectionEnabled--;
@@ -730,6 +748,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
static LLCachedControl<F32> back_sphere_radius(gSavedSettings,"BackShpereCullingRadius");
+ static LLCachedControl<F32> projection_area_cutoff(gSavedSettings,"ObjectProjectionAreaCutOFF");
if(!LLViewerRegion::sVOCacheCullingEnabled)
{
@@ -742,7 +761,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
((LLViewerOctreeGroup*)mOctree->getListener(0))->rebound();
- if(LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_WATER0)
+ if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
{
return 0; //no need for those cameras.
}
@@ -753,7 +772,12 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
}
mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
- if(!mCullHistory[LLViewerCamera::sCurCameraID] && LLViewerRegion::isViewerCameraStatic())
+ //object projected area threshold
+ F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
+ F32 projection_threshold = pixel_meter_ratio > 0.f ? projection_area_cutoff / pixel_meter_ratio : 0.f;
+ projection_threshold *= projection_threshold;
+
+ if(!mCullHistory && LLViewerRegion::isViewerCameraStatic())
{
U32 seed = llmax(mLODPeriod >> 1, (U32)4);
if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -765,7 +789,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
}
if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash)
{
- selectBackObjects(camera, back_sphere_radius);//process back objects selection
+ selectBackObjects(camera, back_sphere_radius, projection_threshold);//process back objects selection
return 0; //nothing changed, reduce frequency of culling
}
}
@@ -774,22 +798,12 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
mBackSlectionEnabled = -1; //reset it.
}
- if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
- {
- mCullHistory[LLViewerCamera::sCurCameraID] <<= 1;
- }
-
//localize the camera
LLVector3 region_agent = mRegionp->getOriginAgent();
camera.calcRegionFrustumPlanes(region_agent);
- LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, this);
- culler.traverse(mOctree);
-
- if(mRegionp->getNumOfVisibleGroups() > 0)
- {
- mCullHistory[LLViewerCamera::sCurCameraID] |= 1;
- }
+ LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, projection_threshold, this);
+ culler.traverse(mOctree);
if(!sNeedsOcclusionCheck)
{
@@ -798,6 +812,12 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
return 1;
}
+void LLVOCachePartition::setCullHistory(BOOL has_new_object)
+{
+ mCullHistory <<= 1;
+ mCullHistory |= has_new_object;
+}
+
void LLVOCachePartition::addOccluders(LLViewerOctreeGroup* gp)
{
LLVOCacheGroup* group = (LLVOCacheGroup*)gp;
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 21b30f5373..3ee9dcaac8 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -185,14 +185,16 @@ public:
void processOccluders(LLCamera* camera);
void removeOccluder(LLVOCacheGroup* group);
+ void setCullHistory(BOOL has_new_object);
+
private:
- void selectBackObjects(LLCamera &camera, F32 back_sphere_radius); //select objects behind camera.
+ void selectBackObjects(LLCamera &camera, F32 back_sphere_radius, F32 projection_area_cutoff); //select objects behind camera.
public:
static BOOL sNeedsOcclusionCheck;
private:
- U32 mCullHistory[LLViewerCamera::NUM_CAMERAS];
+ U32 mCullHistory;
U32 mCulledTime[LLViewerCamera::NUM_CAMERAS];
std::set<LLVOCacheGroup*> mOccludedGroups;