From b052240a500707fc0e34ef6f23a02af39fdfc500 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 22 May 2024 12:33:36 +0300 Subject: viewer#1400 Allow forcing specific LODs for selection --- indra/newview/llselectmgr.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 885f4d993e..cbc52aeec6 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -250,6 +250,23 @@ LLSelectMgr::LLSelectMgr() mForceSelection = FALSE; mShowSelection = FALSE; + + LLControlVariable* ctrl = gSavedSettings.getControl("DebugSelectionLODs").get(); + if (ctrl) + { + mSlectionLodModChangedConnection = ctrl->getSignal()->connect([this](LLControlVariable*, const LLSD&, const LLSD&) + { + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + if (object) + { + object->updateLOD(); + } + } + }); + } } @@ -259,6 +276,7 @@ LLSelectMgr::LLSelectMgr() LLSelectMgr::~LLSelectMgr() { clearSelections(); + mSlectionLodModChangedConnection.disconnect(); } void LLSelectMgr::clearSelections() -- cgit v1.3 From 4214ab8e79809412fdec626fa5f914723e6d4704 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 12 Dec 2024 23:32:34 +0200 Subject: #3280 Fix crashes at gFloaterTools Likely specific to headless client --- indra/newview/llagent.cpp | 5 ++++- indra/newview/llgiveinventory.cpp | 12 ++++++++++-- indra/newview/llpanelprimmediacontrols.cpp | 2 +- indra/newview/llselectmgr.cpp | 5 ++++- indra/newview/lltoolbrush.cpp | 5 ++++- indra/newview/lltooldraganddrop.cpp | 23 +++++++++++++++-------- indra/newview/lltoolplacer.cpp | 5 ++++- indra/newview/lltoolselectland.cpp | 5 ++++- indra/newview/llviewermenu.cpp | 6 +++++- indra/newview/llviewerobject.cpp | 12 ++++++------ indra/newview/pipeline.cpp | 2 +- 11 files changed, 58 insertions(+), 24 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8756baa04a..a076594e0a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2501,7 +2501,10 @@ void LLAgent::endAnimationUpdateUI() gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } // Don't let this be called more than once if the camera // mode hasn't changed. --JC diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 1259b65ebe..57dd203f2f 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -414,7 +414,11 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, effectp->setTargetObject(gObjectList.findObject(to_agent)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + + if (gFloaterTools) + { + gFloaterTools->dirty(); + } LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); @@ -572,7 +576,11 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, effectp->setTargetObject(gObjectList.findObject(to_agent)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + + if (gFloaterTools) + { + gFloaterTools->dirty(); + } LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index b8c12ce0b9..b00b9d1ad1 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -294,7 +294,7 @@ void LLPanelPrimMediaControls::updateShape() LLViewerMediaImpl* media_impl = getTargetMediaImpl(); LLViewerObject* objectp = getTargetObject(); - if(!media_impl || gFloaterTools->getVisible()) + if(!media_impl || (gFloaterTools && gFloaterTools->getVisible())) { setVisible(false); return; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index fceb25b3d3..1d4bfb0ed9 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7253,7 +7253,10 @@ void dialog_refresh_all() // *TODO: Eliminate all calls into outside classes below, make those // objects register with the update signal. - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } gMenuObject->needsArrange(); diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index 2fe81df4fb..cf7b123fa7 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -447,7 +447,10 @@ void LLToolBrushLand::handleSelect() { gEditMenuHandler = this; - gFloaterTools->setStatusText("modifyland"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("modifyland"); + } // if (!mBrushSelected) { mBrushSelected = true; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 4efa289141..75adb722f3 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1253,6 +1253,7 @@ void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj, // If user dropped a material onto face it implies // applying texture now without cancel, save to selection if (nodep + && gFloaterTools && gFloaterTools->getVisible() && nodep->mSavedGLTFMaterialIds.size() > hit_face) { @@ -1429,10 +1430,10 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, // If user dropped a texture onto face it implies // applying texture now without cancel, save to selection - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; if (nodep - && gFloaterTools->getVisible() && panel_face + && gFloaterTools->getVisible() && panel_face->getTextureDropChannel() == 0 /*texture*/ && nodep->mSavedTextures.size() > hit_face) { @@ -1488,8 +1489,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, if (allow_adding_to_override) { LLGLTFMaterial::TextureInfo drop_channel = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); - if (gFloaterTools->getVisible() && panel_face) + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; + if (panel_face && gFloaterTools->getVisible()) { drop_channel = panel_face->getPBRDropChannel(); } @@ -1514,9 +1515,9 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, LLTextureEntry* tep = hit_obj->getTE(hit_face); - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; - if (gFloaterTools->getVisible() && panel_face) + if (panel_face && gFloaterTools->getVisible()) { tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel(); switch (tex_channel) @@ -1611,7 +1612,10 @@ void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj, } } hit_obj->saveScript(new_script, active, true); - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } // VEFFECT: SetScript LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, true); @@ -1844,7 +1848,10 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, effectp->setTargetObject(hit_obj); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } } // accessor that looks at permissions, copyability, and names of diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index b15bb5efd5..0d141d7545 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -527,7 +527,10 @@ bool LLToolPlacer::handleHover(S32 x, S32 y, MASK mask) void LLToolPlacer::handleSelect() { - gFloaterTools->setStatusText("place"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("place"); + } } void LLToolPlacer::handleDeselect() diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp index 88553c7557..331581fd88 100644 --- a/indra/newview/lltoolselectland.cpp +++ b/indra/newview/lltoolselectland.cpp @@ -207,7 +207,10 @@ void LLToolSelectLand::render() void LLToolSelectLand::handleSelect() { - gFloaterTools->setStatusText("selectland"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("selectland"); + } } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 6281ac1f9e..1c9a892a4f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3177,7 +3177,11 @@ void handle_object_edit() LLFloaterReg::showInstance("build"); LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + + if (gFloaterTools) + { + gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + } LLViewerJoystick::getInstance()->moveObjects(true); LLViewerJoystick::getInstance()->setNeedsReset(true); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 86440fca48..74d795ea25 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1290,7 +1290,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #endif //clear cost and linkset cost setObjectCostStale(); - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -1729,7 +1729,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #endif setObjectCostStale(); - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -3747,7 +3747,7 @@ void LLViewerObject::setObjectCost(F32 cost) mObjectCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -3767,7 +3767,7 @@ void LLViewerObject::setLinksetCost(F32 cost) iter++; } - if (needs_refresh) + if (needs_refresh && gFloaterTools) { gFloaterTools->dirty(); } @@ -3778,7 +3778,7 @@ void LLViewerObject::setPhysicsCost(F32 cost) mPhysicsCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -3789,7 +3789,7 @@ void LLViewerObject::setLinksetPhysicsCost(F32 cost) mLinksetPhysicsCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5f096a5356..6c5fd855fd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7208,7 +7208,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable()); + bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools && gFloaterTools->isAvailable()); LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram; shader.bind(); -- cgit v1.3 From 6ca6bdd629efd6aa01b452db4ba6c1c50d6961bf Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 4 Mar 2025 21:32:46 +0200 Subject: #3630 fix for incorrectly pointed particle beam after dropping HUD attachment --- indra/newview/llselectmgr.cpp | 3 ++- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llviewerwindow.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1d4bfb0ed9..b307de787c 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7485,7 +7485,8 @@ void LLSelectMgr::updatePointAt() LLVector3 select_offset; const LLPickInfo& pick = gViewerWindow->getLastPick(); LLViewerObject *click_object = pick.getObject(); - if (click_object && click_object->isSelected()) + bool was_hud = pick.mPickHUD && !click_object->isHUDAttachment(); + if (click_object && click_object->isSelected() && !was_hud) { // clicked on another object in our selection group, use that as target select_offset.setVec(pick.mObjectOffset); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1795d62adc..2d9f73115e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -6178,7 +6178,7 @@ void LLPickInfo::fetchResults() mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY); mObjectID = objectp->mID; mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; - + mPickHUD = objectp->isHUDAttachment(); mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index fbc2c58fbf..ac0dfa3fe4 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -133,6 +133,7 @@ public: bool mPickParticle; bool mPickUnselectable; bool mPickReflectionProbe = false; + bool mPickHUD{ false }; void getSurfaceInfo(); private: -- cgit v1.3 From bf0767b0d781202064c58ff7c9f44dfeec6959ac Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 29 Oct 2024 00:54:13 +0200 Subject: viewer#2894 Make PBR scale like Blinn Phong does --- indra/newview/llselectmgr.cpp | 27 +++++++++++++++++++++++++++ indra/newview/llselectmgr.h | 2 ++ 2 files changed, 29 insertions(+) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b307de787c..b2f30dd966 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3138,6 +3138,8 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) F32 scale_x = 1; F32 scale_y = 1; + F32 offset_x = 0; + F32 offset_y = 0; for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { @@ -3154,6 +3156,21 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; } material->mTextureTransform[i].mScale.set(scale_x, scale_y); + + LLVector2 scales = selectNode->mGLTFScales[te_num][i]; + LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; + F64 int_part = 0; + offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); + if (offset_x < 0) + { + offset_x++; + } + offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); + if (offset_y < 0) + { + offset_y++; + } + material->mTextureTransform[i].mOffset.set(offset_x, offset_y); } const LLGLTFMaterial* base_material = tep->getGLTFMaterial(); @@ -6904,6 +6921,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) { mTextureScaleRatios.clear(); mGLTFScaleRatios.clear(); + mGLTFScales.clear(); + mGLTFOffsets.clear(); if (mObject.notNull()) { @@ -6944,6 +6963,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) F32 scale_x = 1; F32 scale_y = 1; std::vector material_v_vec; + std::vector material_scales_vec; + std::vector material_offset_vec; for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { if (material) @@ -6951,12 +6972,16 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) LLGLTFMaterial::TextureTransform& transform = material->mTextureTransform[i]; scale_x = transform.mScale[VX]; scale_y = transform.mScale[VY]; + material_scales_vec.push_back(transform.mScale); + material_offset_vec.push_back(transform.mOffset); } else { // Not having an override doesn't mean that there is no material scale_x = 1; scale_y = 1; + material_scales_vec.emplace_back(scale_x, scale_y); + material_offset_vec.emplace_back(0.f, 0.f); } if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) @@ -6972,6 +6997,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) material_v_vec.push_back(material_v); } mGLTFScaleRatios.push_back(material_v_vec); + mGLTFScales.push_back(material_scales_vec); + mGLTFOffsets.push_back(material_offset_vec); } } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index b70ec3dbea..e4613bb3e7 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -242,6 +242,8 @@ public: gltf_materials_vec_t mSavedGLTFOverrideMaterials; std::vector mTextureScaleRatios; std::vector< std::vector > mGLTFScaleRatios; + std::vector< std::vector > mGLTFScales; + std::vector< std::vector > mGLTFOffsets; std::vector mSilhouetteVertices; // array of vertices to render silhouette of object std::vector mSilhouetteNormals; // array of normals to render silhouette of object bool mSilhouetteExists; // need to generate silhouette? -- cgit v1.3 From 6b88a2bec27e24debb4eb4fe986850f36f8689a9 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 24 Mar 2025 18:05:06 +0200 Subject: #3780 disable water exclusion if user applies PBR or Media --- indra/newview/llpanelface.cpp | 5 +---- indra/newview/llselectmgr.cpp | 11 ++++++++++- indra/newview/llselectmgr.h | 1 + indra/newview/llviewerobject.cpp | 25 +++++++++++++++++++++++++ indra/newview/llviewerobject.h | 2 ++ 5 files changed, 39 insertions(+), 5 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c4f118fed8..b7d9df6ea6 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3075,10 +3075,7 @@ void LLPanelFace::onCommitHideWater() } else { - // reset texture to default plywood - LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); - // reset texture repeats, that might be altered by invisiprim script from wiki - LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); + LLSelectMgr::getInstance()->clearWaterExclusion(); } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b307de787c..cc88d31aee 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1995,7 +1995,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = BLANK_MATERIAL_ASSET_ID; } } - + objectp->clearTEWaterExclusion(te); // Blank out most override data on the object and send to server objectp->setRenderMaterialID(te, asset_id); @@ -2477,6 +2477,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) } else { // Add/update media + object->clearTEWaterExclusion(te); object->setTEMediaFlags(te, mMediaFlags); LLVOVolume *vo = dynamic_cast(object); llassert(NULL != vo); @@ -7724,6 +7725,14 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) gAgentCamera.mHUDCurZoom = current_zoom; } +void LLSelectMgr::clearWaterExclusion() +{ + // reset texture to default plywood + LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); + // reset texture repeats, that might be altered by invisiprim script from wiki + LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); +} + ///////////////////////////////////////////////////////////////////////////// // Object selection iterator helpers ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index b70ec3dbea..0dbdc133e3 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -836,6 +836,7 @@ public: void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; void updatePointAt(); + void clearWaterExclusion(); // Internal list maintenance functions. TODO: Make these private! void remove(std::vector& objects); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3d88cc5f39..c5e81dd179 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7682,6 +7682,31 @@ void LLViewerObject::setGLTFAsset(const LLUUID& id) updateVolume(volume_params); } +void LLViewerObject::clearTEWaterExclusion(const U8 te) +{ + if (permModify()) + { + LLViewerTexture* image = getTEImage(te); + if (image && (IMG_ALPHA_GRAD == image->getID())) + { + // reset texture to default plywood + setTEImage(te, LLViewerTextureManager::getFetchedTexture(DEFAULT_OBJECT_TEXTURE, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + + // reset texture repeats, that might be altered by invisiprim script from wiki + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + { + return; + } + F32 DEFAULT_REPEATS = 2.f; + F32 new_s = getScale().mV[s_axis] * DEFAULT_REPEATS; + F32 new_t = getScale().mV[t_axis] * DEFAULT_REPEATS; + + setTEScale(te, new_s, new_t); + sendTEUpdate(); + } + } +} class ObjectPhysicsProperties : public LLHTTPNode { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 63458e60ea..2b52ea2076 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -405,6 +405,8 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + void clearTEWaterExclusion(const U8 te); + bool isImageAlphaBlended(const U8 te) const; void fitFaceTexture(const U8 face); -- cgit v1.3 From 939817d560434cdc2888ef478b965f5625a381b7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Apr 2025 21:16:38 +0300 Subject: #3849 Crash at LLSelectMgr::updatePointAt --- indra/newview/llselectmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 3d17446186..be1e64ce54 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7513,7 +7513,7 @@ void LLSelectMgr::updatePointAt() LLVector3 select_offset; const LLPickInfo& pick = gViewerWindow->getLastPick(); LLViewerObject *click_object = pick.getObject(); - bool was_hud = pick.mPickHUD && !click_object->isHUDAttachment(); + bool was_hud = pick.mPickHUD && click_object && !click_object->isHUDAttachment(); if (click_object && click_object->isSelected() && !was_hud) { // clicked on another object in our selection group, use that as target -- cgit v1.3 From b62aae79599544206a12e238359e0ecd1be33213 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Apr 2025 21:16:38 +0300 Subject: #3849 Crash at LLSelectMgr::updatePointAt --- indra/newview/llselectmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index cc88d31aee..fbf5aa84d8 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7486,7 +7486,7 @@ void LLSelectMgr::updatePointAt() LLVector3 select_offset; const LLPickInfo& pick = gViewerWindow->getLastPick(); LLViewerObject *click_object = pick.getObject(); - bool was_hud = pick.mPickHUD && !click_object->isHUDAttachment(); + bool was_hud = pick.mPickHUD && click_object && !click_object->isHUDAttachment(); if (click_object && click_object->isSelected() && !was_hud) { // clicked on another object in our selection group, use that as target -- cgit v1.3 From fe0a4f44cf172953fa44f26acb56e0be50ec8bb4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 5 May 2025 19:38:07 +0300 Subject: #4027 Crash at adjustTexturesByScale --- indra/newview/llselectmgr.cpp | 62 ++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 28 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index be1e64ce54..8aa3693d60 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3142,36 +3142,43 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) F32 offset_x = 0; F32 offset_y = 0; - for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + if (te_num < selectNode->mGLTFScaleRatios.size()) { - LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; - - if (planar) - { - scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; - } - else - { - scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; - } - material->mTextureTransform[i].mScale.set(scale_x, scale_y); - - LLVector2 scales = selectNode->mGLTFScales[te_num][i]; - LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; - F64 int_part = 0; - offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); - if (offset_x < 0) + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { - offset_x++; + LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; + + if (planar) + { + scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; + } + else + { + scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; + } + material->mTextureTransform[i].mScale.set(scale_x, scale_y); + + LLVector2 scales = selectNode->mGLTFScales[te_num][i]; + LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; + F64 int_part = 0; + offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); + if (offset_x < 0) + { + offset_x++; + } + offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); + if (offset_y < 0) + { + offset_y++; + } + material->mTextureTransform[i].mOffset.set(offset_x, offset_y); } - offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); - if (offset_y < 0) - { - offset_y++; - } - material->mTextureTransform[i].mOffset.set(offset_x, offset_y); + } + else + { + llassert(false); // make sure mGLTFScaleRatios is filled } const LLGLTFMaterial* base_material = tep->getGLTFMaterial(); @@ -6927,7 +6934,6 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) if (mObject.notNull()) { - LLVector3 scale = mObject->getScale(); for (U8 i = 0; i < mObject->getNumTEs(); i++) -- cgit v1.3 From 3806c35ebed6fce245213dbdc3f0bd6c34fb0c3f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 18 Jul 2025 00:32:54 +0300 Subject: #4216 Pressing cancel on picker reverts an override even when it shouldn't revert material override --- indra/newview/llselectmgr.cpp | 22 +++++++++++++++++----- indra/newview/lltooldraganddrop.cpp | 13 +++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5357f57dfe..01fd5ae63c 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2249,6 +2249,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials() { // Restore base material LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te]; + LLUUID old_asset_id = objectp->getRenderMaterialID(te); // Update material locally objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/); @@ -2259,18 +2260,29 @@ void LLSelectMgr::selectionRevertGLTFMaterials() objectp->setTEGLTFMaterialOverride(te, material); } - // Enqueue update to server - if (asset_id.notNull() && material) + if (asset_id.isNull() || !material) + { + //blank override out + LLGLTFMaterialList::queueApply(objectp, te, asset_id); + } + if (old_asset_id != asset_id) { // Restore overrides and base material + // Note: might not work reliably if asset is already there, might + // have a server sided problem where servers applies override + // first then resets it by adding asset, in which case need + // to create a server ticket and chain asset then override + // application. LLGLTFMaterialList::queueApply(objectp, te, asset_id, material); } else { - //blank override out - LLGLTFMaterialList::queueApply(objectp, te, asset_id); + // Enqueue override update to server + // Note: this is suboptimal, better to send asset id as well + // but there seems to be a server problem with queueApply + // that ignores override in some cases + LLGLTFMaterialList::queueModify(objectp, te, material); } - } return true; } diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 3665ff5e87..b4a5955be3 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1125,28 +1125,33 @@ void set_texture_to_material(LLViewerObject* hit_obj, case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: default: { - material->setBaseColorId(asset_id); + material->setBaseColorId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: { - material->setOcclusionRoughnessMetallicId(asset_id); + material->setOcclusionRoughnessMetallicId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: { - material->setEmissiveId(asset_id); + material->setEmissiveId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: { - material->setNormalId(asset_id); + material->setNormalId(asset_id, true); } break; } + // Update viewer side, needed for updating mSavedGLTFOverrideMaterials. + // Also for parity, we are immediately setting textures and materials, + // so we should immediate set overrides to. + hit_obj->setTEGLTFMaterialOverride(hit_face, material); + // update server LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); } -- cgit v1.3 From ec3fe8c2a56d92c5eff480d7f027a1b6062bb4cf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Mon, 29 Sep 2025 23:40:41 +0300 Subject: #3189 Fix missed else condition --- indra/newview/llgltfmateriallist.cpp | 4 +++- indra/newview/llselectmgr.cpp | 16 +--------------- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 8da835ed7d..3e4aadc381 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -359,6 +359,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L { if (asset_id.isNull() || override_json.empty()) { + // If there is no asset, there can't be an override queueApply(obj, side, asset_id); } else @@ -371,6 +372,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L { if (asset_id.isNull() || material_override == nullptr) { + // If there is no asset, there can't be an override queueApply(obj, side, asset_id); } else @@ -470,7 +472,7 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr callba { data[i]["gltf_json"] = e.override_data->asJSON(); } - if (!e.override_json.empty()) + else if (!e.override_json.empty()) { data[i]["gltf_json"] = e.override_json; } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 01fd5ae63c..291e3c2ed3 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2265,23 +2265,9 @@ void LLSelectMgr::selectionRevertGLTFMaterials() //blank override out LLGLTFMaterialList::queueApply(objectp, te, asset_id); } - if (old_asset_id != asset_id) - { - // Restore overrides and base material - // Note: might not work reliably if asset is already there, might - // have a server sided problem where servers applies override - // first then resets it by adding asset, in which case need - // to create a server ticket and chain asset then override - // application. - LLGLTFMaterialList::queueApply(objectp, te, asset_id, material); - } else { - // Enqueue override update to server - // Note: this is suboptimal, better to send asset id as well - // but there seems to be a server problem with queueApply - // that ignores override in some cases - LLGLTFMaterialList::queueModify(objectp, te, material); + LLGLTFMaterialList::queueApply(objectp, te, asset_id, material); } } return true; -- cgit v1.3 From 5fe152cfea87c04c1edf2caa7d419a056a7916a2 Mon Sep 17 00:00:00 2001 From: Aqil Ahmad Date: Mon, 6 Oct 2025 18:52:33 +0500 Subject: Fix #4195: Preserve transforms when switching PBR materials (#4725) Fixes texture transforms being reset when switching from Blinn-Phong to PBR materials and between PBR. Previously, custom scale, offset, and rotation settings would be lost, making it tedious to switch between PBR materials. --- indra/llprimitive/llgltfmaterial.cpp | 31 +++++ indra/llprimitive/llgltfmaterial.h | 8 ++ indra/newview/llgltfmateriallist.cpp | 11 -- indra/newview/llselectmgr.cpp | 87 ++++++++++++++ indra/newview/lltooldraganddrop.cpp | 215 ++++++++++++++++++++++++++++++++++- 5 files changed, 339 insertions(+), 13 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index cc4921416f..930222e3db 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -923,3 +923,34 @@ void LLGLTFMaterial::updateTextureTracking() // setTEGLTFMaterialOverride is responsible for tracking // for material overrides editor will set it } + +void LLGLTFMaterial::convertTextureTransformToPBR( + F32 tex_scale_s, + F32 tex_scale_t, + F32 tex_offset_s, + F32 tex_offset_t, + F32 tex_rotation, + LLVector2& pbr_scale, + LLVector2& pbr_offset, + F32& pbr_rotation) +{ + pbr_scale.set(tex_scale_s, tex_scale_t); + pbr_rotation = -(tex_rotation) / 2.f; + const F32 adjusted_offset_s = tex_offset_s; + const F32 adjusted_offset_t = -tex_offset_t; + F32 center_adjust_s = 0.5f * (1.0f - tex_scale_s); + F32 center_adjust_t = 0.5f * (1.0f - tex_scale_t); + + if (pbr_rotation != 0.0f) + { + const F32 c = cosf(pbr_rotation); + const F32 s = sinf(pbr_rotation); + const F32 tmp_s = center_adjust_s * c - center_adjust_t * s; + const F32 tmp_t = center_adjust_s * s + center_adjust_t * c; + center_adjust_s = tmp_s; + center_adjust_t = tmp_t; + } + + pbr_offset.set(adjusted_offset_s + center_adjust_s, + adjusted_offset_t + center_adjust_t); +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 10df4c8ee1..8d45cb6185 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -214,6 +214,14 @@ public: bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); } virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); virtual void updateTextureTracking(); + + // Convert legacy TE transform values to PBR transform values. + static void convertTextureTransformToPBR(F32 tex_scale_s, F32 tex_scale_t, + F32 tex_offset_s, F32 tex_offset_t, + F32 tex_rotation, + LLVector2& pbr_scale, + LLVector2& pbr_offset, + F32& pbr_rotation); protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 3e4aadc381..64b6d20cd6 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -380,17 +380,6 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L LLGLTFMaterial* material = new LLGLTFMaterial(*material_override); sApplyQueue.push_back({ obj->getID(), side, asset_id, material }); } - - if (sUpdates.size() >= MAX_TASK_UPDATES) - { - LLCoros::instance().launch("modifyMaterialCoro", - std::bind(&LLGLTFMaterialList::modifyMaterialCoro, - gAgent.getRegionCapability("ModifyMaterialParams"), - sUpdates, - std::shared_ptr(nullptr))); - - sUpdates = LLSD::emptyArray(); - } } void LLGLTFMaterialList::queueUpdate(const LLSD& data) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 291e3c2ed3..be4b449e2a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1996,9 +1996,96 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = BLANK_MATERIAL_ASSET_ID; } } + + // If this face already has the target material ID, do nothing. + // This prevents re-sending the same ID on OK, which can cause the server + // to drop overrides when queueApply is invoked with the OLD id. + if (objectp->getRenderMaterialID(te) == asset_id) + { + return true; + } + + // Preserve existing texture transforms when switching to PBR material + LLTextureEntry* tep = objectp->getTE(te); + bool should_preserve_transforms = false; + LLGLTFMaterial* preserved_override = nullptr; + + if (tep && asset_id.notNull()) + { + // Only preserve transforms from existing GLTF material override + // Do not fall back to texture entry transforms when switching between PBR materials + LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride(); + if (existing_override) + { + // Check if existing override has non-default transforms + const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0]; + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + + if (existing_transform.mScale != default_transform.mScale || + existing_transform.mOffset != default_transform.mOffset || + existing_transform.mRotation != default_transform.mRotation) + { + // Preserve non-default transforms from current PBR material + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + preserved_override->mTextureTransform[i].mScale = existing_transform.mScale; + preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset; + preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation; + } + should_preserve_transforms = true; + } + // If existing override has default transforms, don't preserve anything + } + else + { + // No existing PBR material override - check texture entry transforms + // This handles the case of switching from Blinn-Phong to PBR material + F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation; + tep->getScale(&existing_scale_s, &existing_scale_t); + tep->getOffset(&existing_offset_s, &existing_offset_t); + existing_rotation = tep->getRotation(); + + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] || + existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] || + existing_rotation != default_transform.mRotation) + { + // Preserve non-default transforms from texture entry + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLVector2 pbr_scale, pbr_offset; + F32 pbr_rotation; + LLGLTFMaterial::convertTextureTransformToPBR( + existing_scale_s, existing_scale_t, + existing_offset_s, existing_offset_t, + existing_rotation, + pbr_scale, pbr_offset, pbr_rotation); + preserved_override->mTextureTransform[i].mScale = pbr_scale; + preserved_override->mTextureTransform[i].mOffset = pbr_offset; + preserved_override->mTextureTransform[i].mRotation = pbr_rotation; + } + should_preserve_transforms = true; + } + } + } + objectp->clearTEWaterExclusion(te); // Blank out most override data on the object and send to server objectp->setRenderMaterialID(te, asset_id); + if (should_preserve_transforms && preserved_override) + { + // Apply material with preserved transforms + LLGLTFMaterialList::queueApply(objectp, te, asset_id, preserved_override); + // Update local state + objectp->setRenderMaterialID(te, asset_id, false, true); + tep->setGLTFMaterialOverride(preserved_override); + } + else + { + objectp->setRenderMaterialID(te, asset_id); + } return true; } diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index b4a5955be3..d0c0bdb5ce 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -29,6 +29,8 @@ // library headers #include "llnotificationsutil.h" +#include +#include // project headers #include "llagent.h" #include "llagentcamera.h" @@ -1297,7 +1299,89 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, asset_id = BLANK_MATERIAL_ASSET_ID; } - hit_obj->setRenderMaterialID(hit_face, asset_id); + // Preserve existing texture transforms when switching to PBR material + LLTextureEntry* tep = hit_obj->getTE(hit_face); + F32 existing_scale_s = LLGLTFMaterial::TextureTransform().mScale.mV[0]; + F32 existing_scale_t = LLGLTFMaterial::TextureTransform().mScale.mV[1]; + F32 existing_offset_s = LLGLTFMaterial::TextureTransform().mOffset.mV[0]; + F32 existing_offset_t = LLGLTFMaterial::TextureTransform().mOffset.mV[1]; + F32 existing_rotation = LLGLTFMaterial::TextureTransform().mRotation; + bool should_preserve_transforms = false; + LLGLTFMaterial* preserved_override = nullptr; + + if (tep && asset_id.notNull()) + { + // Only preserve transforms from existing GLTF material override + // Do not fall back to texture entry transforms when switching between PBR materials + LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride(); + if (existing_override) + { + // Check if existing override has non-default transforms + const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0]; + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + + if (existing_transform.mScale != default_transform.mScale || + existing_transform.mOffset != default_transform.mOffset || + existing_transform.mRotation != default_transform.mRotation) + { + // Preserve non-default transforms from current PBR material + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + preserved_override->mTextureTransform[i].mScale = existing_transform.mScale; + preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset; + preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation; + } + should_preserve_transforms = true; + } + // If existing override has default transforms, don't preserve anything + } + else + { + // No existing PBR material override - check texture entry transforms + // This handles the case of switching from Blinn-Phong to PBR material + F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation; + tep->getScale(&existing_scale_s, &existing_scale_t); + tep->getOffset(&existing_offset_s, &existing_offset_t); + existing_rotation = tep->getRotation(); + + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] || + existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] || + existing_rotation != default_transform.mRotation) + { + // Preserve non-default transforms from texture entry + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLVector2 pbr_scale, pbr_offset; + F32 pbr_rotation; + LLGLTFMaterial::convertTextureTransformToPBR( + existing_scale_s, existing_scale_t, + existing_offset_s, existing_offset_t, + existing_rotation, + pbr_scale, pbr_offset, pbr_rotation); + preserved_override->mTextureTransform[i].mScale = pbr_scale; + preserved_override->mTextureTransform[i].mOffset = pbr_offset; + preserved_override->mTextureTransform[i].mRotation = pbr_rotation; + } + should_preserve_transforms = true; + } + } + } + + if (should_preserve_transforms && preserved_override) + { + // Apply material with preserved transforms + LLGLTFMaterialList::queueApply(hit_obj, hit_face, asset_id, preserved_override); + // Update local state + hit_obj->setRenderMaterialID(hit_face, asset_id, false, true); + tep->setGLTFMaterialOverride(preserved_override); + } + else + { + hit_obj->setRenderMaterialID(hit_face, asset_id); + } dialog_refresh_all(); @@ -1333,7 +1417,134 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, asset_id = BLANK_MATERIAL_ASSET_ID; } - hit_obj->setRenderMaterialIDs(asset_id); + // Preserve existing texture transforms when switching to PBR material for all faces + std::vector> preserved_transforms(hit_obj->getNumTEs()); + + if (asset_id.notNull()) + { + for (S32 te = 0; te < hit_obj->getNumTEs(); ++te) + { + LLTextureEntry* tep = hit_obj->getTE(te); + if (!tep) continue; + + bool should_preserve = false; + LLGLTFMaterial* preserved_override = nullptr; + + // Only preserve transforms from existing GLTF material override + // Do not fall back to texture entry transforms when switching between PBR materials + LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride(); + if (existing_override) + { + // Check if existing override has non-default transforms + const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0]; + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + + if (existing_transform.mScale != default_transform.mScale || + existing_transform.mOffset != default_transform.mOffset || + existing_transform.mRotation != default_transform.mRotation) + { + // Preserve non-default transforms from current PBR material + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + preserved_override->mTextureTransform[i].mScale = existing_transform.mScale; + preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset; + preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation; + } + should_preserve = true; + } + else + { + // Existing override has default transforms, fall back to texture entry + F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation; + tep->getScale(&existing_scale_s, &existing_scale_t); + tep->getOffset(&existing_offset_s, &existing_offset_t); + existing_rotation = tep->getRotation(); + + if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] || + existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] || + existing_rotation != default_transform.mRotation) + { + // Preserve non-default transforms from texture entry + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLVector2 pbr_scale, pbr_offset; + F32 pbr_rotation; + LLGLTFMaterial::convertTextureTransformToPBR( + existing_scale_s, existing_scale_t, + existing_offset_s, existing_offset_t, + existing_rotation, + pbr_scale, pbr_offset, pbr_rotation); + preserved_override->mTextureTransform[i].mScale = pbr_scale; + preserved_override->mTextureTransform[i].mOffset = pbr_offset; + preserved_override->mTextureTransform[i].mRotation = pbr_rotation; + } + should_preserve = true; + } + } + } + else + { + // No existing PBR material override - check texture entry transforms + // This handles the case of switching from Blinn-Phong to PBR material + F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation; + tep->getScale(&existing_scale_s, &existing_scale_t); + tep->getOffset(&existing_offset_s, &existing_offset_t); + existing_rotation = tep->getRotation(); + + const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform(); + if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] || + existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] || + existing_rotation != default_transform.mRotation) + { + // Preserve non-default transforms from texture entry + preserved_override = new LLGLTFMaterial(); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLVector2 pbr_scale, pbr_offset; + F32 pbr_rotation; + LLGLTFMaterial::convertTextureTransformToPBR( + existing_scale_s, existing_scale_t, + existing_offset_s, existing_offset_t, + existing_rotation, + pbr_scale, pbr_offset, pbr_rotation); + preserved_override->mTextureTransform[i].mScale = pbr_scale; + preserved_override->mTextureTransform[i].mOffset = pbr_offset; + preserved_override->mTextureTransform[i].mRotation = pbr_rotation; + } + should_preserve = true; + } + } + + preserved_transforms[te] = std::make_pair(should_preserve, preserved_override); + } + } + + // Apply materials with preserved transforms + if (asset_id.notNull()) + { + for (S32 te = 0; te < hit_obj->getNumTEs(); ++te) + { + LLGLTFMaterial* preserved_override = preserved_transforms[te].second; + if (preserved_override) + { + // Apply material with preserved transforms + LLGLTFMaterialList::queueApply(hit_obj, te, asset_id, preserved_override); + // Update local state + hit_obj->setRenderMaterialID(te, asset_id, false, true); + hit_obj->getTE(te)->setGLTFMaterialOverride(preserved_override); + } + else + { + hit_obj->setRenderMaterialID(te, asset_id, false, true); + } + } + } + else + { + hit_obj->setRenderMaterialIDs(asset_id); + } dialog_refresh_all(); // send the update to the simulator hit_obj->sendTEUpdate(); -- cgit v1.3 From 6a5d4e0e3de5448835b58177ce7a64119facbd28 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:57:04 +0300 Subject: #4876 Fix material not applying 1. Dupplicate call in llselectmgr can cause race conditions 2. lltooldragndrop wasn't updating server in one case --- indra/newview/llselectmgr.cpp | 1 - indra/newview/lltooldraganddrop.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/newview/llselectmgr.cpp') diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index be4b449e2a..4762fc555d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2073,7 +2073,6 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) objectp->clearTEWaterExclusion(te); // Blank out most override data on the object and send to server - objectp->setRenderMaterialID(te, asset_id); if (should_preserve_transforms && preserved_override) { // Apply material with preserved transforms diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index d0c0bdb5ce..f78ff2226c 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1537,7 +1537,7 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, } else { - hit_obj->setRenderMaterialID(te, asset_id, false, true); + hit_obj->setRenderMaterialID(te, asset_id); } } } -- cgit v1.3