diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index abead17d6ff60f3edc559a46d643f6e751eef0b3..985f5a0a1f9ffbc500a2f6749d176c5948f57504 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -963,14 +963,16 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d entry->setState(LLVOCacheEntry::INACTIVE); } -void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) +bool LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) { if(mDead || group->isEmpty()) { - return; + return false; } - group->setVisible(); + mImpl->mVisibleGroups.insert(group); + + return true; } U32 LLViewerRegion::getNumOfVisibleGroups() const diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index e07c2aa8d0d74a79367d51aca00665141de6a897..b2df8d5325957252155bb7e4988484ca446de38e 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -229,7 +229,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface F32 getWidth() const { return mWidth; } BOOL idleUpdate(F32 max_update_time); - void addVisibleGroup(LLviewerOctreeGroup* group); + bool addVisibleGroup(LLviewerOctreeGroup* group); void addVisibleCacheEntry(LLVOCacheEntry* entry); void addActiveCacheEntry(LLVOCacheEntry* entry); void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 6d2a17882adc429de5fc600cc000f39229785f48..dfc9ee57d8107676b1d45031b1b2721934a4d711 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -490,7 +490,9 @@ LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) { mLODPeriod = 16; mRegionp = regionp; - mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mBackSlectionEnabled = -1; + mIdleHash = 0; for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { @@ -517,7 +519,8 @@ void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) class LLVOCacheOctreeCull : public LLViewerOctreeCull { public: - LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion, LLVOCachePartition* part) + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, + const LLVector3& shift, bool use_object_cache_occlusion, LLVOCachePartition* part) : LLViewerOctreeCull(camera), mRegionp(regionp), mPartition(part) @@ -583,7 +586,10 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull !base_group->getOctreeNode()->getParent()) { //no occlusion check - mRegionp->addVisibleGroup(base_group); + if(mRegionp->addVisibleGroup(base_group)) + { + base_group->setVisible(); + } return; } @@ -603,7 +609,10 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull } else { - mRegionp->addVisibleGroup(base_group); + if(mRegionp->addVisibleGroup(base_group)) + { + base_group->setVisible(); + } } } @@ -614,6 +623,81 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull bool mUseObjectCacheOcclusion; }; +//select objects behind camera +class LLVOCacheOctreeBackCull : public LLViewerOctreeCull +{ +public: + LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp) + : LLViewerOctreeCull(camera), mRegionp(regionp) + { + mLocalShift = shift; + mSphereRadius = 20.f; //20m + } + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) + { + const LLVector4a* exts = group->getExtents(); + return backSphereCheck(exts[0], exts[1]); + } + + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) + { + const LLVector4a* exts = group->getObjectExtents(); + return backSphereCheck(exts[0], exts[1]); + } + + virtual void processGroup(LLviewerOctreeGroup* base_group) + { + mRegionp->addVisibleGroup(base_group); + return; + } + +private: + //a sphere around the camera origin, including objects behind camera. + S32 backSphereCheck(const LLVector4a& min, const LLVector4a& max) + { + return AABBSphereIntersect(min, max, mCamera->getOrigin() - mLocalShift, mSphereRadius); + } + +private: + F32 mSphereRadius; + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. +}; + +void LLVOCachePartition::selectBackObjects(LLCamera &camera) +{ + if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + return; + } + + if(mBackSlectionEnabled < 0) + { + mBackSlectionEnabled = LLVOCacheEntry::getInvisibleObjectsLiveTime() - 1; + mBackSlectionEnabled = llmax(mBackSlectionEnabled, (S32)1); + } + + if(!mBackSlectionEnabled) + { + return; + } + + //localize the camera + LLVector3 region_agent = mRegionp->getOriginAgent(); + + LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp); + culler.traverse(mOctree); + + mBackSlectionEnabled--; + if(!mRegionp->getNumOfVisibleGroups()) + { + mBackSlectionEnabled = 0; + } + + return; +} + S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) { static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); @@ -638,22 +722,25 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) if(!mCullHistory[LLViewerCamera::sCurCameraID] && LLViewerRegion::isViewerCameraStatic()) { - static U32 hash = 0; - U32 seed = llmax(mLODPeriod >> 1, (U32)4); if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { if(!(LLViewerOctreeEntryData::getCurrentFrame() % seed)) { - hash = (hash + 1) % seed; + mIdleHash = (mIdleHash + 1) % seed; } } - if(LLViewerOctreeEntryData::getCurrentFrame() % seed != hash) + if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash) { + selectBackObjects(camera);//process back objects selection return 0; //nothing changed, reduce frequency of culling } } - + else + { + mBackSlectionEnabled = -1; //reset it. + } + if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { mCullHistory[LLViewerCamera::sCurCameraID] <<= 1; diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 7c7b64ad5ba2e402541d37fe181e70c1fa9c06c1..867f9ab93c42e5fa1e729ba7aecf55c193f2f6ed 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -126,10 +126,9 @@ class LLVOCacheEntry U32 getUpdateFlags() const {return mUpdateFlags;} static void updateBackCullingFactors(); - -private: static U32 getInvisibleObjectsLiveTime(); +private: void updateParentBoundingInfo(const LLVOCacheEntry* child); public: @@ -172,6 +171,9 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr void resetOccluders(); void processOccluders(LLCamera* camera); +private: + void selectBackObjects(LLCamera &camera); //select objects behind camera. + public: static BOOL sNeedsOcclusionCheck; //static LLTrace::MemStatHandle sMemStat; @@ -180,6 +182,9 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr U32 mCullHistory[LLViewerCamera::NUM_CAMERAS]; U32 mCulledTime[LLViewerCamera::NUM_CAMERAS]; std::set<LLOcclusionCullingGroup*> mOccludedGroups; + + S32 mBackSlectionEnabled; //enable to select back objects if > 0. + U32 mIdleHash; }; //