summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-01-13 17:04:46 +0000
committerDave Parks <davep@lindenlab.com>2022-01-13 17:04:46 +0000
commit04edc151851b7689853069b0748af9c64e94283f (patch)
treefd400c8847e8e4837049dfb03ca3ee71e1e50189
parentac233a46d80f31ceb160654b8186d4cf6a493511 (diff)
SL-16544 Fix for rigged mesh bounding boxes
-rw-r--r--indra/newview/llcontrolavatar.cpp2
-rw-r--r--indra/newview/lldrawable.cpp11
-rw-r--r--indra/newview/lldrawable.h55
-rw-r--r--indra/newview/llspatialpartition.cpp4
-rw-r--r--indra/newview/llviewerjointattachment.cpp6
-rw-r--r--indra/newview/llvieweroctree.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp53
-rw-r--r--indra/newview/llvovolume.cpp41
-rw-r--r--indra/newview/pipeline.cpp3
9 files changed, 108 insertions, 68 deletions
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 606e670805..4a87273372 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -299,7 +299,6 @@ void LLControlAvatar::updateVolumeGeom()
mRootVolp->mDrawable->makeActive();
gPipeline.markMoved(mRootVolp->mDrawable);
gPipeline.markTextured(mRootVolp->mDrawable); // face may need to change draw pool to/from POOL_HUD
- mRootVolp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
LLViewerObject::const_child_list_t& child_list = mRootVolp->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -308,7 +307,6 @@ void LLControlAvatar::updateVolumeGeom()
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
gPipeline.markMoved(childp->mDrawable);
}
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 7c3c230cff..b274fd56b6 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -1749,6 +1749,17 @@ void LLDrawable::updateFaceSize(S32 idx)
}
}
+LLDrawable* LLDrawable::getRoot()
+{
+ LLDrawable* ret = this;
+ while (!ret->isRoot())
+ {
+ ret = ret->getParent();
+ }
+
+ return ret;
+}
+
LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
: LLSpatialPartition(0, FALSE, 0, regionp)
{
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 9a9f6cf7c2..2372ea01a6 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -121,6 +121,7 @@ public:
BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); }
BOOL isRoot() const { return !mParent || mParent->isAvatar(); }
+ LLDrawable* getRoot();
BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); }
virtual BOOL isSpatialBridge() const { return FALSE; }
virtual LLSpatialPartition* asPartition() { return NULL; }
@@ -255,38 +256,34 @@ public:
{
IN_REBUILD_Q1 = 0x00000001,
IN_REBUILD_Q2 = 0x00000002,
- IN_LIGHT_Q = 0x00000004,
- EARLY_MOVE = 0x00000008,
- MOVE_UNDAMPED = 0x00000010,
- ON_MOVE_LIST = 0x00000020,
- USE_BACKLIGHT = 0x00000040,
- UV = 0x00000080,
- UNLIT = 0x00000100,
- LIGHT = 0x00000200,
- LIGHTING_BUILT = 0x00000400,
- REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed
- REBUILD_TCOORD = 0x00001000, //texture coordinates changed
- REBUILD_COLOR = 0x00002000, //color changed
- REBUILD_POSITION= 0x00004000, //vertex positions/normals changed
+ EARLY_MOVE = 0x00000004,
+ MOVE_UNDAMPED = 0x00000008,
+ ON_MOVE_LIST = 0x00000010,
+ UV = 0x00000020,
+ UNLIT = 0x00000040,
+ LIGHT = 0x00000080,
+ REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed
+ REBUILD_TCOORD = 0x00000200, //texture coordinates changed
+ REBUILD_COLOR = 0x00000400, //color changed
+ REBUILD_POSITION= 0x00000800, //vertex positions/normals changed
REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR,
REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR,
REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME,
- REBUILD_RIGGED = 0x00008000,
- ON_SHIFT_LIST = 0x00010000,
- BLOCKER = 0x00020000,
- ACTIVE = 0x00040000,
- DEAD = 0x00080000,
- INVISIBLE = 0x00100000, // stay invisible until flag is cleared
- NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet
- BUILT = 0x00400000,
- FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
- REBUILD_SHADOW = 0x02000000,
- HAS_ALPHA = 0x04000000,
- RIGGED = 0x08000000,
- PARTITION_MOVE = 0x10000000,
- ANIMATED_CHILD = 0x20000000,
- ACTIVE_CHILD = 0x40000000,
- FOR_UNLOAD = 0x80000000, //should be unload from memory
+ REBUILD_RIGGED = 0x00001000,
+ ON_SHIFT_LIST = 0x00002000,
+ ACTIVE = 0x00004000,
+ DEAD = 0x00008000,
+ INVISIBLE = 0x00010000, // stay invisible until flag is cleared
+ NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet
+ BUILT = 0x00040000,
+ FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
+ HAS_ALPHA = 0x00100000,
+ RIGGED = 0x00200000, //has a rigged face
+ RIGGED_CHILD = 0x00400000, //has a child with a rigged face
+ PARTITION_MOVE = 0x00800000,
+ ANIMATED_CHILD = 0x01000000,
+ ACTIVE_CHILD = 0x02000000,
+ FOR_UNLOAD = 0x04000000, //should be unload from memory
} EDrawableFlags;
public:
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index c802e62e40..1869370ac7 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -218,6 +218,7 @@ void LLSpatialGroup::validateDrawMap()
BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
{
+ LL_PROFILE_ZONE_SCOPED;
drawablep->updateSpatialExtents();
OctreeNode* parent = mOctreeNode->getOctParent();
@@ -853,6 +854,7 @@ LLSpatialPartition::~LLSpatialPartition()
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
{
+ LL_PROFILE_ZONE_SCOPED;
drawablep->updateSpatialExtents();
//keep drawable from being garbage collected
@@ -878,6 +880,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!curp->removeObject(drawablep))
{
OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL;
@@ -894,6 +897,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate)
{
+ LL_PROFILE_ZONE_SCOPED;
// sanity check submitted by open source user bushing Spatula
// who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
if (!drawablep)
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 8a597ed7e6..fd314ed3dc 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -121,8 +121,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
object->mDrawable->mXform.setRotation(current_rot);
gPipeline.markMoved(object->mDrawable);
gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
- object->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
-
+
if(mIsHUDAttachment)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
@@ -142,7 +141,6 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
gPipeline.markMoved(childp->mDrawable);
@@ -256,7 +254,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
object->mDrawable->mXform.setRotation(cur_rotation);
gPipeline.markMoved(object->mDrawable, TRUE);
gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
- object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
if (mIsHUDAttachment)
{
@@ -278,7 +275,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
if (mIsHUDAttachment)
{
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 8d6f4d2729..b5bf4f0354 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -516,6 +516,7 @@ bool LLViewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry)
//virtual
void LLViewerOctreeGroup::unbound()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isDirty())
{
return;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f8506f8981..c8c85d404d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1430,7 +1430,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
continue;
}
LLDrawable* drawable = attached_object->mDrawable;
- if (drawable && !drawable->isState(LLDrawable::RIGGED))
+ if (drawable && !drawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) // <-- don't extend bounding box if any rigged objects are present
{
LLSpatialBridge* bridge = drawable->getSpatialBridge();
if (bridge)
@@ -2777,6 +2777,14 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}//if ( voiceEnabled )
}
+static void override_bbox(LLDrawable* drawable, LLVector4a* extents)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ drawable->setSpatialExtents(extents[0], extents[1]);
+ drawable->setPositionGroup(LLVector4a(0, 0, 0));
+ drawable->movePartition();
+}
+
void LLVOAvatar::idleUpdateMisc(bool detailed_update)
{
LL_PROFILE_ZONE_SCOPED;
@@ -2810,21 +2818,34 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid())
{
- // if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
- {
- gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
- }
- else
- {
- gPipeline.updateMoveDampedAsync(attached_object->mDrawable);
- }
-
- LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
- if (bridge)
- {
- gPipeline.updateMoveNormalAsync(bridge);
- }
+
+ //override rigged attachments' octree spatial extents with this avatar's bounding box
+ LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
+ bool rigged = false;
+ if (bridge)
+ {
+ //transform avatar bounding box into attachment's coordinate frame
+ LLVector4a extents[2];
+ bridge->transformExtents(mDrawable->getSpatialExtents(), extents);
+
+ if (attached_object->mDrawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD))
+ {
+ rigged = true;
+ override_bbox(attached_object->mDrawable, extents);
+ }
+ }
+
+
+ attached_object->mDrawable->makeActive();
+ attached_object->mDrawable->updateXform(TRUE);
+
+ if (!rigged)
+ {
+ if (bridge)
+ {
+ gPipeline.updateMoveNormalAsync(bridge);
+ }
+ }
attached_object->updateText();
}
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index d20bf3e871..c49ac895ca 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1667,6 +1667,7 @@ void LLVOVolume::regenFaces()
BOOL LLVOVolume::genBBoxes(BOOL force_global)
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL res = TRUE;
LLVector4a min, max;
@@ -1698,6 +1699,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
{
LL_DEBUGS("RiggedBox") << "rebuilding box, volume face count " << getVolume()->getNumVolumeFaces() << " drawable face count " << mDrawable->getNumFaces() << LL_ENDL;
}
+
// There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
for (S32 i = 0;
i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs();
@@ -1739,11 +1741,22 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
}
}
+ bool rigged = false;
+
+ if (!isAnimatedObject())
+ {
+ rigged = isRiggedMesh() && isAttachment();
+ }
+ else
+ {
+ rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying;
+ }
+
if (any_valid_boxes)
{
if (rebuild)
{
- //get the Avatar associated with this object if there is one
+ //get the Avatar associated with this object if it's rigged
LLVOAvatar* avatar = nullptr;
if (isRiggedMesh())
{
@@ -1764,30 +1777,21 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
}
}
- LLSpatialBridge* bridge = mDrawable->getSpatialBridge();
- if (avatar && bridge)
- {
- //use avatar bounding box for visibility culling
- LLDrawable* ref = avatar->mDrawable;
-
- LLVector4a extents[2];
+ mDrawable->setSpatialExtents(min, max);
- bridge->transformExtents(ref->getSpatialExtents(), extents);
-
- mDrawable->setSpatialExtents(extents[0], extents[1]);
- // don't switch octree node based on bounding box center to avoid breaking batches and rebuilding vertex buffers
- mDrawable->setPositionGroup(LLVector4a(0, 0, 0, 0));
- LL_DEBUGS("RiggedBox") << "rebuilding got extents " << extents[0] << ", " << extents[1] << LL_ENDL;
+ if (avatar)
+ {
+ // put all rigged drawables in the same octree node for better batching
+ mDrawable->setPositionGroup(LLVector4a(0, 0, 0));
}
else
{
- mDrawable->setSpatialExtents(min, max);
min.add(max);
min.mul(0.5f);
mDrawable->setPositionGroup(min);
}
}
-
+
updateRadius();
mDrawable->movePartition();
}
@@ -5844,6 +5848,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!drawablep->isState(LLDrawable::RIGGED))
{
drawablep->setState(LLDrawable::RIGGED);
+ LLDrawable* root = drawablep->getRoot();
+ if (root != drawablep)
+ {
+ root->setState(LLDrawable::RIGGED_CHILD);
+ }
//first time this is drawable is being marked as rigged,
// do another LoD update to use avatar bounding box
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 56fe4ac5af..d5f9772b85 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1876,6 +1876,7 @@ void LLPipeline::resetFrameStats()
//external functions for asynchronous updating
void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (FreezeTime)
{
return;
@@ -1906,6 +1907,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (FreezeTime)
{
return;
@@ -1936,6 +1938,7 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
{
+ LL_PROFILE_ZONE_SCOPED;
for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
iter != moved_list.end(); )
{