diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-03-18 01:59:22 +0200 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-03-20 03:15:28 +0200 |
| commit | 166fa85705bd7501a1af81d4b529fa4b83038be7 (patch) | |
| tree | 7011e1e575804da5baf5af4b1c6af30dd6c29425 | |
| parent | 0aa33a144d392c16eaa419ffefa7c98af2e37834 (diff) | |
#5543 PBR support for pipette
| -rw-r--r-- | indra/newview/llfloatercolorpicker.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llfloatercolorpicker.h | 3 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.cpp | 96 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.h | 4 | ||||
| -rw-r--r-- | indra/newview/lltoolpipette.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/lltoolpipette.h | 7 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 1 |
7 files changed, 101 insertions, 47 deletions
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index cd45093856..56e086502a 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -233,7 +233,15 @@ bool LLFloaterColorPicker::postBuild() childSetCommitCallback("sspin", onTextCommit, (void*)this ); childSetCommitCallback("lspin", onTextCommit, (void*)this ); - LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterColorPicker::onColorSelect, this, _1)); + mPipetteConnection = LLToolPipette::getInstance()->setToolSelectCallback( + [this](LLPointer<LLViewerObject> object, S32 te_index) + { + const LLTextureEntry* entry = object->getTE(te_index); + if (entry) + { + onColorSelect(entry->getColor()); + } + }); return true; } @@ -460,10 +468,10 @@ void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data) } } -void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te ) +// From pipette +void LLFloaterColorPicker::onColorSelect( const LLColor4 &color ) { - // Pipete - selectCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]); + selectCurRgb(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); } void LLFloaterColorPicker::onMouseCaptureLost() diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 5c27fffd08..af199d92a3 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -122,7 +122,7 @@ class LLFloaterColorPicker void onClickPipette ( ); static void onTextCommit ( LLUICtrl* ctrl, void* data ); static void onImmediateCheck ( LLUICtrl* ctrl, void* data ); - void onColorSelect( const class LLTextureEntry& te ); + void onColorSelect(const LLColor4& color); // from pipette private: // mutators for color values, can raise event to preview changes at object void selectCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ); @@ -197,6 +197,7 @@ class LLFloaterColorPicker F32 mContextConeOutAlpha; F32 mContextConeFadeTime; + boost::signals2::scoped_connection mPipetteConnection; }; #endif // LL_LLFLOATERCOLORPICKER_H diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 52ec8c17c1..f0655901f7 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -658,7 +658,10 @@ bool LLFloaterTexturePicker::postBuild() mSavedFolderState.setApply(false); - LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); + mPipetteConnection = LLToolPipette::getInstance()->setToolSelectCallback([this](LLPointer<LLViewerObject> object, S32 te_index) + { + onPipetteSelect(object, te_index); + }); getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); @@ -1640,39 +1643,88 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& fi } } -void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) +void LLFloaterTexturePicker::onPipetteSelect(LLPointer<LLViewerObject>& object, S32 te_index) { - LLUUID inventory_item_id = findItemID(te.getID(), true); - if (inventory_item_id.notNull()) + if (mInventoryPickType == PICK_MATERIAL) { - LLToolPipette::getInstance()->setResult(true, ""); - if (mInventoryPickType == PICK_MATERIAL) - { - // tes have no data about material ids - // Plus gltf materials are layered with overrides, - // which mean that end result might have no id. - LL_WARNS() << "tes have no data about material ids" << LL_ENDL; - } - else + // Note: does not copy overrides! + LLUUID mat_id = object->getRenderMaterialID(te_index); + if (mat_id == BLANK_MATERIAL_ASSET_ID) { - setImageID(te.getID()); + // It's fine if blank material isn't in inventory, just set it + LLToolPipette::getInstance()->setResult(true, ""); + setImageID(mat_id); setTentative(false); - } - mNoCopyTextureSelected = false; - LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); + mNoCopyTextureSelected = false; - if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + commitIfImmediateSet(); + } + else if (mat_id.isNull()) { - // no copy texture - mNoCopyTextureSelected = true; + LLToolPipette::getInstance()->setResult(false, LLTrans::getString("InventoryNoMaterial")); } + else + { + LLUUID inventory_item_id = findItemID(mat_id, true); + if (inventory_item_id.notNull()) + { + LLToolPipette::getInstance()->setResult(true, ""); + setImageID(mat_id); + setTentative(false); + + mNoCopyTextureSelected = false; + LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); + + if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + // no copy texture + mNoCopyTextureSelected = true; + } - commitIfImmediateSet(); + commitIfImmediateSet(); + } + else + { + // Not in inventory, can't apply + LLToolPipette::getInstance()->setResult(false, LLTrans::getString("InventoryNoMaterial")); + } + } } else { - LLToolPipette::getInstance()->setResult(false, LLTrans::getString("InventoryNoTexture")); + const LLTextureEntry* entry = object->getTE(te_index); + if (!entry) + { + // Whatever was selected is not a face/TE, + // no texture to check, so do nothing. + // Should not be reachable, if you hit this, + // check what happens in pipette tool. + llassert(false); + return; + } + LLUUID inventory_item_id = findItemID(entry->getID(), true); + if (inventory_item_id.notNull()) + { + LLToolPipette::getInstance()->setResult(true, ""); + setImageID(entry->getID()); + setTentative(false); + + mNoCopyTextureSelected = false; + LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); + + if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + // no copy texture + mNoCopyTextureSelected = true; + } + + commitIfImmediateSet(); + } + else + { + LLToolPipette::getInstance()->setResult(false, LLTrans::getString("InventoryNoTexture")); + } } } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index e0060474ce..759711ebf7 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -374,7 +374,7 @@ public: static void onBtnNone(void* userdata); void onSelectionChange(const std::deque<LLFolderViewItem*> &items, bool user_action); static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); - void onTextureSelect(const LLTextureEntry& te); + void onPipetteSelect(LLPointer<LLViewerObject>& object, S32 te_index); static void onModeSelect(LLUICtrl* ctrl, void *userdata); static void onBtnAdd(void* userdata); @@ -457,6 +457,8 @@ private: set_image_asset_id_callback mSetImageAssetIDCallback; set_on_update_image_stats_callback mOnUpdateImageStatsCallback; + boost::signals2::scoped_connection mPipetteConnection; + bool mBakeTextureEnabled; bool mLocalTextureEnabled; diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp index 9e3d435688..6ec25e9512 100644 --- a/indra/newview/lltoolpipette.cpp +++ b/indra/newview/lltoolpipette.cpp @@ -47,8 +47,8 @@ // LLToolPipette::LLToolPipette() -: LLTool(std::string("Pipette")), - mSuccess(true) +: LLTool(std::string("Pipette")) +, mSuccess(true) { } @@ -103,15 +103,6 @@ bool LLToolPipette::handleToolTip(S32 x, S32 y, MASK mask) return true; } -void LLToolPipette::setTextureEntry(const LLTextureEntry* entry) -{ - if (entry) - { - mTextureEntry = *entry; - mSignal(mTextureEntry); - } -} - void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); @@ -120,12 +111,14 @@ void LLToolPipette::pickCallback(const LLPickInfo& pick_info) // if we clicked on a face of a valid prim, save off texture entry data if (hit_obj && hit_obj->getPCode() == LL_PCODE_VOLUME && - pick_info.mObjectFace != -1) + pick_info.mObjectFace != -1 && + hit_obj->getNumTEs() > pick_info.mObjectFace) { //TODO: this should highlight the selected face only LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); - const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace); - LLToolPipette::getInstance()->setTextureEntry(entry); + + LLPointer<LLViewerObject> hit_obj_ptr = hit_obj; + LLToolPipette::getInstance()->mSignal(hit_obj_ptr, pick_info.mObjectFace); } } diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index 6c79674d76..7771f467e5 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -51,16 +51,13 @@ public: virtual bool handleHover(S32 x, S32 y, MASK mask) override; virtual bool handleToolTip(S32 x, S32 y, MASK mask) override; - // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots - typedef boost::signals2::signal<void (const LLTextureEntry& te)> signal_t; - void setToolSelectCallback(const signal_t::slot_type& cb) { mSignal.connect(cb); } + typedef boost::signals2::signal<void (LLPointer<LLViewerObject> obj, S32 te_index)> signal_t; + boost::signals2::connection setToolSelectCallback(const signal_t::slot_type& cb) { return mSignal.connect(cb); } void setResult(bool success, const std::string& msg); - void setTextureEntry(const LLTextureEntry* entry); static void pickCallback(const LLPickInfo& pick_info); protected: - LLTextureEntry mTextureEntry; signal_t mSignal; bool mSuccess; std::string mTooltipMsg; diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1860d38b0e..e022f29b76 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2333,6 +2333,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="InventorySingleFolderEmpty">Folder is empty.</string> <string name="InventorySingleFolderNoMatches">No matches.</string> <string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> + <string name="InventoryNoMaterial">You do not have a copy of this material in your inventory</string> <string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string> <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> |
