summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2012-10-31 17:05:53 -0600
committerXiaohong Bao <bao@lindenlab.com>2012-10-31 17:05:53 -0600
commit5ae116f89b8459963ccb6ae9125d94ffaa79025e (patch)
treed9404c72f950d505cad189764bbf3ca07e62c50d /indra/newview
parente35a220bf7dd47132174c81181d5f59fb0d54c5d (diff)
for SH-3471: create a simplified version of octree for object cache entries.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llspatialpartition.cpp108
-rw-r--r--indra/newview/llspatialpartition.h49
-rw-r--r--indra/newview/llvieweroctree.cpp48
-rw-r--r--indra/newview/llvieweroctree.h39
-rw-r--r--indra/newview/llviewerregion.cpp174
-rw-r--r--indra/newview/llviewerregion.h14
-rw-r--r--indra/newview/llvocache.cpp77
-rw-r--r--indra/newview/llvocache.h13
-rw-r--r--indra/newview/pipeline.cpp20
9 files changed, 346 insertions, 196 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index debb790c58..e9ece331d1 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -264,11 +264,7 @@ LLSpatialGroup::~LLSpatialGroup()
{
llerrs << "Illegal deletion of LLSpatialGroup!" << llendl;
}*/
- if(isVisible())
- {
- mSpatialPartition->mRegionp->clearVisibleGroup(this);
- }
-
+
if (gDebugGL)
{
gPipeline.checkReferences(this);
@@ -434,16 +430,6 @@ BOOL LLSpatialGroup::isRecentlyVisible() const
return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ;
}
-BOOL LLSpatialGroup::isVisible() const
-{
- return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE;
-}
-
-void LLSpatialGroup::setVisible()
-{
- mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame();
-}
-
void LLSpatialGroup::validate()
{
ll_assert_aligned(this,64);
@@ -1165,12 +1151,6 @@ BOOL LLSpatialGroup::changeLOD()
void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- if(mSpatialPartition->isVOCachePartition())
- {
- LLviewerOctreeGroup::handleInsertion(node, entry);
- return;
- }
-
addObject((LLDrawable*)entry->getDrawable());
unbound();
setState(OBJECT_DIRTY);
@@ -1178,10 +1158,7 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry*
void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- if(!mSpatialPartition->isVOCachePartition())
- {
- removeObject((LLDrawable*)entry->getDrawable(), TRUE);
- }
+ removeObject((LLDrawable*)entry->getDrawable(), TRUE);
LLviewerOctreeGroup::handleRemoval(node, entry);
}
@@ -1189,12 +1166,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
{
setState(DEAD);
- if(mSpatialPartition->isVOCachePartition())
- {
- LLviewerOctreeGroup::handleDestruction(node);
- return;
- }
-
for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLViewerOctreeEntry* entry = *i;
@@ -1510,8 +1481,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
//==============================================
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp)
-: mRenderByGroup(render_by_group), mBridge(NULL), mRegionp(regionp)
+: mRenderByGroup(render_by_group), mBridge(NULL)
{
+ mRegionp = regionp;
mOcclusionEnabled = TRUE;
mDrawableType = 0;
mPartitionType = LLViewerRegion::PARTITION_NONE;
@@ -1521,27 +1493,14 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32
mBufferUsage = buffer_usage;
mDepthMask = FALSE;
mSlopRatio = 0.25f;
- mInfiniteFarClip = FALSE;
- mVisitedTime = 0;
-
- LLVector4a center, size;
- center.splat(0.f);
- size.splat(1.f);
+ mInfiniteFarClip = FALSE;
- mOctree = new OctreeRoot(center,size, NULL);
new LLSpatialGroup(mOctree, this);
}
LLSpatialPartition::~LLSpatialPartition()
-{
- delete mOctree;
- mOctree = NULL;
-}
-
-BOOL LLSpatialPartition::isVOCachePartition() const
-{
- return mPartitionType == LLViewerRegion::PARTITION_VO_CACHE;
+{
}
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
@@ -2050,12 +2009,7 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera)
S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select)
{
- bool is_vo_cache_part = (mPartitionType == LLViewerRegion::PARTITION_VO_CACHE);
-
- if(is_vo_cache_part && mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame())
- {
- return 0; //no need to visit more than once per frame
- }
+ llassert(results != NULL && for_select);
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
@@ -2070,19 +2024,34 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
((LLSpatialGroup*)mOctree->getListener(0))->validate();
#endif
+ LLOctreeSelect selecter(&camera, results);
+ selecter.traverse(mOctree);
- if (for_select && !is_vo_cache_part)
+ return 0;
+}
+
+S32 LLSpatialPartition::cull(LLCamera &camera)
+{
+#if LL_OCTREE_PARANOIA_CHECK
+ ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
+#endif
{
- LLOctreeSelect selecter(&camera, results);
- selecter.traverse(mOctree);
+ LLFastTimer ftm(FTM_CULL_REBOUND);
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
}
- else if (LLPipeline::sShadowRender && !is_vo_cache_part)
+
+#if LL_OCTREE_PARANOIA_CHECK
+ ((LLSpatialGroup*)mOctree->getListener(0))->validate();
+#endif
+
+ if (LLPipeline::sShadowRender)
{
LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCullShadow culler(&camera);
culler.traverse(mOctree);
}
- else if ((mInfiniteFarClip || !LLPipeline::sUseFarClip) && !is_vo_cache_part)
+ else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
{
LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCullNoFarClip culler(&camera);
@@ -2090,11 +2059,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
}
else
{
- if(is_vo_cache_part)
- {
- mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame();
- }
-
LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCull culler(&camera);
culler.traverse(mOctree);
@@ -4663,21 +4627,3 @@ void LLCullResult::assertDrawMapsEmpty()
}
}
-LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp)
-{
- mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
-}
-
-void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
-{
- llassert(entry->hasVOCacheEntry());
-
- mOctree->insert(entry);
-}
-
-void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
-{
- entry->getVOCacheEntry()->setGroup(NULL);
-
- llassert(!entry->getGroup());
-}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index dd189d751d..079c0f58f0 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -45,6 +45,7 @@
#define SG_STATE_INHERIT_MASK (OCCLUDED)
#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
+class LLViewerOctreePartition;
class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
@@ -225,10 +226,7 @@ public:
typedef std::map<U32, drawmap_elem_t > draw_map_t;
typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
- typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
-
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+ typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
struct CompareDistanceGreater
{
@@ -308,9 +306,7 @@ public:
BOOL addObject(LLDrawable *drawablep);
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
- BOOL isVisible() const;
BOOL isRecentlyVisible() const;
- void setVisible();
void shift(const LLVector4a &offset);
void checkOcclusion(); //read back last occlusion query (if any)
void doOcclusion(LLCamera* camera); //issue occlusion query
@@ -325,14 +321,7 @@ public:
void setState(U32 state) {mState |= state;}
void dirtyGeom() { setState(GEOM_DIRTY); }
- void dirtyMesh() { setState(MESH_DIRTY); }
-
- //octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
- element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
- element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
- U32 getElementCount() const { return mOctreeNode->getElementCount(); }
- bool isEmpty() const { return mOctreeNode->isEmpty(); }
+ void dirtyMesh() { setState(MESH_DIRTY); }
void drawObjectBox(LLColor4 col);
@@ -404,8 +393,7 @@ public:
U32 mBufferUsage;
draw_map_t mDrawMap;
-
- S32 mVisible[LLViewerCamera::NUM_CAMERAS];
+
F32 mDistance;
F32 mDepth;
F32 mLastUpdateDistance;
@@ -428,7 +416,7 @@ public:
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
-class LLSpatialPartition: public LLGeometryManager
+class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
{
public:
LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp);
@@ -458,7 +446,8 @@ public:
virtual void rebuildMesh(LLSpatialGroup* group);
BOOL visibleObjectsInFrustum(LLCamera& camera);
- S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
+ /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum
+ S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum
BOOL isVisible(const LLVector3& v);
bool isHUDPartition() ;
@@ -473,26 +462,21 @@ public:
void resetVertexBuffers();
BOOL isOcclusionEnabled();
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
- BOOL isVOCachePartition() const;
-
+
public:
- OctreeNode* mOctree;
LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
// to call asBridge() from the destructor
BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
U32 mBufferUsage;
+ U32 mDrawableType;
const BOOL mRenderByGroup;
U32 mLODSeed;
U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
U32 mVertexDataMask;
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
- BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
- U32 mDrawableType;
- U32 mPartitionType;
- U32 mVisitedTime;
- LLViewerRegion* mRegionp; // the region this partition belongs to.
+ BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
};
// class for creating bridges between spatial partitions
@@ -638,19 +622,6 @@ public:
LLVoidWaterPartition(LLViewerRegion* regionp);
};
-//spatial partition for hole and edge water (implemented in LLVOWater.cpp)
-class LLVOCachePartition : public LLSpatialPartition
-{
-public:
- LLVOCachePartition(LLViewerRegion* regionp);
-
- void addEntry(LLViewerOctreeEntry* entry);
- void removeEntry(LLViewerOctreeEntry* entry);
-
- virtual void getGeometry(LLSpatialGroup* group) { }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
-};
-
//spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
class LLTerrainPartition : public LLSpatialPartition
{
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 05f977036c..143f2a6819 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -26,6 +26,7 @@
#include "llviewerprecompiledheaders.h"
#include "llvieweroctree.h"
+#include "llviewerregion.h"
//-----------------------------------------------------------------------------------
//static variables definitions
@@ -324,6 +325,10 @@ void LLViewerOctreeEntryData::setVisible() const
LLviewerOctreeGroup::~LLviewerOctreeGroup()
{
+ if(LLViewerRegion::sCurRegionp && isVisible())
+ {
+ LLViewerRegion::sCurRegionp->clearVisibleGroup(this);
+ }
}
LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) :
@@ -482,8 +487,10 @@ void LLviewerOctreeGroup::handleDestruction(const TreeNode* node)
if (obj && obj->getGroup() == this)
{
obj->nullGroup();
+ //obj->setGroup(NULL);
}
}
+ mOctreeNode = NULL;
}
//virtual
@@ -500,8 +507,17 @@ void LLviewerOctreeGroup::handleStateChange(const TreeNode* node)
//virtual
void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
- llerrs << "can not access here. It is an abstract class." << llendl;
+ if (child->getListenerCount() == 0)
+ {
+ new LLviewerOctreeGroup(child);
+ }
+ else
+ {
+ OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl;
+ }
+ unbound();
+
//((LLviewerOctreeGroup*)child->getListener(0))->unbound();
}
@@ -589,7 +605,35 @@ bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4
//virtual
BOOL LLviewerOctreeGroup::isVisible() const
{
- return TRUE;
+ return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE;
+}
+
+//virtual
+BOOL LLviewerOctreeGroup::isRecentlyVisible() const
+{
+ return FALSE;
+}
+
+void LLviewerOctreeGroup::setVisible()
+{
+ mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
+}
+//-----------------------------------------------------------------------------------
+//class LLViewerOctreePartition definitions
+//-----------------------------------------------------------------------------------
+LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL)
+{
+ LLVector4a center, size;
+ center.splat(0.f);
+ size.splat(1.f);
+
+ mOctree = new OctreeRoot(center,size, NULL);
+}
+
+LLViewerOctreePartition::~LLViewerOctreePartition()
+{
+ delete mOctree;
+ mOctree = NULL;
}
//-----------------------------------------------------------------------------------
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index c063e96ea5..498ec3e75d 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -37,8 +37,9 @@
#include "llvector4a.h"
#include "llquaternion.h"
#include "lloctree.h"
-#include "llcamera.h"
+#include "llviewercamera.h"
+class LLViewerRegion;
class LLViewerOctreeEntryData;
class LLviewerOctreeGroup;
class LLViewerOctreeEntry;
@@ -181,6 +182,9 @@ public:
};
public:
+ typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
+ typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+
LLviewerOctreeGroup(OctreeNode* node);
LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs)
{
@@ -203,8 +207,10 @@ public:
virtual void unbound();
virtual void rebound();
- virtual BOOL isVisible() const;
- virtual BOOL isRecentlyVisible() const = 0;
+ void setVisible();
+ BOOL isVisible() const;
+ virtual BOOL isRecentlyVisible() const;
+ bool isEmpty() const { return mOctreeNode->isEmpty(); }
U32 getState() {return mState; }
bool isDirty() const {return mState & DIRTY;}
@@ -228,20 +234,43 @@ public:
const LLVector4a* getObjectBounds() const {return mObjectBounds;}
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
+ //octree wrappers to make code more readable
+ element_list& getData() { return mOctreeNode->getData(); }
+ element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
+ element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
+ U32 getElementCount() const { return mOctreeNode->getElementCount(); }
+
private:
virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut);
protected:
U32 mState;
- OctreeNode* mOctreeNode;
-
+ OctreeNode* mOctreeNode;
+
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
+public:
+ S32 mVisible[LLViewerCamera::NUM_CAMERAS];
}LL_ALIGN_POSTFIX(16);
+class LLViewerOctreePartition
+{
+public:
+ LLViewerOctreePartition();
+ virtual ~LLViewerOctreePartition();
+
+ // Cull on arbitrary frustum
+ virtual S32 cull(LLCamera &camera) = 0;
+
+public:
+ U32 mPartitionType;
+ OctreeNode* mOctree;
+ LLViewerRegion* mRegionp; // the region this partition belongs to.
+};
+
class LLViewerOctreeCull : public OctreeTraveler
{
public:
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 0c0522d32f..1adab15d70 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -86,6 +86,8 @@ const F32 CAP_REQUEST_TIMEOUT = 18;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
+LLViewerRegion* LLViewerRegion::sCurRegionp = NULL;
+
typedef std::map<std::string, std::string> CapabilityMap;
class LLViewerRegionImpl {
@@ -139,7 +141,7 @@ public:
LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated.
LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set.
std::set< LLPointer<LLVOCacheEntry> > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use.
- std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup
+ std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible llspatialgroup
LLVOCachePartition* mVOCachePartition;
// time?
@@ -165,7 +167,7 @@ public:
LLCapabilityListener mCapabilityListener;
//spatial partitions for objects in this region
- std::vector<LLSpatialPartition*> mObjectPartition;
+ std::vector<LLViewerOctreePartition*> mObjectPartition;
};
// support for secondlife:///app/region/{REGION} SLapps
@@ -345,7 +347,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
- mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE);
+ mImpl->mVOCachePartition = getVOCachePartition();
}
@@ -384,12 +386,12 @@ LLViewerRegion::~LLViewerRegion()
delete mParcelOverlay;
delete mImpl->mLandp;
delete mImpl->mEventPoll;
- LLHTTPSender::clearSender(mImpl->mHost);
-
- saveObjectCache();
+ LLHTTPSender::clearSender(mImpl->mHost);
std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
+ saveObjectCache();
+
delete mImpl;
mImpl = NULL;
}
@@ -865,13 +867,13 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d
entry->setState(LLVOCacheEntry::INACTIVE);
}
-void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group)
+void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group)
{
- if(mDead || group->isEmpty() || group->isDead())
+ if(mDead || group->isEmpty())
{
return;
}
-
+ group->setVisible();
mImpl->mVisibleGroups.insert(group);
}
@@ -909,7 +911,7 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry)
mImpl->mVisibleEntries.insert(entry);
}
-void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group)
+void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group)
{
if(mDead)
{
@@ -920,44 +922,18 @@ void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group)
mImpl->mVisibleGroups.erase(group);
}
-
-BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
-{
- LLTimer update_timer;
-
- // did_update returns TRUE if we did at least one significant update
- BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
- if (mParcelOverlay)
- {
- // Hopefully not a significant time sink...
- mParcelOverlay->idleUpdate();
- }
-
- if(update_timer.getElapsedTimeF32() > max_update_time)
- {
- return did_update;
- }
-
- //kill invisible objects
- std::vector<LLDrawable*> delete_list;
- for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin();
- iter != mImpl->mActiveSet.end(); ++iter)
- {
- if(!(*iter)->isRecentlyVisible())
- {
- killObject((*iter), delete_list);
- }
- }
- for(S32 i = 0; i < delete_list.size(); i++)
+//return time left
+F32 LLViewerRegion::addLinkedSetChildren(F32 max_time, S32& max_num_objects)
+{
+ if(mImpl->mVisibleEntries.empty())
{
- gObjectList.killObject(delete_list[i]->getVObj());
+ return max_time;
}
- delete_list.clear();
+ LLTimer update_timer;
bool timeout = false;
- S32 new_object_count = 64; //minimum number of new objects to be added
- //add childrens of visible objects to the rendering pipeline
+
for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
{
LLVOCacheEntry* entry = *iter;
@@ -968,9 +944,9 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
{
addNewObject(child);
- if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time)
+ if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time)
{
- timeout = true;
+ timeout = true; //timeout
break;
}
}
@@ -982,7 +958,10 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
{
mImpl->mDummyEntries.erase(entry);
}
-
+ }
+
+ if(!timeout)
+ {
iter = mImpl->mVisibleEntries.erase(iter);
}
else
@@ -990,17 +969,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
break; //timeout
}
}
+
if(timeout)
{
- mImpl->mVisibleGroups.clear();
- return did_update;
+ return -1.f;
}
+ return max_time - update_timer.getElapsedTimeF32(); //time left
+}
- //add objects in the visible groups to the rendering pipeline
- std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin();
+F32 LLViewerRegion::addVisibleObjects(F32 max_time, S32& max_num_objects)
+{
+ if(mImpl->mVisibleGroups.empty())
+ {
+ return max_time;
+ }
+
+ LLTimer update_timer;
+ bool timeout = false;
+
+ std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin();
while(group_iter != mImpl->mVisibleGroups.end())
{
- LLSpatialGroup* group = *group_iter;
+ LLviewerOctreeGroup* group = *group_iter;
if(!group->getOctreeNode() || group->isEmpty())
{
mImpl->mVisibleGroups.erase(group_iter);
@@ -1009,7 +999,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
}
std::vector<LLViewerOctreeEntry*> entry_list;
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
//group data contents could change during creating new objects, so copy all contents first.
entry_list.push_back(*i);
@@ -1028,7 +1018,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
else if(vo_entry->isState(LLVOCacheEntry::INACTIVE))
{
addNewObject(vo_entry);
- if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time)
+ if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time)
{
timeout = true;
break;
@@ -1044,12 +1034,75 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
}
mImpl->mVisibleGroups.erase(group);
group_iter = mImpl->mVisibleGroups.begin();
+ }
+
+ if(timeout)
+ {
+ return -1.0f;
}
- mImpl->mVisibleGroups.clear();
+ return max_time - update_timer.getElapsedTimeF32();
+}
+
+BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
+{
+ LLTimer update_timer;
+ // did_update returns TRUE if we did at least one significant update
+ BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
+
+ if (mParcelOverlay)
+ {
+ // Hopefully not a significant time sink...
+ mParcelOverlay->idleUpdate();
+ }
+
+ max_update_time -= update_timer.getElapsedTimeF32();
+ if(max_update_time < 0.f)
+ {
+ return did_update;
+ }
+
+ sCurRegionp = this;
+
+ //kill invisible objects
+ max_update_time = killInvisibleObjects(max_update_time);
+
+ S32 new_object_count = 64; //minimum number of new objects to be added
+
+ //add childrens of visible objects to the rendering pipeline
+ max_update_time = addLinkedSetChildren(max_update_time, new_object_count);
+
+ //add objects in the visible groups to the rendering pipeline
+ if(max_update_time > 0.f)
+ {
+ addVisibleObjects(max_update_time, new_object_count);
+ }
+
+ mImpl->mVisibleGroups.clear();
+ sCurRegionp = NULL;
return did_update;
}
+F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
+{
+ std::vector<LLDrawable*> delete_list;
+ for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin();
+ iter != mImpl->mActiveSet.end(); ++iter)
+ {
+ if(!(*iter)->isRecentlyVisible())
+ {
+ killObject((*iter), delete_list);
+ }
+ }
+ for(S32 i = 0; i < delete_list.size(); i++)
+ {
+ gObjectList.killObject(delete_list[i]->getVObj());
+ }
+ delete_list.clear();
+
+ return max_time;
+}
+
void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
{
//kill the object.
@@ -2189,9 +2242,18 @@ void LLViewerRegion::logActiveCapabilities() const
LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
{
- if (type < mImpl->mObjectPartition.size())
+ if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE)
+ {
+ return (LLSpatialPartition*)mImpl->mObjectPartition[type];
+ }
+ return NULL;
+}
+
+LLVOCachePartition* LLViewerRegion::getVOCachePartition()
+{
+ if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())
{
- return mImpl->mObjectPartition[type];
+ return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];
}
return NULL;
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 17654a8bc7..86d3ee0d8c 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -69,6 +69,8 @@ class LLBBox;
class LLSpatialGroup;
class LLDrawable;
class LLViewerRegionImpl;
+class LLviewerOctreeGroup;
+class LLVOCachePartition;
class LLViewerRegion: public LLCapabilityProvider // implements this interface
{
@@ -85,7 +87,7 @@ public:
PARTITION_GRASS,
PARTITION_VOLUME,
PARTITION_BRIDGE,
- PARTITION_HUD_PARTICLE,
+ PARTITION_HUD_PARTICLE,
PARTITION_VO_CACHE,
PARTITION_NONE,
NUM_PARTITIONS
@@ -218,12 +220,12 @@ public:
F32 getWidth() const { return mWidth; }
BOOL idleUpdate(F32 max_update_time);
- void addVisibleGroup(LLSpatialGroup* group);
+ void addVisibleGroup(LLviewerOctreeGroup* group);
void addVisibleCacheEntry(LLVOCacheEntry* entry);
void addActiveCacheEntry(LLVOCacheEntry* entry);
void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
void killCacheEntry(U32 local_id); //physically delete the cache entry
- void clearVisibleGroup(LLSpatialGroup* group);
+ void clearVisibleGroup(LLviewerOctreeGroup* group);
// Like idleUpdate, but forces everything to complete regardless of
// how long it takes.
@@ -333,6 +335,7 @@ public:
U32 getNumOfActiveCachedObjects() const;
LLSpatialPartition* getSpatialPartition(U32 type);
+ LLVOCachePartition* getVOCachePartition();
bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
@@ -350,6 +353,10 @@ private:
void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry
+ F32 killInvisibleObjects(F32 max_time);
+ F32 addLinkedSetChildren(F32 max_time, S32& max_num_objects);
+ F32 addVisibleObjects(F32 max_time, S32& max_num_objects);
+
public:
struct CompareDistance
{
@@ -384,6 +391,7 @@ public:
LLDynamicArray<U32> mMapAvatars;
LLDynamicArray<LLUUID> mMapAvatarIDs;
+ static LLViewerRegion* sCurRegionp;
private:
LLViewerRegionImpl * mImpl;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index f389867484..d4938fd216 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -31,6 +31,7 @@
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "lldrawable.h"
+#include "llviewerregion.h"
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
@@ -356,6 +357,82 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
}
//-------------------------------------------------------------------
+//LLVOCachePartition
+//-------------------------------------------------------------------
+LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
+{
+ mRegionp = regionp;
+ mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
+ mVisitedTime = 0;
+
+ new LLviewerOctreeGroup(mOctree);
+}
+
+void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
+{
+ llassert(entry->hasVOCacheEntry());
+
+ mOctree->insert(entry);
+}
+
+void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
+{
+ entry->getVOCacheEntry()->setGroup(NULL);
+
+ llassert(!entry->getGroup());
+}
+
+class LLVOCacheOctreeCull : public LLViewerOctreeCull
+{
+public:
+ LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp) : LLViewerOctreeCull(camera), mRegionp(regionp) {}
+
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
+ {
+ S32 res = AABBInFrustumNoFarClipGroupBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBSphereIntersectGroupExtents(group));
+ }
+ return res;
+ }
+
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
+ {
+ S32 res = AABBInFrustumNoFarClipObjectBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBSphereIntersectObjectExtents(group));
+ }
+ return res;
+ }
+
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
+ {
+ mRegionp->addVisibleGroup(base_group);
+ }
+
+private:
+ LLViewerRegion* mRegionp;
+};
+
+S32 LLVOCachePartition::cull(LLCamera &camera)
+{
+ if(mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame())
+ {
+ return 0; //already visited.
+ }
+ mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame();
+
+ ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound();
+
+ LLVOCacheOctreeCull culler(&camera, mRegionp);
+ culler.traverse(mOctree);
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
//LLVOCache
//-------------------------------------------------------------------
// Format string used to construct filename for the object cache
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 2228e3e43b..675c12a3eb 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -98,6 +98,19 @@ protected:
std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set.
};
+class LLVOCachePartition : public LLViewerOctreePartition
+{
+public:
+ LLVOCachePartition(LLViewerRegion* regionp);
+
+ void addEntry(LLViewerOctreeEntry* entry);
+ void removeEntry(LLViewerOctreeEntry* entry);
+ /*virtual*/ S32 cull(LLCamera &camera);
+
+private:
+ U32 mVisitedTime;
+};
+
//
//Note: LLVOCache is not thread-safe
//
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e06577c512..850714f676 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -86,6 +86,7 @@
#include "llviewerregion.h" // for audio debugging.
#include "llviewerwindow.h" // For getSpinAxis
#include "llvoavatarself.h"
+#include "llvocache.h"
#include "llvoground.h"
#include "llvosky.h"
#include "llvotree.h"
@@ -2352,12 +2353,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
{
part->cull(camera);
}
- else if(part->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE)
- {
- part->cull(camera);
- }
}
}
+
+ //scan the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->cull(camera);
+ }
}
if (bound_shader)
@@ -2433,12 +2437,8 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
}
assertInitialized();
-
- if(group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE)
- {
- group->mSpatialPartition->mRegionp->addVisibleGroup(group);
- }
- else if (!group->mSpatialPartition->mRenderByGroup)
+
+ if (!group->mSpatialPartition->mRenderByGroup)
{ //render by drawable
sCull->pushDrawableGroup(group);
}