diff options
-rwxr-xr-x | indra/newview/app_settings/settings.xml | 66 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.h | 2 | ||||
-rwxr-xr-x | indra/newview/llviewerregion.cpp | 26 | ||||
-rwxr-xr-x | indra/newview/llvocache.cpp | 84 | ||||
-rwxr-xr-x | indra/newview/llvocache.h | 13 |
6 files changed, 134 insertions, 68 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 14384edc1f..adcea5103e 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -742,17 +742,6 @@ <key>Value</key> <integer>40</integer> </map> - <key>BackSphereCullingRadius</key> - <map> - <key>Comment</key> - <string>Radius of back sphere in meters, objects behind camera but within this radius are loaded for rendering</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>100.0</real> - </map> <key>BottomPanelNew</key> <map> <key>Comment</key> @@ -7112,17 +7101,6 @@ <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>100.0</real> - </map> <key>ParcelMediaAutoPlayEnable</key> <map> <key>Comment</key> @@ -10231,6 +10209,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>SceneLoadFrontPixelThreshold</key> + <map> + <key>Comment</key> + <string>in pixels, all objects in view frustum whose screen area is greater than this threshold will be loaded</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>100.0</real> + </map> <key>SceneLoadingMonitorEnabled</key> <map> <key>Comment</key> @@ -10264,6 +10253,39 @@ <key>Value</key> <real>0.02</real> </map> + <key>SceneLoadMinRadius</key> + <map> + <key>Comment</key> + <string>in meters, all objects (visible or invisible) within this radius will remain loaded in memory</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>16.0</real> + </map> + <key>SceneLoadRearMaxRadiusFraction</key> + <map> + <key>Comment</key> + <string>a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>20.0</real> + </map> + <key>SceneLoadRearPixelThreshold</key> + <map> + <key>Comment</key> + <string>in pixels, all objects out of view frustum whose screen area is greater than this threshold will remain loaded</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>200.0</real> + </map> <key>ScriptHelpFollowsCursor</key> <map> <key>Comment</key> diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 1b3d7da90d..06ff68c6c3 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -1429,7 +1429,7 @@ S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLViewerOct } //------------------------------------------ //check if the objects projection large enough -bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 projection_cutoff) +bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_squared_radius) { LLVector3 local_orig = mCamera->getOrigin() - shift; LLVector4a origin; @@ -1438,14 +1438,13 @@ bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLV 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) + if(squared_dist < near_squared_radius) { - return squared_rad / squared_dist > projection_cutoff; + return true; //always load closeby objects } - return true; + F32 squared_rad = size.dot3(size).getF32(); + return squared_rad / squared_dist > pixel_threshold; } //virtual diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index b03047cbbe..20eb18278f 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -393,7 +393,7 @@ protected: 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); + bool checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_squared_radius); 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 8093ce523f..afc00764b8 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1064,7 +1064,7 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time) return; } - const F32 LARGE_SCENE_CONTRIBUTION = 100.f; //a large number to force to load the object. + const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); @@ -1126,7 +1126,11 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time) } } + // //process visible groups + // + //object projected area threshold + F32 projection_threshold = LLVOCacheEntry::getSquaredPixelThreshold(mImpl->mVOCachePartition->isFrontCull()); std::set< LLPointer<LLViewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin(); for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) { @@ -1149,8 +1153,11 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time) continue; } - vo_entry->calcSceneContribution(local_origin, needs_update, last_update); - mImpl->mWaitingList.insert(vo_entry); + vo_entry->calcSceneContribution(local_origin, needs_update, last_update); + if(vo_entry->getSceneContribution() > projection_threshold) + { + mImpl->mWaitingList.insert(vo_entry); + } } } } @@ -1175,9 +1182,6 @@ void LLViewerRegion::createVisibleObjects(F32 max_time) mImpl->mVOCachePartition->setCullHistory(FALSE); return; } - - //object projected area threshold - F32 projection_threshold = LLVOCacheEntry::getSquaredObjectScreenAreaThreshold(); S32 throttle = sNewObjectCreationThrottle; BOOL has_new_obj = FALSE; @@ -1187,11 +1191,6 @@ void LLViewerRegion::createVisibleObjects(F32 max_time) { LLVOCacheEntry* vo_entry = *iter; - if(vo_entry->getSceneContribution() < projection_threshold) - { - break; - } - if(vo_entry->getState() < LLVOCacheEntry::WAITING) { addNewObject(vo_entry); @@ -1379,8 +1378,6 @@ BOOL LLViewerRegion::isViewerCameraStatic() void LLViewerRegion::killInvisibleObjects(F32 max_time) { - static LLCachedControl<F32> back_sphere_radius(gSavedSettings,"BackSphereCullingRadius"); - if(!sVOCacheCullingEnabled) { return; @@ -1393,7 +1390,8 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time) LLTimer update_timer; LLVector4a camera_origin; camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); - F32 squared_back_threshold = back_sphere_radius * back_sphere_radius; + F32 squared_back_threshold = LLVOCacheEntry::sRearFarRadius; + squared_back_threshold *= squared_back_threshold; bool unstable = sNewObjectCreationThrottle < 0; size_t max_update = unstable ? mImpl->mActiveSet.size() : 64; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index f2c048cd34..3bacf5c319 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -35,7 +35,12 @@ #include "pipeline.h" #include "llagentcamera.h" +//static variables U32 LLVOCacheEntry::sMinFrameRange = 0; +F32 LLVOCacheEntry::sNearRadiusSquared = 1.0f; +F32 LLVOCacheEntry::sRearFarRadius = 1.0f; +F32 LLVOCacheEntry::sFrontPixelThreshold = 1.0f; +F32 LLVOCacheEntry::sRearPixelThreshold = 1.0f; BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE; BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) @@ -341,18 +346,46 @@ void LLVOCacheEntry::updateDebugSettings() { //the number of frames invisible objects stay in memory static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); - sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum + + //min radius: all objects within this radius remain loaded in memory + static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius"); + sNearRadiusSquared = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance + sNearRadiusSquared *= sNearRadiusSquared; + sNearRadiusSquared = llmax(sNearRadiusSquared, 1.f); //minimum value is 1.0m + + //objects within the view frustum whose visible area is greater than this threshold will be loaded + static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); + sFrontPixelThreshold = front_pixel_threshold; + + //objects out of the view frustum whose visible area is greater than this threshold will remain loaded + static LLCachedControl<F32> rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold"); + sRearPixelThreshold = rear_pixel_threshold; + sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. + + // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold + static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); + sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m + sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius". + sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance. } //static -F32 LLVOCacheEntry::getSquaredObjectScreenAreaThreshold() +F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front) { - static LLCachedControl<F32> projection_area_cutoff(gSavedSettings,"ObjectProjectionAreaCutOff"); + F32 threshold; + if(is_front) + { + threshold = sFrontPixelThreshold; + } + else + { + threshold = sRearPixelThreshold; + } //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; + F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f; projection_threshold *= projection_threshold; return projection_threshold; @@ -402,7 +435,13 @@ void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool lookAt.setSub(getPositionGroup(), camera_origin); F32 squared_dist = lookAt.dot3(lookAt).getF32(); - if(squared_dist > 0.f) + if(squared_dist < sNearRadiusSquared) + { + //nearby objects, set a large number + const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. + mSceneContrib = LARGE_SCENE_CONTRIBUTION; + } + else { F32 rad = getBinRadius(); mSceneContrib = rad * rad / squared_dist; @@ -554,14 +593,15 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull { public: LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, - const LLVector3& shift, bool use_object_cache_occlusion, F32 projection_area_cutoff, LLVOCachePartition* part) + const LLVector3& shift, bool use_object_cache_occlusion, F32 pixel_threshold, LLVOCachePartition* part) : LLViewerOctreeCull(camera), mRegionp(regionp), mPartition(part), - mProjectionAreaCutOff(projection_area_cutoff) + mPixelThreshold(pixel_threshold) { mLocalShift = shift; mUseObjectCacheOcclusion = use_object_cache_occlusion; + mSquaredNearRadius = LLVOCacheEntry::sNearRadiusSquared; } virtual bool earlyFail(LLViewerOctreeGroup* base_group) @@ -617,7 +657,7 @@ public: { //check if the objects projection large enough const LLVector4a* exts = group->getObjectExtents(); - res = checkProjectionArea(exts[0], exts[1], mLocalShift, mProjectionAreaCutOff); + res = checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSquaredNearRadius); } return res; @@ -663,7 +703,8 @@ private: LLVOCachePartition* mPartition; LLViewerRegion* mRegionp; LLVector3 mLocalShift; //shift vector from agent space to local region space. - F32 mProjectionAreaCutOff; + F32 mPixelThreshold; + F32 mSquaredNearRadius; bool mUseObjectCacheOcclusion; }; @@ -671,11 +712,11 @@ private: class LLVOCacheOctreeBackCull : public LLViewerOctreeCull { public: - LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 back_sphere_radius, F32 projection_area_cutoff) - : LLViewerOctreeCull(camera), mRegionp(regionp), mProjectionAreaCutOff(projection_area_cutoff) + LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold) + : LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold) { mLocalShift = shift; - mSphereRadius = back_sphere_radius; + mSphereRadius = LLVOCacheEntry::sRearFarRadius; } virtual S32 frustumCheck(const LLViewerOctreeGroup* group) @@ -691,7 +732,7 @@ public: { //check if the objects projection large enough const LLVector4a* exts = group->getObjectExtents(); - return checkProjectionArea(exts[0], exts[1], mLocalShift, mProjectionAreaCutOff); + return checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSphereRadius * mSphereRadius); } return false; } @@ -713,10 +754,10 @@ private: F32 mSphereRadius; LLViewerRegion* mRegionp; LLVector3 mLocalShift; //shift vector from agent space to local region space. - F32 mProjectionAreaCutOff; + F32 mPixelThreshold; }; -void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 back_sphere_radius, F32 projection_area_cutoff) +void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold) { if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { @@ -737,7 +778,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, projection_area_cutoff); + LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold); culler.traverse(mOctree); mBackSlectionEnabled--; @@ -752,7 +793,6 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 back_sphere_rad S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) { static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); - static LLCachedControl<F32> back_sphere_radius(gSavedSettings,"BackSphereCullingRadius"); if(!LLViewerRegion::sVOCacheCullingEnabled) { @@ -776,9 +816,6 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) } mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); - //object projected area threshold - F32 projection_threshold = LLVOCacheEntry::getSquaredObjectScreenAreaThreshold(); - if(!mCullHistory && LLViewerRegion::isViewerCameraStatic()) { U32 seed = llmax(mLODPeriod >> 1, (U32)4); @@ -791,7 +828,8 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) } if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash) { - selectBackObjects(camera, back_sphere_radius, projection_threshold);//process back objects selection + mFrontCull = FALSE; + selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull));//process back objects selection return 0; //nothing changed, reduce frequency of culling } } @@ -804,7 +842,9 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) LLVector3 region_agent = mRegionp->getOriginAgent(); camera.calcRegionFrustumPlanes(region_agent); - LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, projection_threshold, this); + mFrontCull = TRUE; + LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, + LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), this); culler.traverse(mOctree); if(!sNeedsOcclusionCheck) diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index af97f9fdce..9d851288b4 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -125,7 +125,7 @@ public: U32 getUpdateFlags() const {return mUpdateFlags;} static void updateDebugSettings(); - static F32 getSquaredObjectScreenAreaThreshold(); + static F32 getSquaredPixelThreshold(bool is_front); private: void updateParentBoundingInfo(const LLVOCacheEntry* child); @@ -154,7 +154,11 @@ protected: BOOL mTouched; //if set, this entry is valid, otherwise it is invalid. public: - static U32 sMinFrameRange; + static U32 sMinFrameRange; + static F32 sNearRadiusSquared; + static F32 sRearFarRadius; + static F32 sFrontPixelThreshold; + static F32 sRearPixelThreshold; }; class LLVOCacheGroup : public LLOcclusionCullingGroup @@ -184,13 +188,16 @@ public: void setCullHistory(BOOL has_new_object); + bool isFrontCull() const {return mFrontCull;} + private: - void selectBackObjects(LLCamera &camera, F32 back_sphere_radius, F32 projection_area_cutoff); //select objects behind camera. + void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff); //select objects behind camera. public: static BOOL sNeedsOcclusionCheck; private: + BOOL mFrontCull; //the view frustum cull if set, otherwise is back sphere cull. U32 mCullHistory; U32 mCulledTime[LLViewerCamera::NUM_CAMERAS]; std::set<LLVOCacheGroup*> mOccludedGroups; |