@@ -293,8 +293,9 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
293
293
return ;
294
294
}
295
295
296
- mat_list_t ::iterator end = mGLTFMaterialWithLocalTextures .end ();
297
- for (mat_list_t ::iterator it = mGLTFMaterialWithLocalTextures .begin (); it != end;)
296
+ mat->addLocalTextureTracking (getTrackingID (), getWorldID ());
297
+
298
+ for (mat_list_t ::iterator it = mGLTFMaterialWithLocalTextures .begin (); it != mGLTFMaterialWithLocalTextures .end ();)
298
299
{
299
300
if (it->get () == mat)
300
301
{
@@ -304,15 +305,12 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
304
305
if ((*it)->getNumRefs () == 1 )
305
306
{
306
307
it = mGLTFMaterialWithLocalTextures .erase (it);
307
- end = mGLTFMaterialWithLocalTextures .end ();
308
308
}
309
309
else
310
310
{
311
311
it++;
312
312
}
313
313
}
314
-
315
- mat->addLocalTextureTracking (getTrackingID (), getWorldID ());
316
314
mGLTFMaterialWithLocalTextures .push_back (mat);
317
315
}
318
316
@@ -628,16 +626,16 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
628
626
void LLLocalBitmap::updateGLTFMaterials (LLUUID old_id, LLUUID new_id)
629
627
{
630
628
// Might be a better idea to hold this in LLGLTFMaterialList
631
- mat_list_t ::iterator end = mGLTFMaterialWithLocalTextures .end ();
632
- for (mat_list_t ::iterator it = mGLTFMaterialWithLocalTextures .begin (); it != end;)
629
+ for (mat_list_t ::iterator it = mGLTFMaterialWithLocalTextures .begin (); it != mGLTFMaterialWithLocalTextures .end ();)
633
630
{
634
631
if ((*it)->getNumRefs () == 1 )
635
632
{
636
633
// render and override materials are often recreated,
637
634
// clean up any remains
638
635
it = mGLTFMaterialWithLocalTextures .erase (it);
639
- end = mGLTFMaterialWithLocalTextures .end ();
640
636
}
637
+ // Render material consists of base and override materials, make sure replaceLocalTexture
638
+ // gets called for base and override before applyOverride
641
639
else if ((*it)->replaceLocalTexture (mTrackingID , old_id, new_id))
642
640
{
643
641
it++;
@@ -647,43 +645,47 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
647
645
// Matching id not found, no longer in use
648
646
// material would clean itself, remove from the list
649
647
it = mGLTFMaterialWithLocalTextures .erase (it);
650
- end = mGLTFMaterialWithLocalTextures .end ();
651
648
}
652
649
}
653
650
654
- // Render material consists of base and override materials, make sure replaceLocalTexture
655
- // gets called for base and override before applyOverride
656
- end = mGLTFMaterialWithLocalTextures . end () ;
657
- for (mat_list_t ::iterator it = mGLTFMaterialWithLocalTextures . begin (); it != end; )
651
+ // Updating render materials calls updateTextureTracking which can modify
652
+ // mGLTFMaterialWithLocalTextures, so precollect all entries that need to be updated
653
+ std::set<LLTextureEntry*> update_entries ;
654
+ for (LLGLTFMaterial* mat : mGLTFMaterialWithLocalTextures )
658
655
{
659
- LLFetchedGLTFMaterial* fetched_mat = dynamic_cast <LLFetchedGLTFMaterial*>((*it).get ());
656
+ // mGLTFMaterialWithLocalTextures includes overrides that are not 'fetched'
657
+ // and don't have texture entries (they don't need to since render material does).
658
+ LLFetchedGLTFMaterial* fetched_mat = dynamic_cast <LLFetchedGLTFMaterial*>(mat);
660
659
if (fetched_mat)
661
660
{
662
661
for (LLTextureEntry* entry : fetched_mat->mTextureEntires )
663
662
{
664
- // Normally a change in applied material id is supposed to
665
- // drop overrides thus reset material, but local materials
666
- // currently reuse their existing asset id, and purpose is
667
- // to preview how material will work in-world, overrides
668
- // included, so do an override to render update instead.
669
- LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride ();
670
- if (override_mat)
671
- {
672
- // do not create a new material, reuse existing pointer
673
- LLFetchedGLTFMaterial* render_mat = dynamic_cast <LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial ());
674
- if (render_mat)
675
- {
676
- *render_mat = *fetched_mat;
677
- render_mat->applyOverride (*override_mat);
678
- }
679
- else
680
- {
681
- LL_WARNS_ONCE () << " Failed to apply local material override, render material not found" << LL_ENDL;
682
- }
683
- }
663
+ update_entries.insert (entry);
664
+ }
665
+ }
666
+ }
667
+
668
+
669
+ for (LLTextureEntry* entry : update_entries)
670
+ {
671
+ // Normally a change in applied material id is supposed to
672
+ // drop overrides thus reset material, but local materials
673
+ // currently reuse their existing asset id, and purpose is
674
+ // to preview how material will work in-world, overrides
675
+ // included, so do an override to render update instead.
676
+ LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride ();
677
+ LLGLTFMaterial* mat = entry->getGLTFMaterial ();
678
+ if (override_mat && mat)
679
+ {
680
+ // do not create a new material, reuse existing pointer
681
+ // so that mTextureEntires remains untouched
682
+ LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial ();
683
+ if (render_mat)
684
+ {
685
+ *render_mat = *mat;
686
+ render_mat->applyOverride (*override_mat); // can update mGLTFMaterialWithLocalTextures
684
687
}
685
688
}
686
- ++it;
687
689
}
688
690
}
689
691
0 commit comments