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.cpp288
1 files changed, 203 insertions, 85 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index b0dd0a99ac..583bb54160 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -2,30 +2,25 @@
* @file lldrawable.cpp
* @brief LLDrawable class implementation
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * 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.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * 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.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * 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
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -59,6 +54,9 @@ const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f;
const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
+static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+
+
////////////////////////
//
// Inline implementations.
@@ -85,7 +83,7 @@ LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
void LLDrawable::incrementVisible()
{
sCurVisible++;
- sCurPixelAngle = (F32) gViewerWindow->getWindowDisplayHeight()/LLViewerCamera::getInstance()->getView();
+ sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
}
void LLDrawable::init()
{
@@ -101,7 +99,7 @@ void LLDrawable::init()
mVObjp = NULL;
// mFaces
mSpatialGroupp = NULL;
- mVisible = 0;
+ mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
mRadius = 0.f;
mGeneration = -1;
@@ -122,6 +120,11 @@ void LLDrawable::destroy()
sNumZombieDrawables--;
}
+ if (LLSpatialGroup::sNoDelete)
+ {
+ llerrs << "Illegal deletion of LLDrawable!" << llendl;
+ }
+
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@@ -182,7 +185,7 @@ BOOL LLDrawable::isLight() const
void LLDrawable::cleanupReferences()
{
- LLFastTimer t(LLFastTimer::FTM_PIPELINE);
+ LLFastTimer t(FTM_PIPELINE);
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@@ -223,7 +226,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
-LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep)
+LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
LLMemType mt(LLMemType::MTYPE_DRAWABLE);
@@ -247,7 +250,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep)
return face;
}
-LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep)
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
LLMemType mt(LLMemType::MTYPE_DRAWABLE);
@@ -269,7 +272,7 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep)
}
-void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
+void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
{
@@ -288,9 +291,11 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImag
addFace(poolp, texturep);
}
}
+
+ llassert_always(mFaces.size() == newFaces);
}
-void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
+void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2)
{
@@ -309,6 +314,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer
addFace(poolp, texturep);
}
}
+
+ llassert_always(mFaces.size() == newFaces) ;
}
void LLDrawable::mergeFaces(LLDrawable* src)
@@ -329,6 +336,7 @@ void LLDrawable::deleteFaces(S32 offset, S32 count)
{
face_list_t::iterator face_begin = mFaces.begin() + offset;
face_list_t::iterator face_end = face_begin + count;
+
std::for_each(face_begin, face_end, DeletePointer());
mFaces.erase(face_begin, face_end);
}
@@ -352,6 +360,7 @@ void LLDrawable::makeActive()
if (pcode == LLViewerObject::LL_VO_WATER ||
pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
pcode == LLViewerObject::LL_VO_PART_GROUP ||
+ pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
pcode == LLViewerObject::LL_VO_CLOUDS ||
pcode == LLViewerObject::LL_VO_GROUND ||
pcode == LLViewerObject::LL_VO_SKY)
@@ -371,12 +380,15 @@ void LLDrawable::makeActive()
mParent->makeActive();
}
- gPipeline.setActive(this, TRUE);
-
//all child objects must also be active
- for (U32 i = 0; i < getChildCount(); i++)
+ llassert_always(mVObjp);
+
+ LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
{
- LLDrawable* drawable = getChild(i);
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
if (drawable)
{
drawable->makeActive();
@@ -414,17 +426,18 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
if (isState(ACTIVE))
{
clearState(ACTIVE);
- gPipeline.setActive(this, FALSE);
if (mParent.notNull() && mParent->isActive() && warning_enabled)
{
LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
}
-
- S32 child_count = mVObjp->mChildList.size();
- for (S32 child_num = 0; child_num < child_count; child_num++)
+
+ LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
{
- LLDrawable* child_drawable = mVObjp->mChildList[child_num]->mDrawable;
+ LLViewerObject* child = *iter;
+ LLDrawable* child_drawable = child->mDrawable;
if (child_drawable)
{
if (child_drawable->getParent() != this)
@@ -480,7 +493,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
F32 dist_squared = 0.f;
F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera);
- if (damped && mDistanceWRTCamera > 0.0f)
+ if (damped && isVisible())
{
F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
@@ -504,11 +517,19 @@ F32 LLDrawable::updateXform(BOOL undamped)
{
// snap to final position
dist_squared = 0.0f;
+ if (getVOVolume() && !isRoot())
+ { //child prim snapping to some position, needs a rebuild
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ }
}
}
if ((mCurrentScale != target_scale) ||
- (!isRoot() && (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED*camdist2)))
+ (!isRoot() &&
+ (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED ||
+ !mVObjp->getAngularVelocity().isExactlyZero() ||
+ target_pos != mXform.getPosition() ||
+ target_rot != mXform.getRotation())))
{ //child prim moving or scale change requires immediate rebuild
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
@@ -646,8 +667,13 @@ BOOL LLDrawable::updateMoveDamped()
return done_moving;
}
-void LLDrawable::updateDistance(LLCamera& camera)
+void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
+ if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
+ {
+ llerrs << "WTF?" << llendl;
+ }
+
//switch LOD with the spatial group to avoid artifacts
//LLSpatialGroup* sg = getSpatialGroup();
@@ -665,19 +691,22 @@ void LLDrawable::updateDistance(LLCamera& camera)
pos += volume->getRegion()->getOriginAgent();
}
- for (S32 i = 0; i < getNumFaces(); i++)
+ if (isState(LLDrawable::HAS_ALPHA))
{
- LLFace* facep = getFace(i);
- if (facep->getPoolType() == LLDrawPool::POOL_ALPHA)
+ for (S32 i = 0; i < getNumFaces(); i++)
{
- LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
- LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
- LLVector3 at = camera.getAtAxis();
- for (U32 j = 0; j < 3; j++)
+ LLFace* facep = getFace(i);
+ if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
{
- v.mV[j] -= box.mV[j] * at.mV[j];
+ LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
+ LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
+ const LLVector3& at = camera.getAtAxis();
+ for (U32 j = 0; j < 3; j++)
+ {
+ v.mV[j] -= box.mV[j] * at.mV[j];
+ }
+ facep->mDistance = v * camera.getAtAxis();
}
- facep->mDistance = v * camera.getAtAxis();
}
}
}
@@ -709,11 +738,7 @@ void LLDrawable::updateTexture()
if (getVOVolume())
{
- if (!isActive())
- {
- //gPipeline.markMoved(this);
- }
- else
+ if (isActive())
{
if (isRoot())
{
@@ -926,6 +951,30 @@ 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
+{
+ //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
{
@@ -934,6 +983,9 @@ BOOL LLDrawable::isVisible() const
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())
@@ -956,6 +1008,7 @@ BOOL LLDrawable::isVisible() const
}
}
else
+#endif
{
LLSpatialGroup* group = getSpatialGroup();
if (group && group->isVisible())
@@ -972,8 +1025,8 @@ BOOL LLDrawable::isVisible() const
// Spatial Partition Bridging Drawable
//=======================================
-LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask)
-: LLSpatialPartition(data_mask, FALSE)
+LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
+: LLSpatialPartition(data_mask, render_by_group, FALSE)
{
mDrawable = root;
root->setSpatialBridge(this);
@@ -984,8 +1037,16 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask)
mPartitionType = LLViewerRegion::PARTITION_VOLUME;
mOctree->balance();
+
+ llassert(mDrawable);
+ llassert(mDrawable->getRegion());
+ LLSpatialPartition *part = mDrawable->getRegion()->getSpatialPartition(mPartitionType);
+ llassert(part);
- mDrawable->getRegion()->getSpatialPartition(mPartitionType)->put(this);
+ if (part)
+ {
+ part->put(this);
+ }
}
LLSpatialBridge::~LLSpatialBridge()
@@ -1002,7 +1063,7 @@ void LLSpatialBridge::updateSpatialExtents()
LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
{
- LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND);
+ LLFastTimer ftm(FTM_CULL_REBOUND);
root->rebound();
}
@@ -1169,11 +1230,23 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
av = objparent->mDrawable;
LLSpatialGroup* group = av->getSpatialGroup();
- BOOL impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
- BOOL loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
-
+ BOOL impostor = FALSE;
+ BOOL loaded = FALSE;
+ if (objparent->isAvatar())
+ {
+ LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
+ if (avatarp->isVisible())
+ {
+ impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
+ loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
+ }
+ else
+ {
+ return;
+ }
+ }
+
if (!group ||
- av->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance ||
LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
impostor ||
!loaded)
@@ -1190,11 +1263,14 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f;
LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f;
- if (LLPipeline::sImpostorRender ||
+ 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)))
{
- if (!LLPipeline::sImpostorRender && LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA)
+ if (!LLPipeline::sImpostorRender &&
+ !LLPipeline::sShadowRender &&
+ LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA)
{
return;
}
@@ -1204,9 +1280,16 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
if (for_select)
{
results->push_back(mDrawable);
- for (U32 i = 0; i < mDrawable->getChildCount(); i++)
+ if (mDrawable->getVObj())
{
- results->push_back(mDrawable->getChild(i));
+ LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ results->push_back(drawable);
+ }
}
}
else
@@ -1218,7 +1301,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
}
-void LLSpatialBridge::updateDistance(LLCamera& camera_in)
+void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
{
if (mDrawable == NULL)
{
@@ -1226,22 +1309,40 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in)
return;
}
- LLCamera camera = transformCamera(camera_in);
-
- mDrawable->updateDistance(camera);
-
- for (U32 i = 0; i < mDrawable->getChildCount(); ++i)
+ if (mDrawable->getVObj())
{
- LLDrawable* child = mDrawable->getChild(i);
- if (!child)
+ if (mDrawable->getVObj()->isAttachment())
{
- llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl;
- continue;
+ LLDrawable* parent = mDrawable->getParent();
+ if (parent && parent->getVObj())
+ {
+ LLVOAvatar* av = parent->getVObj()->asAvatar();
+ if (av && av->isImpostor())
+ {
+ return;
+ }
+ }
}
- if (!child->isAvatar())
+ LLCamera camera = transformCamera(camera_in);
+
+ mDrawable->updateDistance(camera, force_update);
+
+ LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
{
- child->updateDistance(camera);
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if (!drawable)
+ {
+ continue;
+ }
+
+ if (!drawable->isAvatar())
+ {
+ drawable->updateDistance(camera, force_update);
+ }
}
}
}
@@ -1259,8 +1360,17 @@ void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL imm
BOOL LLSpatialBridge::updateMove()
{
+ llassert_always(mDrawable);
+ llassert_always(mDrawable->mVObjp);
+ llassert_always(mDrawable->getRegion());
+ LLSpatialPartition* part = mDrawable->getRegion()->getSpatialPartition(mPartitionType);
+ llassert_always(part);
+
mOctree->balance();
- mDrawable->getRegion()->getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE);
+ if (part)
+ {
+ part->move(this, getSpatialGroup(), TRUE);
+ }
return TRUE;
}
@@ -1277,12 +1387,18 @@ void LLSpatialBridge::cleanupReferences()
if (mDrawable)
{
mDrawable->setSpatialGroup(NULL);
- for (U32 i = 0; i < mDrawable->getChildCount(); i++)
+ if (mDrawable->getVObj())
{
- LLDrawable* drawable = mDrawable->getChild(i);
- if (drawable)
+ LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
{
- drawable->setSpatialGroup(NULL);
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if (drawable)
+ {
+ drawable->setSpatialGroup(NULL);
+ }
}
}
@@ -1332,7 +1448,10 @@ BOOL LLDrawable::isAnimating() const
{
return TRUE;
}
-
+ if (mVObjp->getPCode() == LLViewerObject::LL_VO_HUD_PART_GROUP)
+ {
+ return TRUE;
+ }
if (mVObjp->getPCode() == LLViewerObject::LL_VO_CLOUDS)
{
return TRUE;
@@ -1355,9 +1474,8 @@ void LLDrawable::updateFaceSize(S32 idx)
}
LLBridgePartition::LLBridgePartition()
-: LLSpatialPartition(0, TRUE)
+: LLSpatialPartition(0, FALSE, 0)
{
- mRenderByGroup = FALSE;
mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
mLODPeriod = 16;