summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawable.cpp
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-03-22 00:44:59 -0700
committerRichard Linden <none@none>2013-03-22 00:44:59 -0700
commit68f9f656cd22332e46959a90347e38f79c19a66c (patch)
tree531d87287b69f500c5901f785e60483555b415f9 /indra/newview/lldrawable.cpp
parente87000ba0750e55d9d6b55feccc4124f5d2b4b74 (diff)
parent368dd542bec7c31e14673b83d3342c35717d2920 (diff)
merge with viewer-release
Diffstat (limited to 'indra/newview/lldrawable.cpp')
-rw-r--r--indra/newview/lldrawable.cpp336
1 files changed, 166 insertions, 170 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index d041baea90..4d72dd1343 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;
@@ -58,6 +59,7 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
extern bool gShiftFrame;
+LLTrace::MemStatHandle LLDrawable::sMemStat("LLDrawable");
////////////////////////
@@ -75,7 +77,6 @@ extern bool gShiftFrame;
//
// static
-U32 LLDrawable::sCurVisible = 0;
U32 LLDrawable::sNumZombieDrawables = 0;
F32 LLDrawable::sCurPixelAngle = 0;
LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
@@ -85,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();
-
mState = 0;
- mVObjp = NULL;
+
// mFaces
- mSpatialGroupp = NULL;
- mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
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.
+ }
- mGeneration = -1;
- mBinRadius = 1.f;
- mBinIndex = -1;
+ getRegion()->addActiveCacheEntry(vo_entry);
+ }
- mSpatialBridge = NULL;
+ llassert(!vo_entry || vo_entry->getEntry() == mEntry);
+
+ initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
// static
@@ -155,6 +182,7 @@ void LLDrawable::markDead()
llwarns << "Warning! Marking dead multiple times!" << llendl;
return;
}
+ setState(DEAD);
if (mSpatialBridge)
{
@@ -165,7 +193,6 @@ void LLDrawable::markDead()
sNumZombieDrawables++;
// We're dead. Free up all of our references to other objects
- setState(DEAD);
cleanupReferences();
// sDeadList.put(this);
}
@@ -219,6 +246,8 @@ void LLDrawable::cleanupReferences()
gPipeline.unlinkDrawable(this);
+ removeFromOctree();
+
{
LLFastTimer t(FTM_DEREF_DRAWABLE);
// Cleanup references to other objects
@@ -227,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()
{
/*
@@ -287,10 +331,10 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
LLFace *face;
-
+
{
LLFastTimer t(FTM_ALLOCATE_FACE);
- face = new LLFace(this, mVObjp);
+ face = new LLFace(this, mVObjp);
}
face->setTEOffset(mFaces.size());
@@ -439,6 +483,12 @@ 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());
}
@@ -519,7 +569,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
if (damped && isVisible())
{
- F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
+ F32 lerp_amt = llclamp(LLSmoothInterpolation::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
dist_squared = dist_vec_squared(new_pos, target_pos);
@@ -738,7 +788,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVOVolume* volume = getVOVolume();
if (volume)
{
- if (getSpatialGroup())
+ if (getGroup())
{
pos.set(getPositionGroup().getF32ptr());
}
@@ -856,9 +906,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)
{
@@ -866,9 +914,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);
@@ -880,40 +926,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);
}
}
@@ -922,11 +952,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));
}
}
@@ -960,26 +990,56 @@ void LLDrawable::updateUVMinMax()
{
}
-LLSpatialGroup* LLDrawable::getSpatialGroup() const
+//virtual
+bool LLDrawable::isVisible() const
+{
+ if (LLViewerOctreeEntryData::isVisible())
{
- llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
- return mSpatialGroupp;
+ return true;
}
-void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
- //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
- llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
+ LLviewerOctreeGroup* group = mEntry->getGroup();
+ if (group && group->isVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ return true;
+ }
+ }
- //precondition: groupp MUST be null or groupp MUST contain this
- llassert(!groupp || groupp->hasElement(this));
+ return false;
+}
-/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
+//virtual
+bool LLDrawable::isRecentlyVisible() const
+{
+ //currently visible or visible in the previous frame.
+ bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
+
+ 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));
- if (mSpatialGroupp != groupp && getVOVolume())
+ //precondition: groupp MUST be null or groupp MUST contain this
+ llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));
+
+ 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
@@ -995,10 +1055,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()
@@ -1017,11 +1077,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();
@@ -1040,89 +1100,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()
-{
- return MIN_VIS_FRAME_RANGE ;
-}
-
-BOOL LLDrawable::isRecentlyVisible() const
+//virtual
+S32 LLDrawable::getMinVisFrameRange() 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;
@@ -1143,11 +1140,14 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLSpatialBridge::~LLSpatialBridge()
{
+ if(mEntry)
+ {
LLSpatialGroup* group = getSpatialGroup();
if (group)
{
group->mSpatialPartition->remove(this, group);
}
+ }
//delete octree here so listeners will still be able to access bridge specific state
destroyTree();
@@ -1168,8 +1168,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;
@@ -1181,7 +1182,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];
@@ -1203,12 +1204,9 @@ void LLSpatialBridge::updateSpatialExtents()
scale.mul(size);
mat.rotate(scale, v[3]);
-
- LLVector4a& newMin = mExtents[0];
- LLVector4a& newMax = mExtents[1];
-
+ LLVector4a newMin;
+ LLVector4a newMax;
newMin = newMax = center;
-
for (U32 i = 0; i < 4; i++)
{
LLVector4a delta;
@@ -1221,19 +1219,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)
@@ -1268,7 +1268,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
@@ -1303,21 +1303,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);
}
@@ -1361,7 +1361,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
if (!group ||
- LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
+ LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
impostor ||
!loaded)
{
@@ -1375,16 +1375,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 &&
@@ -1499,9 +1500,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()
@@ -1509,11 +1508,8 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
- /*
-
- DON'T DO THIS -- this should happen through octree destruction
+ mDrawable->setGroup(NULL);
- mDrawable->setSpatialGroup(NULL);
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1524,10 +1520,10 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
- drawable->setSpatialGroup(NULL);
+ drawable->setGroup(NULL);
+ }
}
}
- }*/
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1596,8 +1592,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;
@@ -1605,8 +1601,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;