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 | |
| parent | e3d86e4599ee5944eaa2cfe0147d1a117495b2de (diff) | |
SL-16487 Fix for rigged attachment bounding boxes being too tight.
| -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      { | 
