summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerobject.cpp')
-rw-r--r--indra/newview/llviewerobject.cpp130
1 files changed, 97 insertions, 33 deletions
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b0401b1425..c13e541da0 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5091,11 +5091,10 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
if (base_material && override_material)
{
tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material));
-
- LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
- *render_material = *base_material;
- render_material->applyOverride(*override_material);
- tep->setGLTFRenderMaterial(render_material);
+ }
+ if (base_material)
+ {
+ initRenderMaterial(i);
}
}
}
@@ -5271,6 +5270,9 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
});
}
getTE(te)->setGLTFMaterial(mat);
+ initRenderMaterial(te);
+ mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
+ llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(getTE(te)->getGLTFRenderMaterial()) != nullptr);
}
else if (mat_id.isNull() && mat != nullptr)
{
@@ -5660,6 +5662,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
return retval;
}
+// Set render material if there are overrides or if the base material is has a
+// baked texture. Otherwise, set it to null.
+// If you are setting the material override and not sending an update message,
+// you should probably call this function.
+S32 LLViewerObject::initRenderMaterial(U8 te)
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ LLTextureEntry* tep = getTE(te);
+ if (!tep) { return 0; }
+ const LLFetchedGLTFMaterial* base_material = static_cast<LLFetchedGLTFMaterial*>(tep->getGLTFMaterial());
+ llassert(base_material);
+ if (!base_material) { return 0; }
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ LLFetchedGLTFMaterial* render_material = nullptr;
+ bool need_render_material = override_material;
+ if (!need_render_material)
+ {
+ for (const LLUUID& texture_id : base_material->mTextureId)
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(texture_id))
+ {
+ need_render_material = true;
+ break;
+ }
+ }
+ }
+ if (need_render_material)
+ {
+ render_material = new LLFetchedGLTFMaterial(*base_material);
+ if (override_material) { render_material->applyOverride(*override_material); }
+ render_material->clearFetchedTextures();
+ }
+ return tep->setGLTFRenderMaterial(render_material);
+}
+
S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
{
LL_PROFILE_ZONE_SCOPED;
@@ -5693,22 +5731,13 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
if (retval)
{
+ retval = initRenderMaterial(te) | retval;
if (override_mat)
{
- LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
- render_mat->applyOverride(*override_mat);
- tep->setGLTFRenderMaterial(render_mat);
- retval = TEM_CHANGE_TEXTURE;
-
for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
}
-
- }
- else if (tep->setGLTFRenderMaterial(nullptr))
- {
- retval = TEM_CHANGE_TEXTURE;
}
}
@@ -7578,25 +7607,15 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// the overrides have not changed due to being only texture
// transforms. Re-apply the overrides to the render material here,
// if present.
- const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
- if (override_material)
+ // Also, sometimes, the material has baked textures, which requires
+ // a copy unique to this object.
+ // Currently, we do not deduplicate render materials.
+ new_material->onMaterialComplete([obj_id = getID(), te]()
{
- new_material->onMaterialComplete([obj_id = getID(), te]()
- {
- LLViewerObject* obj = gObjectList.findObject(obj_id);
- if (!obj) { return; }
- LLTextureEntry* tep = obj->getTE(te);
- if (!tep) { return; }
- const LLGLTFMaterial* new_material = tep->getGLTFMaterial();
- if (!new_material) { return; }
- const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
- if (!override_material) { return; }
- LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
- *render_material = *new_material;
- render_material->applyOverride(*override_material);
- tep->setGLTFRenderMaterial(render_material);
- });
- }
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (!obj) { return; }
+ obj->initRenderMaterial(te);
+ });
}
}
@@ -7718,6 +7737,51 @@ void LLViewerObject::clearTEWaterExclusion(const U8 te)
}
}
+bool LLViewerObject::isReachable()
+{
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ LLViewerRegion* object_region = getRegion();
+
+ if (!agent_region || !object_region)
+ {
+ return false;
+ }
+ if (agent_region == object_region)
+ {
+ return true;
+ }
+
+ std::unordered_set<LLViewerRegion*> visited;
+ std::queue<LLViewerRegion*> pending;
+ visited.insert(agent_region);
+ pending.push(agent_region);
+
+ while (!pending.empty())
+ {
+ LLViewerRegion* current = pending.front();
+ pending.pop();
+
+ std::vector<LLViewerRegion*> neighbors;
+ current->getNeighboringRegions(neighbors);
+
+ for (LLViewerRegion* neighbor : neighbors)
+ {
+ if (!neighbor) continue;
+
+ if (neighbor == object_region)
+ {
+ return true;
+ }
+ // region's neighbors were not checked
+ if (visited.insert(neighbor).second)
+ {
+ pending.push(neighbor);
+ }
+ }
+ }
+ return false;
+}
+
class ObjectPhysicsProperties : public LLHTTPNode
{
public: