diff options
author | Dave Parks <davep@lindenlab.com> | 2022-01-13 17:04:46 +0000 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-01-13 17:04:46 +0000 |
commit | 04edc151851b7689853069b0748af9c64e94283f (patch) | |
tree | fd400c8847e8e4837049dfb03ca3ee71e1e50189 | |
parent | ac233a46d80f31ceb160654b8186d4cf6a493511 (diff) |
SL-16544 Fix for rigged mesh bounding boxes
-rw-r--r-- | indra/newview/llcontrolavatar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/lldrawable.cpp | 11 | ||||
-rw-r--r-- | indra/newview/lldrawable.h | 55 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llviewerjointattachment.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 53 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 41 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 3 |
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(); ) { |