summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawable.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawable.cpp786
1 files changed, 473 insertions, 313 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8106fada11..f956023358 100644..100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -35,6 +35,7 @@
#include "llcriticaldamp.h"
#include "llface.h"
#include "lllightconstants.h"
+#include "llmatrix4a.h"
#include "llsky.h"
#include "llsurfacepatch.h"
#include "llviewercamera.h"
@@ -48,13 +49,15 @@
#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;
const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f;
-const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
-static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound");
+
+extern bool gShiftFrame;
////////////////////////
@@ -72,39 +75,72 @@ static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
//
// static
-U32 LLDrawable::sCurVisible = 0;
U32 LLDrawable::sNumZombieDrawables = 0;
F32 LLDrawable::sCurPixelAngle = 0;
-LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
+std::vector<LLPointer<LLDrawable> > LLDrawable::sDeadList;
#define FORCE_INVISIBLE_AREA 16.f
// 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),
+ LLTrace::MemTrackable<LLDrawable, 16>("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;
-
- mQuietCount = 0;
-
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;
+ 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);
+ }
+
+ getRegion()->addActiveCacheEntry(vo_entry);
+
+ if(vo_entry->getNumOfChildren() > 0)
+ {
+ getRegion()->addVisibleChildCacheEntry(vo_entry, NULL); //to load all children.
+ }
+
+ llassert(!vo_entry->getGroup()); //not in the object cache octree.
+ }
+
+ llassert(!vo_entry || vo_entry->getEntry() == mEntry);
+
+ initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
// static
@@ -115,15 +151,26 @@ void LLDrawable::initClass()
void LLDrawable::destroy()
{
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
+
if (isDead())
{
sNumZombieDrawables--;
}
+ // Attempt to catch violations of this in debug,
+ // knowing that some false alarms may result
+ //
+ llassert(!LLSpatialGroup::sNoDelete);
+
+ /* cannot be guaranteed and causes crashes on false alarms
if (LLSpatialGroup::sNoDelete)
{
- llerrs << "Illegal deletion of LLDrawable!" << llendl;
- }
+ LL_ERRS() << "Illegal deletion of LLDrawable!" << LL_ENDL;
+ }*/
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@@ -131,17 +178,19 @@ void LLDrawable::destroy()
/*if (!(sNumZombieDrawables % 10))
{
- llinfos << "- Zombie drawables: " << sNumZombieDrawables << llendl;
+ LL_INFOS() << "- Zombie drawables: " << sNumZombieDrawables << LL_ENDL;
}*/
+
}
void LLDrawable::markDead()
{
if (isDead())
{
- llwarns << "Warning! Marking dead multiple times!" << llendl;
+ LL_WARNS() << "Warning! Marking dead multiple times!" << LL_ENDL;
return;
}
+ setState(DEAD);
if (mSpatialBridge)
{
@@ -152,9 +201,8 @@ void LLDrawable::markDead()
sNumZombieDrawables++;
// We're dead. Free up all of our references to other objects
- setState(DEAD);
cleanupReferences();
-// sDeadList.put(this);
+// sDeadList.push_back(this);
}
LLVOVolume* LLDrawable::getVOVolume() const
@@ -170,6 +218,11 @@ LLVOVolume* LLDrawable::getVOVolume() const
}
}
+const LLMatrix4& LLDrawable::getRenderMatrix() const
+{
+ return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix();
+}
+
BOOL LLDrawable::isLight() const
{
LLViewerObject* objectp = mVObjp;
@@ -183,36 +236,63 @@ BOOL LLDrawable::isLight() const
}
}
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLE("Cleanup Drawable");
+static LLTrace::BlockTimerStatHandle FTM_DEREF_DRAWABLE("Deref");
+static LLTrace::BlockTimerStatHandle FTM_DELETE_FACES("Faces");
+
void LLDrawable::cleanupReferences()
{
- LLFastTimer t(FTM_PIPELINE);
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLE);
- std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
- mFaces.clear();
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DELETE_FACES);
+ std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
+ mFaces.clear();
+ }
gObjectList.removeDrawable(this);
gPipeline.unlinkDrawable(this);
- // Cleanup references to other objects
- mVObjp = NULL;
- mParent = NULL;
+ removeFromOctree();
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DEREF_DRAWABLE);
+ // Cleanup references to other objects
+ mVObjp = NULL;
+ mParent = NULL;
+ }
+}
+
+void LLDrawable::removeFromOctree()
+{
+ if(!mEntry)
+ {
+ return;
+ }
+
+ mEntry->removeData(this);
+ if(mEntry->hasVOCacheEntry())
+ {
+ getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this);
+ }
+ mEntry = NULL;
}
void LLDrawable::cleanupDeadDrawables()
{
/*
S32 i;
- for (i = 0; i < sDeadList.count(); i++)
+ for (i = 0; i < sDeadList.size(); i++)
{
if (sDeadList[i]->getNumRefs() > 1)
{
- llwarns << "Dead drawable has " << sDeadList[i]->getNumRefs() << " remaining refs" << llendl;
+ LL_WARNS() << "Dead drawable has " << sDeadList[i]->getNumRefs() << " remaining refs" << LL_ENDL;
gPipeline.findReferences(sDeadList[i]);
}
}
*/
- sDeadList.reset();
+ sDeadList.clear();
}
S32 LLDrawable::findReferences(LLDrawable *drawablep)
@@ -220,18 +300,24 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
S32 count = 0;
if (mParent == drawablep)
{
- llinfos << this << ": parent reference" << llendl;
+ LL_INFOS() << this << ": parent reference" << LL_ENDL;
count++;
}
return count;
}
+static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face");
+
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
- LLFace *face = new LLFace(this, mVObjp);
- if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl;
+ LLFace *face;
+ {
+ LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE);
+ face = new LLFace(this, mVObjp);
+ }
+
+ if (!face) LL_ERRS() << "Allocating new Face: " << mFaces.size() << LL_ENDL;
if (face)
{
@@ -252,10 +338,12 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
-
LLFace *face;
- face = new LLFace(this, mVObjp);
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE);
+ face = new LLFace(this, mVObjp);
+ }
face->setTEOffset(mFaces.size());
face->setTexture(texturep);
@@ -272,6 +360,49 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
}
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setSpecularMap(specularp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
@@ -343,7 +474,7 @@ void LLDrawable::deleteFaces(S32 offset, S32 count)
void LLDrawable::update()
{
- llerrs << "Shouldn't be called!" << llendl;
+ LL_ERRS() << "Shouldn't be called!" << LL_ENDL;
}
@@ -362,11 +493,10 @@ void LLDrawable::makeActive()
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)
{
- llerrs << "Static viewer object has active drawable!" << llendl;
+ LL_ERRS() << "Static viewer object has active drawable!" << LL_ENDL;
}
}
#endif
@@ -379,6 +509,8 @@ void LLDrawable::makeActive()
if (!isRoot() && !mParent->isActive())
{
mParent->makeActive();
+ //NOTE: linked set will now NEVER become static
+ mParent->setState(LLDrawable::ACTIVE_CHILD);
}
//all child objects must also be active
@@ -398,40 +530,32 @@ void LLDrawable::makeActive()
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
{
- if (mVObjp->isFlexible())
- {
- return;
- }
- }
-
- if (mVObjp->getPCode() == LL_PCODE_VOLUME)
- {
gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
}
updatePartition();
}
-
- if (isRoot())
- {
- mQuietCount = 0;
- }
- else
+ else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does...
{
- getParent()->mQuietCount = 0;
+ mParent->makeActive();
+ //NOTE: linked set will now NEVER become static
+ mParent->setState(LLDrawable::ACTIVE_CHILD);
}
+
+ llassert(isAvatar() || isRoot() || mParent->isActive());
}
void LLDrawable::makeStatic(BOOL warning_enabled)
{
- if (isState(ACTIVE))
+ if (isState(ACTIVE) &&
+ !isState(ACTIVE_CHILD) &&
+ !mVObjp->isAttachment() &&
+ !mVObjp->isFlexible())
{
- clearState(ACTIVE);
+ clearState(ACTIVE | ANIMATED_CHILD);
- if (mParent.notNull() && mParent->isActive() && warning_enabled)
- {
- LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
- }
+ //drawable became static with active parent, not acceptable
+ llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled);
LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -443,7 +567,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
{
if (child_drawable->getParent() != this)
{
- llwarns << "Child drawable has unknown parent." << llendl;
+ LL_WARNS() << "Child drawable has unknown parent." << LL_ENDL;
}
child_drawable->makeStatic(warning_enabled);
}
@@ -459,8 +583,10 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
mSpatialBridge->markDead();
setSpatialBridge(NULL);
}
+ updatePartition();
}
- updatePartition();
+
+ llassert(isAvatar() || isRoot() || mParent->isStatic());
}
// Returns "distance" between target destination and resulting xfrom
@@ -488,7 +614,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
//scaling
LLVector3 target_scale = mVObjp->getScale();
LLVector3 old_scale = mCurrentScale;
- LLVector3 dest_scale = target_scale;
// Damping
F32 dist_squared = 0.f;
@@ -496,11 +621,12 @@ 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);
LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot);
+ // FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes.
dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f;
LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt);
@@ -514,9 +640,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
target_rot = new_rot;
target_scale = new_scale;
}
- else
+ else if (mVObjp->getAngularVelocity().isExactlyZero())
{
- // snap to final position
+ // snap to final position (only if no target omega is applied)
dist_squared = 0.0f;
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
@@ -524,16 +650,41 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
}
}
+ else
+ {
+ // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275
+ // dist_squared = dist_vec_squared(old_pos, target_pos);
- if ((mCurrentScale != target_scale) ||
- (!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
+ // The following fixes MAINT-2247 but causes MAINT-2275
+ //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f;
+ //dist_squared += dist_vec_squared(old_scale, target_scale);
+ }
+
+ LLVector3 vec = mCurrentScale-target_scale;
+
+ if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
+ { //scale change requires immediate rebuild
+ mCurrentScale = target_scale;
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
+ else if (!isRoot() &&
+ (!mVObjp->getAngularVelocity().isExactlyZero() ||
+ dist_squared > 0.f))
+ { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild
+ dist_squared = 1.f; //keep this object on the move list
+ if (!isState(LLDrawable::ANIMATED_CHILD))
+ {
+ setState(LLDrawable::ANIMATED_CHILD);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+ mVObjp->dirtySpatialGroup();
+ }
+ }
+ else if (!isRoot() &&
+ ((dist_vec_squared(old_pos, target_pos) > 0.f)
+ || (1.f - dot(old_rot, target_rot)) > 0.f))
+ { //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ }
else if (!getVOVolume() && !isAvatar())
{
movePartition();
@@ -544,9 +695,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
mXform.setRotation(target_rot);
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
-
- mCurrentScale = target_scale;
-
+
if (mSpatialBridge)
{
gPipeline.markMoved(mSpatialBridge, FALSE);
@@ -564,12 +713,19 @@ 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++)
{
- getFace(i)->updateCenterAgent();
+ LLFace* face = getFace(i);
+ if (face)
+ {
+ face->updateCenterAgent();
+ }
}
}
@@ -586,7 +742,7 @@ BOOL LLDrawable::updateMove()
{
if (isDead())
{
- llwarns << "Update move on dead drawable!" << llendl;
+ LL_WARNS() << "Update move on dead drawable!" << LL_ENDL;
return TRUE;
}
@@ -596,18 +752,8 @@ BOOL LLDrawable::updateMove()
}
makeActive();
-
- BOOL done;
- if (isState(MOVE_UNDAMPED))
- {
- done = updateMoveUndamped();
- }
- else
- {
- done = updateMoveDamped();
- }
- return done;
+ return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped();
}
BOOL LLDrawable::updateMoveUndamped()
@@ -624,7 +770,6 @@ BOOL LLDrawable::updateMoveUndamped()
}
mVObjp->clearChanged(LLXform::MOVED);
-
return TRUE;
}
@@ -672,7 +817,13 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
{
- llerrs << "WTF?" << llendl;
+ LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL;
+ return;
+ }
+
+ if (gShiftFrame)
+ {
+ return;
}
//switch LOD with the spatial group to avoid artifacts
@@ -685,50 +836,53 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVOVolume* volume = getVOVolume();
if (volume)
{
- volume->updateRelativeXform();
- pos = volume->getRelativeXform().getTranslation();
- if (isStatic())
+ if (getGroup())
{
- pos += volume->getRegion()->getOriginAgent();
+ pos.set(getPositionGroup().getF32ptr());
}
-
+ else
+ {
+ pos = getPositionAgent();
+ }
+
if (isState(LLDrawable::HAS_ALPHA))
{
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace* facep = getFace(i);
- if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
+ if (facep &&
+ (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
{
- LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
+ LLVector4a box;
+ box.setSub(facep->mExtents[1], facep->mExtents[0]);
+ box.mul(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];
+ v.mV[j] -= box[j] * at.mV[j];
}
facep->mDistance = v * camera.getAtAxis();
}
}
- }
+ }
}
else
{
- pos = LLVector3(getPositionGroup());
+ pos = LLVector3(getPositionGroup().getF32ptr());
}
pos -= camera.getOrigin();
- mDistanceWRTCamera = llround(pos.magVec(), 0.01f);
+ mDistanceWRTCamera = ll_round(pos.magVec(), 0.01f);
mVObjp->updateLOD();
}
}
void LLDrawable::updateTexture()
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
-
if (isDead())
{
- llwarns << "Dead drawable updating texture!" << llendl;
+ LL_WARNS() << "Dead drawable updating texture!" << LL_ENDL;
return;
}
@@ -739,18 +893,6 @@ void LLDrawable::updateTexture()
if (getVOVolume())
{
- if (isActive())
- {
- if (isRoot())
- {
- mQuietCount = 0;
- }
- else
- {
- getParent()->mQuietCount = 0;
- }
- }
-
gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE);
}
}
@@ -762,11 +904,11 @@ BOOL LLDrawable::updateGeometry(BOOL priority)
return res;
}
-void LLDrawable::shiftPos(const LLVector3 &shift_vector)
+void LLDrawable::shiftPos(const LLVector4a &shift_vector)
{
if (isDead())
{
- llwarns << "Shifting dead drawable" << llendl;
+ LL_WARNS() << "Shifting dead drawable" << LL_ENDL;
return;
}
@@ -779,14 +921,19 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
mXform.setPosition(mVObjp->getPositionAgent());
}
- mXform.setRotation(mVObjp->getRotation());
- mXform.setScale(1,1,1);
mXform.updateMatrix();
if (isStatic())
{
LLVOVolume* volume = getVOVolume();
- if (!volume)
+
+ bool rebuild = (!volume &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TREE &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN &&
+ getRenderType() != LLPipeline::RENDER_TYPE_SKY &&
+ getRenderType() != LLPipeline::RENDER_TYPE_GROUND);
+
+ if (rebuild)
{
gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
}
@@ -794,20 +941,20 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace *facep = getFace(i);
- facep->mCenterAgent += shift_vector;
- facep->mExtents[0] += shift_vector;
- facep->mExtents[1] += shift_vector;
-
- if (!volume && facep->hasGeometry())
+ if (facep)
{
- facep->mVertexBuffer = NULL;
- facep->mLastVertexBuffer = NULL;
+ facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
+ facep->mExtents[0].add(shift_vector);
+ facep->mExtents[1].add(shift_vector);
+
+ if (rebuild && facep->hasGeometry())
+ {
+ facep->clearVertexBuffer();
+ }
}
}
- mExtents[0] += shift_vector;
- mExtents[1] += shift_vector;
- mPositionGroup += LLVector3d(shift_vector);
+ shift(shift_vector);
}
else if (mSpatialBridge)
{
@@ -815,9 +962,7 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
}
else if (isAvatar())
{
- mExtents[0] += shift_vector;
- mExtents[1] += shift_vector;
- mPositionGroup += LLVector3d(shift_vector);
+ shift(shift_vector);
}
mVObjp->onShift(shift_vector);
@@ -829,35 +974,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
return mXform.getPositionW();
}
-const LLVector3* LLDrawable::getSpatialExtents() const
-{
- return mExtents;
-}
-
-void LLDrawable::setSpatialExtents(LLVector3 min, LLVector3 max)
-{
- LLVector3 size = max - min;
- mExtents[0] = min;
- mExtents[1] = max;
-}
-
-void LLDrawable::setPositionGroup(const LLVector3d& pos)
-{
- mPositionGroup.setVec(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.setVec(0,0,0);
+ getGroupPosition().splat(0.f);
}
}
@@ -866,11 +1000,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));
}
}
@@ -894,7 +1028,7 @@ F32 LLDrawable::getVisibilityRadius() const
{
return llmax(getRadius(), vov->getLightRadius());
} else {
- // llwarns ?
+ // LL_WARNS() ?
}
}
return getRadius();
@@ -904,13 +1038,71 @@ void LLDrawable::updateUVMinMax()
{
}
-void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
+//virtual
+bool LLDrawable::isVisible() const
{
-/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
+ if (LLViewerOctreeEntryData::isVisible())
+{
+ return true;
+}
+
+{
+ LLViewerOctreeGroup* group = mEntry->getGroup();
+ if (group && group->isVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//virtual
+bool LLDrawable::isRecentlyVisible() const
+{
+ //currently visible or visible in the previous frame.
+ bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
+
+ if(!vis)
{
- mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
- }*/
- mSpatialGroupp = groupp;
+ const U32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
+ vis = (sCurVisible - getVisible() < MIN_VIS_FRAME_RANGE);
+ }
+
+ 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 (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
+ for (S32 i = 0; i < getNumFaces(); ++i)
+ {
+ LLFace* facep = getFace(i);
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+ }
+
+ //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 ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) :
+ // (getEntry() && getEntry()->getBinIndex() != -1));
+
+ LLViewerOctreeEntryData::setGroup(groupp);
}
LLSpatialPartition* LLDrawable::getSpatialPartition()
@@ -924,16 +1116,23 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
retval = gPipeline.getSpatialPartition((LLViewerObject*) mVObjp);
}
else if (isRoot())
- { //must be an active volume
+ {
+ if (mSpatialBridge && (mSpatialBridge->asPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) != mVObjp->isHUDAttachment())
+ {
+ // remove obsolete bridge
+ mSpatialBridge->markDead();
+ setSpatialBridge(NULL);
+ }
+ //must be an active volume
if (!mSpatialBridge)
{
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();
@@ -952,83 +1151,15 @@ 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
-{
- 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;
- }
- }
-
- return FALSE;
-}
-
//=======================================
// Spatial Partition Bridging Drawable
//=======================================
-LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
-: LLSpatialPartition(data_mask, render_by_group, FALSE)
+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);
@@ -1052,11 +1183,23 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLSpatialBridge::~LLSpatialBridge()
{
+ if(mEntry)
+ {
LLSpatialGroup* group = getSpatialGroup();
if (group)
{
- group->mSpatialPartition->remove(this, group);
+ group->getSpatialPartition()->remove(this, group);
}
+ }
+
+ //delete octree here so listeners will still be able to access bridge specific state
+ destroyTree();
+}
+
+void LLSpatialBridge::destroyTree()
+{
+ delete mOctree;
+ mOctree = NULL;
}
void LLSpatialBridge::updateSpatialExtents()
@@ -1064,63 +1207,76 @@ void LLSpatialBridge::updateSpatialExtents()
LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
{
- LLFastTimer ftm(FTM_CULL_REBOUND);
+ LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND);
root->rebound();
}
- LLXformMatrix* mat = mDrawable->getXform();
-
- LLVector3 offset = root->mBounds[0];
- LLVector3 size = root->mBounds[1];
+ const LLVector4a* root_bounds = root->getBounds();
+ LLVector4a offset;
+ LLVector4a size = root_bounds[1];
- LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
- LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
+ //VECTORIZE THIS
+ LLMatrix4a mat;
+ mat.loadu(mDrawable->getXform()->getWorldMatrix());
+
+ LLVector4a t;
+ t.splat(0.f);
+
+ LLVector4a center;
+ mat.affineTransform(t, center);
- offset *= rotation;
- center += offset;
+ mat.rotate(root_bounds[0], offset);
+ center.add(offset);
- LLVector3 v[4];
+ LLVector4a v[4];
+
//get 4 corners of bounding box
- v[0] = (size * rotation);
- v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation);
- v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation);
- v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation);
+ mat.rotate(size,v[0]);
- LLVector3& newMin = mExtents[0];
- LLVector3& newMax = mExtents[1];
+ LLVector4a scale;
- newMin = newMax = center;
+ scale.set(-1.f, -1.f, 1.f);
+ scale.mul(size);
+ mat.rotate(scale, v[1]);
+ scale.set(1.f, -1.f, -1.f);
+ scale.mul(size);
+ mat.rotate(scale, v[2]);
+
+ scale.set(-1.f, 1.f, -1.f);
+ scale.mul(size);
+ mat.rotate(scale, v[3]);
+
+ LLVector4a newMin;
+ LLVector4a newMax;
+ newMin = newMax = center;
for (U32 i = 0; i < 4; i++)
{
- for (U32 j = 0; j < 3; j++)
- {
- F32 delta = fabsf(v[i].mV[j]);
- F32 min = center.mV[j] - delta;
- F32 max = center.mV[j] + delta;
-
- if (min < newMin.mV[j])
- {
- newMin.mV[j] = min;
- }
-
- if (max > newMax.mV[j])
- {
- newMax.mV[j] = max;
- }
- }
- }
+ LLVector4a delta;
+ delta.setAbs(v[i]);
+ LLVector4a min;
+ min.setSub(center, delta);
+ LLVector4a max;
+ max.setAdd(center, delta);
- LLVector3 diagonal = newMax - newMin;
- mRadius = diagonal.magVec() * 0.5f;
+ newMin.setMin(newMin, min);
+ newMax.setMax(newMax, max);
+ }
+ setSpatialExtents(newMin, newMax);
+
+ LLVector4a diagonal;
+ diagonal.setSub(newMax, newMin);
+ mRadius = diagonal.getLength3().getF32() * 0.5f;
- mPositionGroup.setVec((newMin + newMax) * 0.5f);
+ LLVector4a& pos = getGroupPosition();
+ pos.setAdd(newMin,newMax);
+ pos.mul(0.5f);
updateBinRadius();
}
void LLSpatialBridge::updateBinRadius()
{
- mBinRadius = llmin((F32) mOctree->getSize().mdV[0]*0.5f, 256.f);
+ setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));
}
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
@@ -1128,7 +1284,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
LLCamera ret = camera;
LLXformMatrix* mat = mDrawable->getXform();
LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
- LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
LLVector3 delta = ret.getOrigin() - center;
LLQuaternion rot = ~mat->getRotation();
@@ -1155,7 +1310,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
@@ -1165,46 +1320,46 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,
{
if (isActive() && !mParent->isActive())
{
- llerrs << "Active drawable has static parent!" << llendl;
+ LL_ERRS() << "Active drawable has static parent!" << LL_ENDL;
}
if (isStatic() && !mParent->isStatic())
{
- llerrs << "Static drawable has active parent!" << llendl;
+ LL_ERRS() << "Static drawable has active parent!" << LL_ENDL;
}
if (mSpatialBridge)
{
- llerrs << "Child drawable has spatial bridge!" << llendl;
+ LL_ERRS() << "Child drawable has spatial bridge!" << LL_ENDL;
}
}
else if (isActive() && !mSpatialBridge)
{
- llerrs << "Active root drawable has no spatial bridge!" << llendl;
+ LL_ERRS() << "Active root drawable has no spatial bridge!" << LL_ENDL;
}
else if (isStatic() && mSpatialBridge.notNull())
{
- llerrs << "Static drawable has spatial bridge!" << llendl;
+ LL_ERRS() << "Static drawable has spatial bridge!" << LL_ENDL;
}
}
#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);
}
@@ -1248,7 +1403,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
if (!group ||
- LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
+ LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
impostor ||
!loaded)
{
@@ -1261,13 +1416,18 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
group->rebound();
- LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f;
- LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f;
+ LLVector4a center;
+ const LLVector4a* exts = getSpatialExtents();
+ center.setAdd(exts[0], exts[1]);
+ center.mul(0.5f);
+ LLVector4a size;
+ 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 &&
@@ -1310,6 +1470,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
if (mDrawable->getVObj())
{
if (mDrawable->getVObj()->isAttachment())
@@ -1350,7 +1515,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
void LLSpatialBridge::makeActive()
{ //it is an error to make a spatial bridge active (it's already active)
- llerrs << "makeActive called on spatial bridge" << llendl;
+ LL_ERRS() << "makeActive called on spatial bridge" << LL_ENDL;
}
void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate)
@@ -1375,11 +1540,9 @@ BOOL LLSpatialBridge::updateMove()
return TRUE;
}
-void LLSpatialBridge::shiftPos(const LLVector3& vec)
+void LLSpatialBridge::shiftPos(const LLVector4a& vec)
{
- mExtents[0] += vec;
- mExtents[1] += vec;
- mPositionGroup += LLVector3d(vec);
+ LLDrawable::shift(vec);
}
void LLSpatialBridge::cleanupReferences()
@@ -1387,7 +1550,8 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
- mDrawable->setSpatialGroup(NULL);
+ mDrawable->setGroup(NULL);
+
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1398,10 +1562,10 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
- drawable->setSpatialGroup(NULL);
+ drawable->setGroup(NULL);
+ }
}
}
- }
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1453,15 +1617,11 @@ BOOL LLDrawable::isAnimating() const
{
return TRUE;
}
- if (mVObjp->getPCode() == LLViewerObject::LL_VO_CLOUDS)
- {
- return TRUE;
- }
- if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
- {
+ /*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
+ { //target omega
return TRUE;
- }
+ }*/
return FALSE;
}
@@ -1474,8 +1634,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;
@@ -1483,8 +1643,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;
@@ -1497,7 +1657,7 @@ F32 LLHUDBridge::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
}
-void LLHUDBridge::shiftPos(const LLVector3& vec)
+void LLHUDBridge::shiftPos(const LLVector4a& vec)
{
//don't shift hud bridges on region crossing
}