diff options
author | Runitai Linden <davep@lindenlab.com> | 2021-12-15 13:43:58 -0600 |
---|---|---|
committer | Runitai Linden <davep@lindenlab.com> | 2021-12-15 13:43:58 -0600 |
commit | 8bf5597db2f10c4a423af5df333ff0f1c7fd9c99 (patch) | |
tree | 6157de427adaacac7f68e1ec86aa2578e184f4f5 /indra/newview | |
parent | e3d86e4599ee5944eaa2cfe0147d1a117495b2de (diff) |
SL-16487 Fix for rigged attachment bounding boxes being too tight.
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lldrawable.cpp | 39 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 11 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 151 |
4 files changed, 121 insertions, 82 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 7e99b99284..7c3c230cff 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1162,21 +1162,26 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) LLViewerOctreeEntryData::setGroup(groupp); } +/* +* Get the SpatialPartition this Drawable should use. +* Checks current SpatialPartition assignment and corrects if it is invalid. +*/ LLSpatialPartition* LLDrawable::getSpatialPartition() { LL_PROFILE_ZONE_SCOPED LLSpatialPartition* retval = NULL; - + if (!mVObjp || !getVOVolume() || isStatic()) { - retval = gPipeline.getSpatialPartition((LLViewerObject*) mVObjp); + retval = gPipeline.getSpatialPartition((LLViewerObject*)mVObjp); } else if (isRoot()) { - if (mSpatialBridge) + // determine if the spatial bridge has changed + if (mSpatialBridge) { U32 partition_type = mSpatialBridge->asPartition()->mPartitionType; bool is_hud = mVObjp->isHUDAttachment(); @@ -1193,14 +1198,14 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { // Was/became part of animesh // remove obsolete bridge - mSpatialBridge->markDead(); + mSpatialBridge->markDead(); setSpatialBridge(NULL); } else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment) { // Was/became part of avatar // remove obsolete bridge - mSpatialBridge->markDead(); + mSpatialBridge->markDead(); setSpatialBridge(NULL); } } @@ -1211,17 +1216,20 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { setSpatialBridge(new LLHUDBridge(this, getRegion())); } - else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) - { - setSpatialBridge(new LLControlAVBridge(this, getRegion())); - } + else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) + { + setSpatialBridge(new LLControlAVBridge(this, getRegion())); + } // check HUD first, because HUD is also attachment else if (mVObjp->isAttachment()) { + // Attachment + // Use AvatarBridge of root object in attachment linkset setSpatialBridge(new LLAvatarBridge(this, getRegion())); } else { + // Moving linkset, use VolumeBridge of root object in linkset setSpatialBridge(new LLVolumeBridge(this, getRegion())); } } @@ -1395,10 +1403,21 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) ret.setOrigin(delta); ret.setAxes(lookAt, left_axis, up_axis); - + return ret; } +void LLSpatialBridge::transformExtents(const LLVector4a* src, LLVector4a* dst) +{ + LLMatrix4 mat = mDrawable->getXform()->getWorldMatrix(); + mat.invert(); + + LLMatrix4a world_to_bridge(mat); + + matMulBoundBox(world_to_bridge, src, dst); +} + + void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select) { LLViewerOctreeEntryData::setVisible(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8e4e008738..db274aa5ad 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9426,7 +9426,7 @@ LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te) } -const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin, LLVOVolume* requesting_obj) +const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin) { U64 hash = skin->mHash; MatrixPaletteCache& entry = mMatrixPaletteCache[hash]; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index b85400866e..ab2a2daf49 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -55,7 +55,6 @@ #include "llavatarrendernotifier.h" #include "llmodel.h" - extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; extern const LLUUID ANIM_AGENT_PHYSICS_MOTION; @@ -749,10 +748,14 @@ public: void updateMeshVisibility(); LLViewerTexture* getBakedTexture(const U8 te); + // Matrix palette cache entry class alignas(16) MatrixPaletteCache { public: + // Last frame this entry was updated U32 mFrame; + + // List of Matrix4a's for this entry LLMeshSkinInfo::matrix_list_t mMatrixPalette; // Float array ready to be sent to GL @@ -764,8 +767,12 @@ public: } }; - const MatrixPaletteCache& updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skinInfo, LLVOVolume* requesting_obj = nullptr); + // Accessor for Matrix Palette Cache + // Will do a map lookup for the entry associated with the given MeshSkinInfo + // Will update said entry if it hasn't been updated yet this frame + const MatrixPaletteCache& updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skinInfo); + // Map of LLMeshSkinInfo::mHash to MatrixPaletteCache typedef std::unordered_map<U64, MatrixPaletteCache> matrix_palette_cache_t; matrix_palette_cache_t mMatrixPaletteCache; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c312ebb307..a4f217bbcb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1667,15 +1667,14 @@ void LLVOVolume::regenFaces() BOOL LLVOVolume::genBBoxes(BOOL force_global) { - LL_PROFILE_ZONE_SCOPED; - BOOL res = TRUE; + BOOL res = TRUE; - LLVector4a min,max; + LLVector4a min, max; - min.clear(); - max.clear(); + min.clear(); + max.clear(); - BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); + BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); if (getRiggedVolume()) { @@ -1686,93 +1685,107 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) // Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about. updateRiggedVolume(); } - - LLVolume* volume = mRiggedVolume; - if (!volume) - { - volume = getVolume(); - } + + LLVolume* volume = mRiggedVolume; + if (!volume) + { + volume = getVolume(); + } bool any_valid_boxes = false; - + if (getRiggedVolume()) { 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(); - i++) - { - LLFace *face = mDrawable->getFace(i); - if (!face) - { - continue; - } + for (S32 i = 0; + i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs(); + i++) + { + LLFace* face = mDrawable->getFace(i); + if (!face) + { + continue; + } BOOL face_res = face->genVolumeBBoxes(*volume, i, - mRelativeXform, - (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); + mRelativeXform, + (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); res &= face_res; // note that this result is never used - + // MAINT-8264 - ignore bboxes of ill-formed faces. if (!face_res) { continue; } - if (rebuild) - { + if (rebuild) + { if (getRiggedVolume()) { LL_DEBUGS("RiggedBox") << "rebuilding box, face " << i << " extents " << face->mExtents[0] << ", " << face->mExtents[1] << LL_ENDL; } - if (!any_valid_boxes) - { - min = face->mExtents[0]; - max = face->mExtents[1]; + if (!any_valid_boxes) + { + min = face->mExtents[0]; + max = face->mExtents[1]; any_valid_boxes = true; - } - else - { - min.setMin(min, face->mExtents[0]); - max.setMax(max, face->mExtents[1]); - } - } - } - - bool rigged = false; - - if (!isAnimatedObject()) - { - rigged = isRiggedMesh() && isAttachment(); - } - else - { - rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying; + } + else + { + min.setMin(min, face->mExtents[0]); + max.setMax(max, face->mExtents[1]); + } + } } - if (rigged) - { - mDrawable->setSpatialExtents(min, max); - // always use the same octree node position for any given rigged mesh so it doesn't switch nodes - // while animating (and thus rebuild its vertex buffer) - mDrawable->setPositionGroup(LLVector4a(0, 0, 0)); - updateRadius(); - mDrawable->movePartition(); - } - else if (any_valid_boxes) + if (any_valid_boxes) { if (rebuild) { - if (getRiggedVolume()) + //get the Avatar associated with this object if there is one + LLVOAvatar* avatar = nullptr; + if (isRiggedMesh()) { - LL_DEBUGS("RiggedBox") << "rebuilding got extents " << min << ", " << max << LL_ENDL; + if (!isAnimatedObject()) + { + if (isAttachment()) + { + avatar = getAvatar(); + } + } + else + { + LLControlAvatar* controlAvatar = getControlAvatar(); + if (controlAvatar && controlAvatar->mPlaying) + { + avatar = controlAvatar; + } + } + } + + LLSpatialBridge* bridge = mDrawable->getSpatialBridge(); + if (avatar && bridge) + { + //use avatar bounding box for visibility culling + LLDrawable* ref = avatar->mDrawable; + + LLVector4a extents[2]; + + 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; + } + else + { + mDrawable->setSpatialExtents(min, max); + min.add(max); + min.mul(0.5f); + mDrawable->setPositionGroup(min); } - mDrawable->setSpatialExtents(min,max); - min.add(max); - min.mul(0.5f); - mDrawable->setPositionGroup(min); } updateRadius(); @@ -1782,8 +1795,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { LL_DEBUGS("RiggedBox") << "genBBoxes failed to find any valid face boxes" << LL_ENDL; } - - return res; + + return res; } void LLVOVolume::preRebuild() @@ -4817,7 +4830,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (copy) { - copyVolumeFaces(volume); + copyVolumeFaces(volume); } else { |