diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 86589b87e..eda350e93 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -44,13 +44,14 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") #endif +extern U32 gOctreeMaxCapacity; #if LL_DEBUG #define LL_OCTREE_PARANOIA_CHECK 0 #else #define LL_OCTREE_PARANOIA_CHECK 0 #endif -#define LL_OCTREE_MAX_CAPACITY 128 +//#define LL_OCTREE_MAX_CAPACITY 128 template class LLOctreeNode; @@ -314,16 +315,14 @@ public: //is it here? if (isInside(data->getPositionGroup())) { - if (getElementCount() < LL_OCTREE_MAX_CAPACITY && - (contains(data->getBinRadius()) || - (data->getBinRadius() > getSize().mdV[0] && - parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) + if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || + (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here #if LL_OCTREE_PARANOIA_CHECK //if this is a redundant insertion, error out (should never happen) if (mData.find(data) != mData.end()) { - llerrs << "Redundant octree insertion detected. " << data << llendl; + llwarns << "Redundant octree insertion detected. " << data << llendl; return false; } #endif @@ -341,7 +340,7 @@ public: child = getChild(i); if (child->isInside(data->getPositionGroup())) { - llassert(child->getElementCount() <= LL_OCTREE_MAX_CAPACITY); + llassert(child->getElementCount() <= gOctreeMaxCapacity); child->insert(data); return false; } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b67d4b085..43b63e135 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9032,6 +9032,74 @@ Value 1 + + OctreeMaxNodeCapacity + + Comment + Maximum number of elements to store in a single octree node + Persist + 1 + Type + U32 + Value + 128 + + + OctreeStaticObjectSizeFactor + + Comment + Multiplier on static object size for determining octree node size + Persist + 1 + Type + S32 + Value + 4 + + + OctreeAlphaDistanceFactor + + Comment + Multiplier on alpha object distance for determining octree node size + Persist + 1 + Type + Vector3 + Value + + 0.1 + 0.0 + 0.0 + + + + OctreeAttachmentSizeFactor + + Comment + Multiplier on attachment size for determining octree node size + Persist + 1 + Type + S32 + Value + 4 + + + OctreeDistanceFactor + + Comment + Multiplier on distance for determining octree node size + Persist + 1 + Type + Vector3 + Value + + 0.01 + 0.0 + 0.0 + + RenderAnisotropic Comment @@ -9118,7 +9186,7 @@ Type F32 Value - 1.0 + 1.0 RenderAvatarInvisible @@ -10482,7 +10550,7 @@ Type S32 Value - 8192 + 65536 RenderMaxVBOSize diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b4433501d..72ebc6db4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1265,7 +1265,9 @@ bool LLAppViewer::cleanup() // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. LLWorldMap::getInstance()->reset(); // release any images - + + LLCalc::cleanUp(); + llinfos << "Global stuff deleted" << llendflush; if (gAudiop) diff --git a/indra/newview/llcapabilityprovider.h b/indra/newview/llcapabilityprovider.h new file mode 100644 index 000000000..9d9124559 --- /dev/null +++ b/indra/newview/llcapabilityprovider.h @@ -0,0 +1,56 @@ +/** + * @file llcapabilityprovider.h + * @author Nat Goodspeed + * @date 2009-01-07 + * @brief Interface by which to reference (e.g.) LLViewerRegion to obtain a + * capability. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLCAPABILITYPROVIDER_H) +#define LL_LLCAPABILITYPROVIDER_H + +#include "llhost.h" +#include + +/// Interface for obtaining a capability URL, given a capability name +class LLCapabilityProvider +{ +public: + virtual ~LLCapabilityProvider() {} + /** + * Get a capability URL, given a capability name. Returns empty string if + * no such capability is defined on this provider. + */ + virtual std::string getCapability(const std::string& name) const = 0; + /** + * Get host to which to send that capability request. + */ + virtual const LLHost& getHost() const = 0; + /** + * Describe this LLCapabilityProvider for logging etc. + */ + virtual std::string getDescription() const = 0; +}; + +#endif /* ! defined(LL_LLCAPABILITYPROVIDER_H) */ diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 64464f132..89bc66dfc 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -95,7 +95,9 @@ void LLDrawable::init() mRenderType = 0; mCurrentScale = LLVector3(1,1,1); mDistanceWRTCamera = 0.0f; - + mPositionGroup.clearVec(); + mExtents[0].clear(); + mExtents[1].clear(); mQuietCount = 0; mState = 0; @@ -177,6 +179,11 @@ LLVOVolume* LLDrawable::getVOVolume() const } } +const LLMatrix4& LLDrawable::getRenderMatrix() const +{ + return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); +} + BOOL LLDrawable::isLight() const { LLViewerObject* objectp = mVObjp; @@ -571,7 +578,10 @@ void LLDrawable::setRadius(F32 radius) void LLDrawable::moveUpdatePipeline(BOOL moved) { - makeActive(); + if (moved) + { + makeActive(); + } // Update the face centers. for (S32 i = 0; i < getNumFaces(); i++) @@ -679,7 +689,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { - llerrs << "WTF?" << llendl; + llwarns << "Attempted to update distance for non-world camera." << llendl; + return; } //switch LOD with the spatial group to avoid artifacts @@ -748,7 +759,7 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (isActive()) + /*if (isActive()) { if (isRoot()) { @@ -758,7 +769,7 @@ void LLDrawable::updateTexture() { getParent()->mQuietCount = 0; } - } + }*/ gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 32049da0d..a515612e6 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -102,7 +102,7 @@ public: LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } - const LLMatrix4& getRenderMatrix() const { return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); } + const LLMatrix4& getRenderMatrix() const; void setPosition(LLVector3 v) const { } const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } @@ -250,35 +250,36 @@ public: typedef enum e_drawable_flags { - IN_REBUILD_Q1 = 0x00000002, - IN_REBUILD_Q2 = 0x00000004, - IN_LIGHT_Q = 0x00000008, - EARLY_MOVE = 0x00000010, - MOVE_UNDAMPED = 0x00000020, - ON_MOVE_LIST = 0x00000040, - USE_BACKLIGHT = 0x00000080, - UV = 0x00000100, - UNLIT = 0x00000200, - LIGHT = 0x00000400, - LIGHTING_BUILT = 0x00000800, - REBUILD_VOLUME = 0x00001000, //volume changed LOD or parameters, or vertex buffer changed - REBUILD_TCOORD = 0x00002000, //texture coordinates changed - REBUILD_COLOR = 0x00004000, //color changed - REBUILD_POSITION= 0x00010000, //vertex positions/normals changed + IN_REBUILD_Q1 = 0x00000001, + IN_REBUILD_Q2 = 0x00000002, + IN_LIGHT_Q = 0x00000004, + EARLY_MOVE = 0x00000008, + MOVE_UNDAMPED = 0x00000010, + ON_MOVE_LIST = 0x00000020, + USE_BACKLIGHT = 0x00000040, + UV = 0x00000080, + UNLIT = 0x00000100, + LIGHT = 0x00000200, + LIGHTING_BUILT = 0x00000400, + REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed + REBUILD_TCOORD = 0x00001000, //texture coordinates changed + REBUILD_COLOR = 0x00002000, //color changed + REBUILD_POSITION= 0x00004000, //vertex positions/normals changed REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, - ON_SHIFT_LIST = 0x00100000, - BLOCKER = 0x00400000, - ACTIVE = 0x00800000, - DEAD = 0x01000000, - INVISIBLE = 0x02000000, // stay invisible until flag is cleared - NEARBY_LIGHT = 0x04000000, // In gPipeline.mNearbyLightSet - BUILT = 0x08000000, - FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000, - HAS_ALPHA = 0x80000000, + ON_SHIFT_LIST = 0x00010000, + BLOCKER = 0x00020000, + ACTIVE = 0x00040000, + DEAD = 0x00080000, + INVISIBLE = 0x00100000, // stay invisible until flag is cleared + NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet + BUILT = 0x00400000, + FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) + CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame + REBUILD_SHADOW = 0x02000000, + HAS_ALPHA = 0x04000000, + PARTITION_MOVE = 0x10000000, } EDrawableFlags; LLXformMatrix mXform; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 1c789e1ca..32dcd4c30 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -63,6 +63,13 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; + +#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 + +std::set LLSpatialGroup::sPendingQueries; + +U32 gOctreeMaxCapacity; + BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; @@ -80,6 +87,9 @@ protected: virtual void releaseName(GLuint name) { +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + LLSpatialGroup::sPendingQueries.erase(name); +#endif glDeleteQueriesARB(1, &name); } }; @@ -191,7 +201,7 @@ static U8 sOcclusionIndices[] = b000, b110, b100, b101, b001, b011, b010, b110, }; -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center) +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector3& center) { LLVector3 d = center - camera->getOrigin(); @@ -473,7 +483,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) if (mOctreeNode->isInside(drawablep->getPositionGroup()) && (mOctreeNode->contains(drawablep) || (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] && - parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) + parent && parent->getElementCount() >= gOctreeMaxCapacity))) { unbound(); setState(OBJECT_DIRTY); @@ -1442,6 +1452,9 @@ void LLSpatialGroup::checkOcclusion() if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif } else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { //delete the query to avoid holding onto hundreds of pending queries @@ -1525,6 +1538,10 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) #else U32 mode = GL_SAMPLES_PASSED_ARB; #endif + +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif { //LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); @@ -1543,7 +1560,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) else { glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); } } else @@ -1559,7 +1576,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) else { glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); } } @@ -2512,7 +2529,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) gGL.color4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } - else if (camera && group->mOcclusionVerts) + /*else if (camera && group->mOcclusionVerts) { LLVertexBuffer::unbind(); glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); @@ -2524,7 +2541,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) glColor4f(1.0f, 1.f, 1.f, 1.0f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + }*/ } } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 093a13d78..debbeb780 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -58,7 +58,7 @@ S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVect S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center); +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector3& center); class LLDrawInfo : public LLRefCount { @@ -156,6 +156,7 @@ class LLSpatialGroup : public LLOctreeListener friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: + static std::set sPendingQueries; //pending occlusion queries static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index b3cf4d784..a58d38329 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -63,6 +63,7 @@ #include "pipeline.h" #include "llviewerjoystick.h" #include "llviewerparcelmedia.h" +#include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" #include "llparcel.h" #include "llnotify.h" @@ -78,7 +79,6 @@ #include "llfloaterchat.h" #include "statemachine/aistatemachine.h" #include "aithreadsafe.h" -#include "llviewerobjectlist.h" #include "lldrawpoolbump.h" #include "emeraldboobutils.h" @@ -422,6 +422,16 @@ static bool handleResetVertexBuffersChanged(const LLSD&) return true; } +static bool handleRepartition(const LLSD&) +{ + if (gPipeline.isInit()) + { + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gObjectList.repartitionObjects(); + } + return true; +} + static bool handleRenderDynamicLODChanged(const LLSD& newvalue) { LLPipeline::sDynamicLOD = newvalue.asBoolean(); @@ -595,6 +605,11 @@ void settings_setup_listeners() gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2)); gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2)); gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); + gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 8414945a8..8d5b1fef6 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -617,6 +617,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); + gPipeline.processPartitionQ(); gPipeline.updateGeom(max_geom_update_time); gPipeline.updateGL(); stop_glerror(); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 31e10ef22..9be2aacc3 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1117,6 +1117,24 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) LLWorld::getInstance()->shiftRegions(offset); } +void LLViewerObjectList::repartitionObjects() +{ + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (!objectp->isDead()) + { + LLDrawable* drawable = objectp->mDrawable; + if (drawable && !drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->updateSpatialExtents(); + drawable->movePartition(); + } + } + } +} + //debug code bool LLViewerObjectList::hasMapObjectInRegion(LLViewerRegion* regionp) { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index ff655f832..90d100044 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -94,7 +94,9 @@ public: void updateApparentAngles(LLAgent &agent); void update(LLAgent &agent, LLWorld &world); + void shiftObjects(const LLVector3 &offset); + void repartitionObjects(); bool hasMapObjectInRegion(LLViewerRegion* regionp) ; void clearAllMapObjectsInRegion(LLViewerRegion* regionp) ; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 00d37f823..bad1cfe1d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -519,7 +519,7 @@ void LLVOVolume::updateTextureVirtualSize() if (isHUDAttachment()) { - F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); + F32 area = (F32) camera->getScreenPixelArea(); vsize = area; imagep->setBoostLevel(LLViewerTexture::BOOST_HUD); face->setPixelArea(area); // treat as full screen @@ -654,7 +654,8 @@ void LLVOVolume::updateTextureVirtualSize() BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); + return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || + (mDrawable.notNull() && mDrawable->isActive()); } BOOL LLVOVolume::setMaterial(const U8 material) @@ -918,7 +919,7 @@ BOOL LLVOVolume::calcLOD() } // DON'T Compensate for field of view changing on FOV zoom. - distance *= 3.14159f/3.f; + distance *= F_PI/3.f; cur_detail = computeLODDetail(llround(distance, 0.01f), llround(radius, 0.01f)); @@ -949,6 +950,15 @@ BOOL LLVOVolume::updateLOD() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); mLODChanged = TRUE; } + else + { + F32 new_radius = getBinRadius(); + F32 old_radius = mDrawable->getBinRadius(); + if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) + { + gPipeline.markPartitionMove(mDrawable); + } + } lod_changed |= LLViewerObject::updateLOD(); @@ -2070,6 +2080,16 @@ F32 LLVOVolume::getBinRadius() { F32 radius; + F32 scale = 1.f; + + static const LLCachedControl size_factor_setting("OctreeStaticObjectSizeFactor", 4); + static const LLCachedControl attachment_size_factor_setting("OctreeAttachmentSizeFactor", 4); + static const LLCachedControl distance_factor_setting("OctreeDistanceFactor",LLVector3::zero); + static const LLCachedControl alpha_distance_factor_setting("OctreeAlphaDistanceFactor",LLVector3(.1f,0.f,0.f)); + const S32 size_factor = llmax(size_factor_setting.get(),1); + const S32 attachment_size_factor = llmax(size_factor_setting.get(),1); + const LLVector3& distance_factor = distance_factor_setting; + const LLVector3& alpha_distance_factor = alpha_distance_factor_setting; const LLVector3* ext = mDrawable->getSpatialExtents(); BOOL shrink_wrap = mDrawable->isAnimating(); @@ -2099,6 +2119,8 @@ F32 LLVOVolume::getBinRadius() radius = llmin(bounds.mV[1], bounds.mV[2]); radius = llmin(radius, bounds.mV[0]); radius *= 0.5f; + radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0]; } else if (shrink_wrap) { @@ -2106,27 +2128,22 @@ F32 LLVOVolume::getBinRadius() } else if (mDrawable->isStatic()) { - /*if (mDrawable->getRadius() < 2.0f) - { - radius = 16.f; - } - else - { - radius = llmax(mDrawable->getRadius(), 32.f); - }*/ - - radius = (((S32) mDrawable->getRadius())/2+1)*8; + radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor; + radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; } else if (mDrawable->getVObj()->isAttachment()) { - radius = (((S32) (mDrawable->getRadius()*4)+1))*2; + radius = llmax((S32) mDrawable->getRadius(),1)*attachment_size_factor; } else { - radius = 8.f; + radius = mDrawable->getRadius(); + radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; } - return llclamp(radius, 0.5f, 256.f); + return llclamp(radius*scale, 0.5f, 256.f); } const LLVector3 LLVOVolume::getPivotPositionAgent() const diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 65dd11119..6eb4b56b4 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -365,6 +365,7 @@ void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE); + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); @@ -2413,6 +2414,31 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu) } } +void LLPipeline::markPartitionMove(LLDrawable* drawable) +{ + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().isExactlyZero()) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } +} + +void LLPipeline::processPartitionQ() +{ + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } + + mPartitionQ.clear(); +} void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -7282,7 +7308,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); } } else @@ -7346,7 +7372,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); } gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredSpotLightProgram); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4145a9476..efafec32e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -135,6 +135,7 @@ public: void markGLRebuild(LLGLUpdate* glu); void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); + void markPartitionMove(LLDrawable* drawablep); //get the object between start and end that's closest to start. LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, @@ -188,6 +189,7 @@ public: void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); + void processPartitionQ(); void updateGeom(F32 max_dtime); void updateGL(); void rebuildPriorityGroups(); @@ -592,6 +594,9 @@ protected: LLDrawable::drawable_list_t mBuildQ2; // non-priority LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + + LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius + bool mGroupQ2Locked; bool mGroupQ1Locked;