summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/lldrawable.cpp39
-rw-r--r--indra/newview/llvoavatar.cpp2
-rw-r--r--indra/newview/llvoavatar.h11
-rw-r--r--indra/newview/llvovolume.cpp151
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
{