From 85967398ff8591170d89374652a6998ff6cd3d69 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 21 Jun 2023 20:50:50 -0500 Subject: [PATCH 1/7] SL-19792 Fix for visible gaps in water between region water and void water. --- indra/newview/app_settings/settings.xml | 33 ++++++++++----- .../class1/windlight/atmosphericsF.glsl | 2 - indra/newview/llreflectionmapmanager.cpp | 5 ++- indra/newview/llsettingsvo.cpp | 8 ++-- indra/newview/llvowater.cpp | 41 ++++++++++--------- 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2b2a2d9d1b..f3065d12b8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10590,17 +10590,6 @@ Value 3 - RenderSkyHDRScale - - Comment - Amount to over-brighten sun for HDR effect during the day - Persist - 0 - Type - F32 - Value - 1.0 - RenderSkyAutoAdjustLegacy Comment @@ -10612,6 +10601,28 @@ Value 1 + RenderSkyAutoAdjustAmbientScale + + Comment + Amount to scale ambient when auto-adjusting legacy skies + Persist + 1 + Type + F32 + Value + 0.5 + + RenderSkyAutoAdjustHDRScale + + Comment + HDR Scale value to use when auto-adjusting legacy skies + Persist + 1 + Type + F32 + Value + 2.0 + RenderReflectionProbeMaxLocalLightAmbiance Comment diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index 48cf234aa0..41a848a14f 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -36,8 +36,6 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { light *= atten.r; additive = srgb_to_linear(additive*2.0); - // magic 1.25 here is to match the default RenderSkyHDRScale -- this parameter needs to be plumbed into sky settings or something - // so it's available to all shaders that call atmosFragLighting instead of just softenLightF.glsl additive *= sky_hdr_scale; light += additive; return light; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e30aba3df7..779fe8bfd9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -924,8 +924,9 @@ void LLReflectionMapManager::updateUniforms() static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); - F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; - F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; + bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); + F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + F32 radscale = is_ambiance_pass ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 258cc1c7b2..264359a3a9 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -719,6 +719,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) F32 g = getGamma(); static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + static LLCachedControl auto_adjust_ambient_scale(gSavedSettings, "RenderSkyAutoAdjustAmbientScale", 0.75f); + static LLCachedControl auto_adjust_hdr_scale(gSavedSettings, "RenderSkyAutoAdjustHDRScale", 2.f); static LLCachedControl cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale); @@ -736,9 +738,9 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) } else if (psky->canAutoAdjust() && should_auto_adjust) { // auto-adjust legacy sky to take advantage of probe ambiance - shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * 0.5f).mV); - shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, 2.f); - probe_ambiance = 1.f; + shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV); + shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale); + probe_ambiance = 1.f; // NOTE -- must match LLSettingsSky::getReflectionProbeAmbiance value for "auto_adjust" true } else { diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 608d2cb799..77ad967cef 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -142,9 +142,14 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const unsigned int vertices_per_quad = 4; static const unsigned int indices_per_quad = 6; - const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1; + S32 size_x = LLPipeline::sRenderTransparentWater ? 8 : 1; + S32 size_y = LLPipeline::sRenderTransparentWater ? 8 : 1; - const S32 num_quads = size * size; + const LLVector3& scale = getScale(); + size_x *= llmin(llround(scale.mV[0] / 256.f), 8); + size_y *= llmin(llround(scale.mV[1] / 256.f), 8); + + const S32 num_quads = size_x * size_y; face->setSize(vertices_per_quad * num_quads, indices_per_quad * num_quads); @@ -175,41 +180,37 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) face->mCenterLocal = position_agent; S32 x, y; - F32 step_x = getScale().mV[0] / size; - F32 step_y = getScale().mV[1] / size; + F32 step_x = getScale().mV[0] / size_x; + F32 step_y = getScale().mV[1] / size_y; const LLVector3 up(0.f, step_y * 0.5f, 0.f); const LLVector3 right(step_x * 0.5f, 0.f, 0.f); const LLVector3 normal(0.f, 0.f, 1.f); - F32 size_inv = 1.f / size; + F32 size_inv_x = 1.f / size_x; + F32 size_inv_y = 1.f / size_y; - F32 z_fudge = 0.f; - - if (getIsEdgePatch()) - { //bump edge patches down 10 cm to prevent aliasing along edges - z_fudge = -0.1f; - } - - for (y = 0; y < size; y++) + for (y = 0; y < size_y; y++) { - for (x = 0; x < size; x++) + for (x = 0; x < size_x; x++) { - S32 toffset = index_offset + 4*(y*size + x); + S32 toffset = index_offset + 4*(y*size_x + x); position_agent = getPositionAgent() - getScale() * 0.5f; position_agent.mV[VX] += (x + 0.5f) * step_x; position_agent.mV[VY] += (y + 0.5f) * step_y; - position_agent.mV[VZ] += z_fudge; + + position_agent.mV[VX] = llround(position_agent.mV[VX]); + position_agent.mV[VY] = llround(position_agent.mV[VY]); *verticesp++ = position_agent - right + up; *verticesp++ = position_agent - right - up; *verticesp++ = position_agent + right + up; *verticesp++ = position_agent + right - up; - *texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv); - *texCoordsp++ = LLVector2(x*size_inv, y*size_inv); - *texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv); - *texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv); + *texCoordsp++ = LLVector2(x*size_inv_x, (y+1)*size_inv_y); + *texCoordsp++ = LLVector2(x*size_inv_x, y*size_inv_y); + *texCoordsp++ = LLVector2((x+1)*size_inv_x, (y+1)*size_inv_y); + *texCoordsp++ = LLVector2((x+1)*size_inv_x, y*size_inv_y); *normalsp++ = normal; *normalsp++ = normal; From 4e6303792a49e4db7a30ab5774668eb54b6a50b2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 22 Jun 2023 00:53:18 +0300 Subject: [PATCH 2/7] SL-5161 Don't render meshes that are waiting for skin data --- indra/newview/llmeshrepository.cpp | 54 +++++++++++++++++++++++++ indra/newview/llmeshrepository.h | 4 ++ indra/newview/llvovolume.cpp | 63 ++++++++++++++++++++++-------- indra/newview/llvovolume.h | 3 +- 4 files changed, 107 insertions(+), 17 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 67bf6827ad..9f90e132f8 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4255,6 +4255,37 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) return false; } +bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id) +{ + if (mesh_id.isNull()) + { + return false; + } + + if (mThread->hasSkinInfoInHeader(mesh_id)) + { + return true; + } + + const LLMeshSkinInfo* skininfo = getSkinInfo(mesh_id); + if (skininfo) + { + return true; + } + + return false; +} + +bool LLMeshRepository::hasHeader(const LLUUID& mesh_id) +{ + if (mesh_id.isNull()) + { + return false; + } + + return mThread->hasHeader(mesh_id); +} + bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); @@ -4271,6 +4302,29 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) return false; } +bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id) +{ + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) + { + LLMeshHeader& mesh = iter->second.second; + if (mesh.mSkinOffset >= 0 + && mesh.mSkinSize > 0) + { + return true; + } + } + + return false; +} + +bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) +{ + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + return iter != mMeshHeader.end(); +} void LLMeshRepository::uploadModel(std::vector& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 619e076fa6..89cd2d867f 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -401,6 +401,8 @@ public: bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool hasPhysicsShapeInHeader(const LLUUID& mesh_id); + bool hasSkinInfoInHeader(const LLUUID& mesh_id); + bool hasHeader(const LLUUID& mesh_id); void notifyLoadedMeshes(); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -650,6 +652,8 @@ public: LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); + bool hasSkinInfo(const LLUUID& mesh_id); + bool hasHeader(const LLUUID& mesh_id); void buildHull(const LLVolumeParams& params, S32 detail); void buildPhysicsMesh(LLModel::Decomposition& decomp); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8160785d75..805eb47431 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -230,7 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mColorChanged = FALSE; mSpotLightPriority = 0.f; - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = NULL; mMediaImplList.resize(getNumTEs()); @@ -1132,7 +1132,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) { mSkinInfo = NULL; - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; } if (!getVolume()->isMeshAssetLoaded()) @@ -1145,13 +1145,24 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - if (!mSkinInfo && !mSkinInfoFailed) + if (!mSkinInfo && !mSkinInfoUnavaliable) { - const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this); - if (skin_info) - { - notifySkinInfoLoaded(skin_info); - } + LLUUID mesh_id = volume_params.getSculptID(); + if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id)) + { + // If header is present but has no data about skin, + // no point fetching + mSkinInfoUnavaliable = true; + } + + if (!mSkinInfoUnavaliable) + { + const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(mesh_id, this); + if (skin_info) + { + notifySkinInfoLoaded(skin_info); + } + } } } else // otherwise is sculptie @@ -1186,7 +1197,7 @@ void LLVOVolume::updateSculptTexture() mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = NULL; } else @@ -1227,6 +1238,16 @@ void LLVOVolume::notifyMeshLoaded() mSculptChanged = TRUE; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + if (!mSkinInfo && !mSkinInfoUnavaliable) + { + // Header was loaded, update skin info state from header + LLUUID mesh_id = getVolume()->getParams().getSculptID(); + if (!gMeshRepo.hasSkinInfo(mesh_id)) + { + mSkinInfoUnavaliable = true; + } + } + LLVOAvatar *av = getAvatar(); if (av && !isAnimatedObject()) { @@ -1244,7 +1265,7 @@ void LLVOVolume::notifyMeshLoaded() void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) { - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = skin; notifyMeshLoaded(); @@ -1252,7 +1273,7 @@ void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) void LLVOVolume::notifySkinInfoUnavailable() { - mSkinInfoFailed = true; + mSkinInfoUnavaliable = true; mSkinInfo = nullptr; } @@ -5589,11 +5610,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) std::string vobj_name = llformat("Vol%p", vobj); bool is_mesh = vobj->isMesh(); - if (is_mesh && - ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) - { - continue; - } + if (is_mesh) + { + if ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) + || !gMeshRepo.meshRezEnabled()) + { + // Waiting for asset to fetch + continue; + } + + if (!vobj->getSkinInfo() && !vobj->isSkinInfoUnavaliable()) + { + // Waiting for skin info to fetch + continue; + } + } LLVolume* volume = vobj->getVolume(); if (volume) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index acba18383f..aadc1fbcf3 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -330,6 +330,7 @@ public: BOOL setIsFlexible(BOOL is_flexible); const LLMeshSkinInfo* getSkinInfo() const; + const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; } //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); } @@ -480,7 +481,7 @@ private: LLPointer mRiggedVolume; - bool mSkinInfoFailed; + bool mSkinInfoUnavaliable; LLConstPointer mSkinInfo; // statics public: From 3a1b60b2baa80218a79bf33cf983bd28df4f2343 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 22 Jun 2023 17:10:24 -0500 Subject: [PATCH 3/7] SL-19785 Fix for blown out skies from Glow Focus. Add notification when editing legacy skies. --- indra/llinventory/llsettingssky.cpp | 1 + .../shaders/class1/deferred/cloudsF.glsl | 2 +- indra/newview/llfloaterenvironmentadjust.cpp | 7 +++++-- indra/newview/llfloaterfixedenvironment.cpp | 6 ++++++ indra/newview/llpaneleditsky.cpp | 5 ++++- indra/newview/skins/default/xui/en/notifications.xml | 12 ++++++++++++ 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 6521ec8b43..8338245897 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -1142,6 +1142,7 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level) void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance) { + mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index e0e97bb938..f6870c3ff0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -110,7 +110,7 @@ void main() // Combine vec3 color; color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); - color.rgb= max(vec3(0), color.rgb); + color.rgb = clamp(color.rgb, vec3(0), vec3(1)); color.rgb *= 2.0; /// Gamma correct for WL (soft clip effect). diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index f9e8963479..18be4fffda 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -174,7 +174,8 @@ void LLFloaterEnvironmentAdjust::refresh() getChild(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId()); getChild(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID()); - getChild(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance()); + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + getChild(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance(should_auto_adjust)); LLColor3 glow(mLiveSky->getGlow()); @@ -488,7 +489,9 @@ void LLFloaterEnvironmentAdjust::onReflectionProbeAmbianceChanged() void LLFloaterEnvironmentAdjust::updateGammaLabel() { if (!mLiveSky) return; - F32 ambiance = mLiveSky->getReflectionProbeAmbiance(); + + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 ambiance = mLiveSky->getReflectionProbeAmbiance(should_auto_adjust); if (ambiance != 0.f) { childSetValue("scene_gamma_label", getString("hdr_string")); diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index b9dc14ac1a..bb6584302d 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -182,6 +182,12 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p syncronizeTabs(); refresh(); LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + + // teach user about HDR settings + if (mSettings && ((LLSettingsSky*)mSettings.get())->canAutoAdjust()) + { + LLNotificationsUtil::add("AutoAdjustHDRSky"); + } } void LLFloaterFixedEnvironment::syncronizeTabs() diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index a14af27e59..761d856aae 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -36,6 +36,7 @@ #include "llsettingssky.h" #include "llenvironment.h" #include "llatmosphere.h" +#include "llviewercontrol.h" namespace { @@ -207,7 +208,9 @@ void LLPanelSettingsSkyAtmosTab::refresh() F32 moisture_level = mSkySettings->getSkyMoistureLevel(); F32 droplet_radius = mSkySettings->getSkyDropletRadius(); F32 ice_level = mSkySettings->getSkyIceLevel(); - F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(); + + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(should_auto_adjust); getChild(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level); getChild(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 4949075f2d..f77b235408 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12097,5 +12097,17 @@ Material successfully created. Asset ID: [ASSET_ID] notext="Cancel" yestext="OK"/> + + + You are editing a non-HDR sky that has been automatically converted to HDR. To remove HDR and tone mapping, set Reflection Probe Ambiance to zero. + + From ca84e0e0c0b4b2844f478a549cb2cb1fbb52c898 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 22 Jun 2023 22:09:42 +0300 Subject: [PATCH 4/7] SL-5161 Avatars should stay hidden longer if they are waiting for meshes or skin data --- indra/llmath/llvolume.cpp | 25 ++++++++-- indra/llmath/llvolume.h | 9 ++-- indra/newview/llmeshrepository.cpp | 8 ++- indra/newview/llvoavatar.cpp | 80 ++++++++++++++++++++++++++++++ indra/newview/llvoavatar.h | 1 + 5 files changed, 116 insertions(+), 7 deletions(-) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 91e463cc32..0e3792fda3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2056,7 +2056,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mDetail = detail; mSculptLevel = -2; mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims - mIsMeshAssetLoaded = FALSE; + mIsMeshAssetLoaded = false; + mIsMeshAssetUnavaliable = false; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; mHullIndices = NULL; @@ -2804,14 +2805,32 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) } -BOOL LLVolume::isMeshAssetLoaded() +bool LLVolume::isMeshAssetLoaded() { return mIsMeshAssetLoaded; } -void LLVolume::setMeshAssetLoaded(BOOL loaded) +void LLVolume::setMeshAssetLoaded(bool loaded) { mIsMeshAssetLoaded = loaded; + if (loaded) + { + mIsMeshAssetUnavaliable = false; + } +} + +void LLVolume::setMeshAssetUnavaliable(bool unavaliable) +{ + // Don't set it if at least one lod loaded + if (!mIsMeshAssetLoaded) + { + mIsMeshAssetUnavaliable = unavaliable; + } +} + +bool LLVolume::isMeshAssetUnavaliable() +{ + return mIsMeshAssetUnavaliable; } void LLVolume::copyFacesTo(std::vector &faces) const diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ad6a669531..afed98ff36 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1111,15 +1111,18 @@ private: bool unpackVolumeFacesInternal(const LLSD& mdl); public: - virtual void setMeshAssetLoaded(BOOL loaded); - virtual BOOL isMeshAssetLoaded(); + virtual void setMeshAssetLoaded(bool loaded); + virtual bool isMeshAssetLoaded(); + virtual void setMeshAssetUnavaliable(bool unavaliable); + virtual bool isMeshAssetUnavaliable(); protected: BOOL mUnique; F32 mDetail; S32 mSculptLevel; F32 mSurfaceArea; //unscaled surface area - BOOL mIsMeshAssetLoaded; + bool mIsMeshAssetLoaded; + bool mIsMeshAssetUnavaliable; const LLVolumeParams mParams; LLPath *mPathp; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 9f90e132f8..57ac111fdf 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4067,7 +4067,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol if (sys_volume) { sys_volume->copyVolumeFaces(volume); - sys_volume->setMeshAssetLoaded(TRUE); + sys_volume->setMeshAssetLoaded(true); LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); } else @@ -4099,6 +4099,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + if (sys_volume) + { + sys_volume->setMeshAssetUnavaliable(true); + } + for (LLVOVolume* vobj : obj_iter->second) { if (vobj) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c7a2cea627..22cd9f71b3 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7574,6 +7574,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } +bool LLVOAvatar::hasPendingAttachedMeshes() +{ + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* objectp = attachment_iter->get(); + if (objectp) + { + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild && objectchild->getVolume()) + { + const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID(); + if (mesh_id.isNull()) + { + // No mesh nor skin info needed + continue; + } + + if (objectchild->getVolume()->isMeshAssetUnavaliable()) + { + // Mesh failed to load, do not expect it + continue; + } + + if (objectchild->mDrawable) + { + LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume(); + if (pvobj) + { + if (!pvobj->isMesh()) + { + // Not a mesh + continue; + } + + if (!objectchild->getVolume()->isMeshAssetLoaded()) + { + // Waiting for mesh + return true; + } + + const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); + if (skin_data) + { + // Skin info present, done + continue; + } + + if (pvobj->isSkinInfoUnavaliable()) + { + // Load failed or info not present, don't expect it + continue; + } + } + + // objectchild is not ready + return true; + } + } + } + } + } + } + } + return false; +} + //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -8150,6 +8229,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded() || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC) || !mPendingAttachment.empty() || (rez_status < 3 && !isFullyBaked()) + || hasPendingAttachedMeshes() ); } updateRezzedStatusTimers(rez_status); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f1dc503c9e..48bfd5293a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -917,6 +917,7 @@ public: virtual BOOL detachObject(LLViewerObject *viewer_object); static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id ); void cleanupAttachedMesh( LLViewerObject* pVO ); + bool hasPendingAttachedMeshes(); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; From 22eecf1018d8adbf214b9f1072b3cd6d3ab3d5ae Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 23 Jun 2023 11:46:09 -0500 Subject: [PATCH 5/7] SL-19897 Fix for 100% transparent objects not showing up in highlight transparent until LoD switch. --- indra/newview/llspatialpartition.cpp | 37 ++-------------------------- indra/newview/llspatialpartition.h | 5 ++-- indra/newview/llviewermenu.cpp | 7 +++--- indra/newview/pipeline.cpp | 34 ++++++++++++++++++++++--- indra/newview/pipeline.h | 5 +++- 5 files changed, 43 insertions(+), 45 deletions(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 978cb78083..f52f1a925d 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -777,7 +777,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c assert_states_valid(this); } -void LLSpatialGroup::destroyGL(bool keep_occlusion) + +void LLSpatialGroup::destroyGLState(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1290,45 +1291,11 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); } -class LLOctreeDirty : public OctreeTraveler -{ -public: - virtual void visit(const OctreeNode* state) - { - LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); - group->destroyGL(); - - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) - { - gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL); - } - } - - for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) - { - LLSpatialBridge* bridge = *i; - traverse(bridge->mOctree); - } - } -}; void LLSpatialPartition::restoreGL() { } -void LLSpatialPartition::resetVertexBuffers() -{ - LLOctreeDirty dirty; - dirty.traverse(mOctree); -} - BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 053ce9e60b..88584f535a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -295,7 +295,9 @@ public: BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group void shift(const LLVector4a &offset); - void destroyGL(bool keep_occlusion = false); + + // TODO: this no longer appears to be called, figure out if it's important and if not remove it + void destroyGLState(bool keep_occlusion = false); void updateDistance(LLCamera& camera); F32 getUpdateUrgency() const; @@ -419,7 +421,6 @@ public: void renderDebug(); void renderIntersectingBBoxes(LLCamera* camera); void restoreGL(); - void resetVertexBuffers(); BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b9042b3496..6e5c268c00 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7826,10 +7826,6 @@ class LLToggleShaderControl : public view_listener_t BOOL checked = gSavedSettings.getBOOL( control_name ); gSavedSettings.setBOOL( control_name, !checked ); LLPipeline::refreshCachedSettings(); - //gPipeline.updateRenderDeferred(); - //gPipeline.releaseGLBuffers(); - //gPipeline.createGLBuffers(); - //gPipeline.resetVertexBuffers(); LLViewerShaderMgr::instance()->setShaders(); return !checked; } @@ -8560,6 +8556,9 @@ class LLViewHighlightTransparent : public view_listener_t bool handleEvent(const LLSD& userdata) { LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; + + // invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag + gPipeline.rebuildDrawInfo(); return true; } }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38f27d4dfa..e64ef6d555 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10593,8 +10593,36 @@ void LLPipeline::handleShadowDetailChanged() } } -void LLPipeline::overrideEnvironmentMap() +class LLOctreeDirty : public OctreeTraveler { - //mReflectionMapManager.mProbes.clear(); - //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin()); +public: + virtual void visit(const OctreeNode* state) + { + LLSpatialGroup* group = (LLSpatialGroup*)state->getListener(0); + + group->setState(LLSpatialGroup::GEOM_DIRTY); + gPipeline.markRebuild(group); + + for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) + { + LLSpatialBridge* bridge = *i; + traverse(bridge->mOctree); + } + } +}; + + +void LLPipeline::rebuildDrawInfo() +{ + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLOctreeDirty dirty; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + dirty.traverse(part->mOctree); + } } + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 19c8b06a46..961a55330a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -131,6 +131,10 @@ public: bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); bool allocateShadowBuffer(U32 resX, U32 resY); + // rebuild all LLVOVolume render batches + void rebuildDrawInfo(); + + // Clear LLFace mVertexBuffer pointers void resetVertexBuffers(LLDrawable* drawable); // perform a profile of the given avatar @@ -449,7 +453,6 @@ public: void handleShadowDetailChanged(); LLReflectionMapManager mReflectionMapManager; - void overrideEnvironmentMap(); private: void unloadShaders(); From 21b67896e9d1d181f39b8e44b9efe2b4c153d22b Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 26 Jun 2023 15:37:18 -0500 Subject: [PATCH 6/7] SL-19909 Fix for reflection probes on vehicles blocking mouse clicks. Incidental instrumentation and decruft. --- indra/newview/llappviewer.cpp | 2 -- indra/newview/llreflectionmap.cpp | 2 +- indra/newview/llviewerobject.cpp | 2 ++ indra/newview/llviewerobjectlist.cpp | 4 ++++ indra/newview/llviewerregion.cpp | 7 +++++++ indra/newview/llvovolume.cpp | 9 ++++++++- indra/newview/llworld.cpp | 3 ++- 7 files changed, 24 insertions(+), 5 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index abef25e34f..cf84094aa4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4675,7 +4675,6 @@ public: static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio"); static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup"); static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables"); -static LLTrace::BlockTimerStatHandle FTM_CLEANUP_OBJECTS("Objects"); static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks"); static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD"); static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist"); @@ -4972,7 +4971,6 @@ void LLAppViewer::idle() { LL_RECORD_BLOCK_TIME(FTM_CLEANUP); { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_OBJECTS); gObjectList.cleanDeadObjects(); } { diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 72dab0cba8..efaf068bd2 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -117,7 +117,7 @@ void LLReflectionMap::autoAdjustOrigin() { int face = -1; LLVector4a intersection; - LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, true, &face, &intersection); + LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], false, false, true, &face, &intersection); if (drawable != nullptr) { hit = true; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e67750af7c..628a787b9d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -418,6 +418,7 @@ void LLViewerObject::markDead() { if (!mDead) { + LL_PROFILE_ZONE_SCOPED; //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL; // Root object of this hierarchy unlinks itself. @@ -1153,6 +1154,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, const EObjectUpdateType update_type, LLDataPacker *dp) { + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL; LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index e576784db8..ce4f9b7e64 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1353,6 +1353,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED; // Don't ever kill gAgentAvatarp, just force it to the agent's region // unless region is NULL which is assumed to mean you are logging out. if ((objectp == gAgentAvatarp) && gAgent.getRegion()) @@ -1379,6 +1380,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) void LLViewerObjectList::killObjects(LLViewerRegion *regionp) { + LL_PROFILE_ZONE_SCOPED; LLViewerObject *objectp; @@ -1438,6 +1440,8 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) return; } + LL_PROFILE_ZONE_SCOPED; + S32 num_removed = 0; LLViewerObject *objectp; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index d60fae4bd6..6b92b16ef4 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -716,6 +716,7 @@ static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); LLViewerRegion::~LLViewerRegion() { + LL_PROFILE_ZONE_SCOPED; mDead = TRUE; mImpl->mActiveSet.clear(); mImpl->mVisibleEntries.clear(); @@ -1590,6 +1591,7 @@ void LLViewerRegion::lightIdleUpdate() void LLViewerRegion::idleUpdate(F32 max_update_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer update_timer; F32 max_time; @@ -1693,6 +1695,10 @@ BOOL LLViewerRegion::isViewerCameraStatic() void LLViewerRegion::killInvisibleObjects(F32 max_time) { +#if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory. + // because of this, every time you turn around the simulator sends a swarm of full object update messages from cache + // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to + // appear in the scene when flying back and forth between regions if(!sVOCacheCullingEnabled) { return; @@ -1769,6 +1775,7 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time) } return; +#endif } void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8160785d75..de1d3fc012 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -244,6 +244,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re LLVOVolume::~LLVOVolume() { + LL_PROFILE_ZONE_SCOPED; delete mTextureAnimp; mTextureAnimp = NULL; delete mVolumeImpl; @@ -267,6 +268,7 @@ void LLVOVolume::markDead() { if (!mDead) { + LL_PROFILE_ZONE_SCOPED; if (getVolume()) { LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID()); @@ -4676,7 +4678,12 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end_face = face+1; } pick_transparent |= isHiglightedOrBeacon(); - bool special_cursor = specialHoverCursor(); + + // we *probably* shouldn't care about special cursor at all, but we *definitely* + // don't care about special cursor for reflection probes -- makes alt-zoom + // go through reflection probes on vehicles + bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); + for (S32 i = start_face; i < end_face; ++i) { if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 0e0dbdc071..709a457862 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -111,7 +111,7 @@ LLWorld::LLWorld() : gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled"); + LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled"); } @@ -681,6 +681,7 @@ static LLTrace::SampleStatHandle<> sNumActiveCachedObjects("numactivecachedobjec void LLWorld::updateRegions(F32 max_update_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer update_timer; mNumOfActiveCachedObjects = 0; From 77ea8eedb8dab989043fed4d7db6938a8c6cf54d Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Mon, 26 Jun 2023 14:07:16 -0700 Subject: [PATCH 7/7] Fix for SL-19620 & SL-19768 material overrides incorrectly affecting other faces --- indra/newview/llvocache.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7081ecaa4b..a4070a513c 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -105,7 +105,7 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) std::string error, warn; if (override_mat->fromJSON(gltf_json_str, warn, error)) { - mGLTFMaterial[i] = override_mat; + mGLTFMaterial[side_idx] = override_mat; } else { @@ -126,6 +126,16 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL; } } + + llassert(mSides.size() == mGLTFMaterial.size()); +#ifdef SHOW_ASSERT + for (auto const & side : mSides) + { + // check that mSides and mGLTFMaterial have exactly the same keys present + llassert(mGLTFMaterial.count(side.first) == 1); + } +#endif + return true; } @@ -141,8 +151,11 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const data["object_id"] = mObjectId; data["local_id"] = (LLSD::Integer) mLocalId; + llassert(mSides.size() == mGLTFMaterial.size()); for (auto const & side : mSides) { + // check that mSides and mGLTFMaterial have exactly the same keys present + llassert(mGLTFMaterial.count(side.first) == 1); data["sides"].append(LLSD::Integer(side.first)); data["gltf_json"].append(side.second); }