summaryrefslogtreecommitdiff
path: root/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-06-06 19:57:03 -0500
committerDave Parks <davep@lindenlab.com>2022-06-06 19:57:03 -0500
commit616f2b639bc6907e810664522304305337646292 (patch)
tree29c98de959f080d07784687a838e01b5280cd17a /indra/newview/llvovolume.cpp
parent0fe8493b5a531bb0fbc431f54ee25f8e2923b5bf (diff)
SL-17532 Potential fix for some rigged mesh draw order issues.
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r--indra/newview/llvovolume.cpp51
1 files changed, 44 insertions, 7 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 126a25115d..eb1e2cbd80 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5480,7 +5480,7 @@ static inline void add_face(T*** list, U32* count, T* face)
{
if (count[1] < MAX_FACE_COUNT)
{
- face->setDrawOrderIndex(count[1]);
+ //face->setDrawOrderIndex(count[1]);
list[1][count[1]++] = face;
}
}
@@ -5488,15 +5488,40 @@ static inline void add_face(T*** list, U32* count, T* face)
{
if (count[0] < MAX_FACE_COUNT)
{
- face->setDrawOrderIndex(count[0]);
+ //face->setDrawOrderIndex(count[0]);
list[0][count[0]++] = face;
}
}
}
+// return index into linkset for given object (0 for root prim)
+U32 get_linkset_index(LLVOVolume* vobj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
+ if (vobj->isRootEdit())
+ {
+ return 0;
+ }
+
+ LLViewerObject* root = vobj->getRootEdit();
+ U32 idx = 1;
+ for (auto& child : root->getChildren())
+ {
+ if (child == vobj)
+ {
+ return idx;
+ }
+ ++idx;
+ }
+
+ llassert(false);
+ return idx; //should never get here
+}
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5655,6 +5680,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
+ U32 linkset_index = get_linkset_index(vobj);
+
// Standard rigged mesh attachments:
bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
@@ -5674,6 +5701,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // order by linkset index first and face index second
+ facep->setDrawOrderIndex(linkset_index * 100 + i);
+
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
// batch, it will recover its vertex buffer reference from the spatial group
facep->setVertexBuffer(NULL);
@@ -5698,11 +5728,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->isState(LLFace::RIGGED))
{
//face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeFace(facep);
- }
facep->clearState(LLFace::RIGGED);
facep->mAvatar = NULL;
facep->mSkinInfo = NULL;
@@ -6158,6 +6183,13 @@ struct CompareBatchBreakerRigged
}
};
+struct CompareDrawOrder
+{
+ bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
+ {
+ return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex();
+ }
+};
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
@@ -6202,6 +6234,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//sort faces by things that break batches, including avatar and mesh id
std::sort(faces, faces + face_count, CompareBatchBreakerRigged());
}
+ else
+ {
+ // preserve legacy draw order for rigged faces
+ std::sort(faces, faces + face_count, CompareDrawOrder());
+ }
}
else if (!distance_sort)
{