diff options
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/newview/app_settings/settings.xml | 12 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.cpp | 19 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.h | 7 | ||||
-rwxr-xr-x | indra/newview/llviewerregion.cpp | 17 | ||||
-rwxr-xr-x | indra/newview/llvocache.cpp | 68 | ||||
-rwxr-xr-x | indra/newview/llvocache.h | 6 |
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; |