diff options
Diffstat (limited to 'indra/newview/llviewerobject.cpp')
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 130 |
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: |
