summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawable.cpp')
-rw-r--r--indra/newview/lldrawable.cpp355
1 files changed, 175 insertions, 180 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 6ef437cefb..ba970671af 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -49,6 +49,7 @@
#include "llspatialpartition.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
+#include "llvocache.h"
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
@@ -76,7 +77,6 @@ LLTrace::MemStat LLDrawable::sMemStat("LLDrawable");
//
// static
-U32 LLDrawable::sCurVisible = 0;
U32 LLDrawable::sNumZombieDrawables = 0;
F32 LLDrawable::sCurPixelAngle = 0;
LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
@@ -86,33 +86,59 @@ LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
// static
void LLDrawable::incrementVisible()
{
- sCurVisible++;
+ LLViewerOctreeEntryData::incrementVisible();
sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
}
-void LLDrawable::init()
+LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
+ : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
+ mVObjp(vobj)
+{
+ init(new_entry);
+}
+
+void LLDrawable::init(bool new_entry)
{
// mXform
mParent = NULL;
mRenderType = 0;
mCurrentScale = LLVector3(1,1,1);
- mDistanceWRTCamera = 0.0f;
- mPositionGroup.clear();
- mExtents[0].clear();
- mExtents[1].clear();
-
+ mDistanceWRTCamera = 0.0f;
mState = 0;
- mVObjp = NULL;
- // mFaces
- mSpatialGroupp = NULL;
- mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
- mRadius = 0.f;
- mGeneration = -1;
- mBinRadius = 1.f;
- mBinIndex = -1;
-
+ // mFaces
+ mRadius = 0.f;
+ mGeneration = -1;
mSpatialBridge = NULL;
+
+ LLViewerOctreeEntry* entry = NULL;
+ LLVOCacheEntry* vo_entry = NULL;
+ if(!new_entry && mVObjp && getRegion() != NULL)
+ {
+ vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID());
+ if(vo_entry)
+ {
+ entry = vo_entry->getEntry();
+ }
+ }
+ setOctreeEntry(entry);
+ if(vo_entry)
+ {
+ if(!entry)
+ {
+ vo_entry->setOctreeEntry(mEntry);
+ }
+ else if(vo_entry->getNumOfChildren() > 0)
+ {
+ getRegion()->addVisibleCacheEntry(vo_entry); //to load all children.
+ }
+
+ getRegion()->addActiveCacheEntry(vo_entry);
+ }
+
+ llassert(!vo_entry || vo_entry->getEntry() == mEntry);
+
+ initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
// static
@@ -156,6 +182,7 @@ void LLDrawable::markDead()
llwarns << "Warning! Marking dead multiple times!" << llendl;
return;
}
+ setState(DEAD);
if (mSpatialBridge)
{
@@ -165,8 +192,7 @@ void LLDrawable::markDead()
sNumZombieDrawables++;
- // We're dead. Free up all of our references to other objects
- setState(DEAD);
+ // We're dead. Free up all of our references to other objects
cleanupReferences();
// sDeadList.put(this);
}
@@ -220,6 +246,8 @@ void LLDrawable::cleanupReferences()
gPipeline.unlinkDrawable(this);
+ removeFromOctree();
+
{
LLFastTimer t(FTM_DEREF_DRAWABLE);
// Cleanup references to other objects
@@ -228,6 +256,21 @@ void LLDrawable::cleanupReferences()
}
}
+void LLDrawable::removeFromOctree()
+{
+ if(!mEntry)
+ {
+ return;
+ }
+
+ mEntry->removeData(this);
+ if(mEntry->hasVOCacheEntry())
+ {
+ getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this);
+ }
+ mEntry = NULL;
+}
+
void LLDrawable::cleanupDeadDrawables()
{
/*
@@ -428,7 +471,13 @@ void LLDrawable::makeActive()
}
updatePartition();
}
-
+ else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does...
+ {
+ mParent->makeActive();
+ //NOTE: linked set will now NEVER become static
+ mParent->setState(LLDrawable::ACTIVE_CHILD);
+ }
+
llassert(isAvatar() || isRoot() || mParent->isActive());
}
@@ -717,7 +766,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVOVolume* volume = getVOVolume();
if (volume)
{
- if (getSpatialGroup())
+ if (getGroup())
{
pos.set(getPositionGroup().getF32ptr());
}
@@ -835,9 +884,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
}
- mExtents[0].add(shift_vector);
- mExtents[1].add(shift_vector);
- mPositionGroup.add(shift_vector);
+ shift(shift_vector);
}
else if (mSpatialBridge)
{
@@ -845,9 +892,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
else if (isAvatar())
{
- mExtents[0].add(shift_vector);
- mExtents[1].add(shift_vector);
- mPositionGroup.add(shift_vector);
+ shift(shift_vector);
}
mVObjp->onShift(shift_vector);
@@ -859,40 +904,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
return mXform.getPositionW();
}
-const LLVector4a* LLDrawable::getSpatialExtents() const
-{
- return mExtents;
-}
-
-void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max)
-{
- mExtents[0].load3(min.mV);
- mExtents[1].load3(max.mV);
-}
-
-void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
-{
- mExtents[0] = min;
- mExtents[1] = max;
-}
-
-void LLDrawable::setPositionGroup(const LLVector4a& pos)
-{
- mPositionGroup = pos;
-}
-
void LLDrawable::updateSpatialExtents()
{
if (mVObjp)
{
- mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]);
+ const LLVector4a* exts = getSpatialExtents();
+ LLVector4a extents[2];
+ extents[0] = exts[0];
+ extents[1] = exts[1];
+
+ mVObjp->updateSpatialExtents(extents[0], extents[1]);
+ setSpatialExtents(extents[0], extents[1]);
}
updateBinRadius();
if (mSpatialBridge.notNull())
{
- mPositionGroup.splat(0.f);
+ getGroupPosition().splat(0.f);
}
}
@@ -901,11 +930,11 @@ void LLDrawable::updateBinRadius()
{
if (mVObjp.notNull())
{
- mBinRadius = llmin(mVObjp->getBinRadius(), 256.f);
+ setBinRadius(llmin(mVObjp->getBinRadius(), 256.f));
}
else
{
- mBinRadius = llmin(getRadius()*4.f, 256.f);
+ setBinRadius(llmin(getRadius()*4.f, 256.f));
}
}
@@ -939,26 +968,56 @@ void LLDrawable::updateUVMinMax()
{
}
-LLSpatialGroup* LLDrawable::getSpatialGroup() const
-{
- llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
- return mSpatialGroupp;
+//virtual
+bool LLDrawable::isVisible() const
+{
+ if (LLViewerOctreeEntryData::isVisible())
+ {
+ return true;
+ }
+
+ {
+ LLviewerOctreeGroup* group = mEntry->getGroup();
+ if (group && group->isVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ return true;
+ }
+ }
+
+ return false;
}
-void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
+//virtual
+bool LLDrawable::isRecentlyVisible() const
{
- //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
- llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
-
- //precondition: groupp MUST be null or groupp MUST contain this
- llassert(!groupp || groupp->hasElement(this));
+ //currently visible or visible in the previous frame.
+ bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
-/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
+ if(!vis)
{
- mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
- }*/
+ LLviewerOctreeGroup* group = getGroup();
+ if (group && group->isRecentlyVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ vis = TRUE ;
+ }
+ }
+
+ return vis ;
+}
+
+void LLDrawable::setGroup(LLviewerOctreeGroup *groupp)
+{
+ LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup();
+
+ //precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this
+ //llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this));
+
+ //precondition: groupp MUST be null or groupp MUST contain this
+ llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));
- if (mSpatialGroupp != groupp && getVOVolume())
+ if (cur_groupp != groupp && getVOVolume())
{ //NULL out vertex buffer references for volumes on spatial group change to maintain
//requirement that every face vertex buffer is either NULL or points to a vertex buffer
//contained by its drawable's spatial group
@@ -974,10 +1033,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
//postcondition: if next group is NOT NULL, binIndex must not be -1
- llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
- getBinIndex() != -1);
+ //llassert(groupp == NULL ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) :
+ // (getEntry() && getEntry()->getBinIndex() != -1));
- mSpatialGroupp = groupp;
+ LLViewerOctreeEntryData::setGroup(groupp);
}
LLSpatialPartition* LLDrawable::getSpatialPartition()
@@ -996,11 +1055,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
{
if (mVObjp->isHUDAttachment())
{
- setSpatialBridge(new LLHUDBridge(this));
+ setSpatialBridge(new LLHUDBridge(this, getRegion()));
}
else
{
- setSpatialBridge(new LLVolumeBridge(this));
+ setSpatialBridge(new LLVolumeBridge(this, getRegion()));
}
}
return mSpatialBridge->asPartition();
@@ -1019,89 +1078,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
-const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
-//static
-S32 LLDrawable::getMinVisFrameRange()
+//virtual
+S32 LLDrawable::getMinVisFrameRange() const
{
- return MIN_VIS_FRAME_RANGE ;
-}
-
-BOOL LLDrawable::isRecentlyVisible() const
-{
- //currently visible or visible in the previous frame.
- BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
-
- if(!vis)
- {
- LLSpatialGroup* group = getSpatialGroup();
- if (group && group->isRecentlyVisible())
- {
- mVisible = sCurVisible;
- vis = TRUE ;
- }
- }
-
- return vis ;
-}
-
-BOOL LLDrawable::isVisible() const
-{
- if (mVisible == sCurVisible)
- {
- return TRUE;
- }
-
-#if 0
- //disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result.
- //should be safe to just always ask the spatial group for visibility.
- if (isActive())
- {
- if (isRoot())
- {
- LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() :
- getSpatialGroup();
- if (group && group->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
- else
- {
- if (getParent()->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
- }
- else
-#endif
- {
- LLSpatialGroup* group = getSpatialGroup();
- if (group && group->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
+ const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
- return FALSE;
+ return MIN_VIS_FRAME_RANGE ;
}
//=======================================
// Spatial Partition Bridging Drawable
//=======================================
-LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
-: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
+LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
+ LLDrawable(root->getVObj(), true),
+ LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
{
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
- mBinIndex = -1;
-
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1122,10 +1118,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLSpatialBridge::~LLSpatialBridge()
{
- LLSpatialGroup* group = getSpatialGroup();
- if (group)
+ if(mEntry)
{
- group->mSpatialPartition->remove(this, group);
+ LLSpatialGroup* group = getSpatialGroup();
+ if (group)
+ {
+ group->mSpatialPartition->remove(this, group);
+ }
}
//delete octree here so listeners will still be able to access bridge specific state
@@ -1147,8 +1146,9 @@ void LLSpatialBridge::updateSpatialExtents()
root->rebound();
}
+ const LLVector4a* root_bounds = root->getBounds();
LLVector4a offset;
- LLVector4a size = root->mBounds[1];
+ LLVector4a size = root_bounds[1];
//VECTORIZE THIS
LLMatrix4a mat;
@@ -1160,7 +1160,7 @@ void LLSpatialBridge::updateSpatialExtents()
LLVector4a center;
mat.affineTransform(t, center);
- mat.rotate(root->mBounds[0], offset);
+ mat.rotate(root_bounds[0], offset);
center.add(offset);
LLVector4a v[4];
@@ -1182,12 +1182,9 @@ void LLSpatialBridge::updateSpatialExtents()
scale.mul(size);
mat.rotate(scale, v[3]);
-
- LLVector4a& newMin = mExtents[0];
- LLVector4a& newMax = mExtents[1];
-
- newMin = newMax = center;
-
+ LLVector4a newMin;
+ LLVector4a newMax;
+ newMin = newMax = center;
for (U32 i = 0; i < 4; i++)
{
LLVector4a delta;
@@ -1200,19 +1197,21 @@ void LLSpatialBridge::updateSpatialExtents()
newMin.setMin(newMin, min);
newMax.setMax(newMax, max);
}
-
+ setSpatialExtents(newMin, newMax);
+
LLVector4a diagonal;
diagonal.setSub(newMax, newMin);
mRadius = diagonal.getLength3().getF32() * 0.5f;
- mPositionGroup.setAdd(newMin,newMax);
- mPositionGroup.mul(0.5f);
+ LLVector4a& pos = getGroupPosition();
+ pos.setAdd(newMin,newMax);
+ pos.mul(0.5f);
updateBinRadius();
}
void LLSpatialBridge::updateBinRadius()
{
- mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f);
+ setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));
}
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
@@ -1247,7 +1246,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
{
- mVisible = sCurVisible;
+ LLViewerOctreeEntryData::setVisible();
#if 0 && !LL_RELEASE_FOR_DOWNLOAD
//crazy paranoid rules checking
@@ -1282,21 +1281,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,
#endif
}
-class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable>
+class LLOctreeMarkNotCulled: public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { }
- virtual void traverse(const LLOctreeNode<LLDrawable>* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
group->setVisible();
- LLOctreeTraveler<LLDrawable>::traverse(node);
+ OctreeTraveler::traverse(node);
}
- void visit(const LLOctreeNode<LLDrawable>* branch)
+ void visit(const OctreeNode* branch)
{
gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera);
}
@@ -1340,7 +1339,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
if (!group ||
- LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
+ LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
impostor ||
!loaded)
{
@@ -1354,16 +1353,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
group->rebound();
LLVector4a center;
- center.setAdd(mExtents[0], mExtents[1]);
+ const LLVector4a* exts = getSpatialExtents();
+ center.setAdd(exts[0], exts[1]);
center.mul(0.5f);
LLVector4a size;
- size.setSub(mExtents[1], mExtents[0]);
+ size.setSub(exts[1], exts[0]);
size.mul(0.5f);
if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||
LLPipeline::sImpostorRender ||
(camera_in.AABBInFrustumNoFarClip(center, size) &&
- AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
+ AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
{
if (!LLPipeline::sImpostorRender &&
!LLPipeline::sShadowRender &&
@@ -1478,9 +1478,7 @@ BOOL LLSpatialBridge::updateMove()
void LLSpatialBridge::shiftPos(const LLVector4a& vec)
{
- mExtents[0].add(vec);
- mExtents[1].add(vec);
- mPositionGroup.add(vec);
+ LLDrawable::shift(vec);
}
void LLSpatialBridge::cleanupReferences()
@@ -1488,11 +1486,8 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
- /*
+ mDrawable->setGroup(NULL);
- DON'T DO THIS -- this should happen through octree destruction
-
- mDrawable->setSpatialGroup(NULL);
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1503,10 +1498,10 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
- drawable->setSpatialGroup(NULL);
- }
+ drawable->setGroup(NULL);
}
- }*/
+ }
+ }
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1575,8 +1570,8 @@ void LLDrawable::updateFaceSize(S32 idx)
}
}
-LLBridgePartition::LLBridgePartition()
-: LLSpatialPartition(0, FALSE, 0)
+LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
+: LLSpatialPartition(0, FALSE, 0, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
@@ -1584,8 +1579,8 @@ LLBridgePartition::LLBridgePartition()
mSlopRatio = 0.25f;
}
-LLHUDBridge::LLHUDBridge(LLDrawable* drawablep)
-: LLVolumeBridge(drawablep)
+LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+: LLVolumeBridge(drawablep, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_HUD;
mPartitionType = LLViewerRegion::PARTITION_HUD;