llpreviewmaterial.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /**
  2. * @file llpreviewmaterial.h
  3. * @brief LLPreviewMaterial class declaration
  4. *
  5. * $LicenseInfo:firstyear=2022&license=viewergpl$
  6. *
  7. * Copyright (c) 2022, Linden Research, Inc., (c) 2023-2024 Henri Beauchamp
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLPREVIEWMATERIAL_H
  33. #define LL_LLPREVIEWMATERIAL_H
  34. #include <set>
  35. #include "boost/signals2.hpp"
  36. #include "llassettype.h"
  37. #include "hbfastmap.h"
  38. #include "llimagej2c.h"
  39. #include "llpreview.h"
  40. #include "llviewertexture.h"
  41. #include "llvoinventorylistener.h"
  42. class LLButton;
  43. class LLCheckBoxCtrl;
  44. class LLColorSwatchCtrl;
  45. class LLComboBox;
  46. class LLGLTFMaterial;
  47. class LLLocalGLTFMaterial;
  48. class LLPermissions;
  49. class LLSpinCtrl;
  50. class LLTextBox;
  51. class LLTextureCtrl;
  52. namespace tinygltf
  53. {
  54. class Model;
  55. }
  56. class LLPreviewMaterial final : public LLPreview, public LLVOInventoryListener
  57. {
  58. friend class LLMaterialCopiedCB;
  59. protected:
  60. LOG_CLASS(LLPreviewMaterial);
  61. // Constructor used internally only, for the live editor and uploads.
  62. LLPreviewMaterial(const std::string& name, bool live_editor = false);
  63. public:
  64. // Constructor used to preview/edit inventory items.
  65. LLPreviewMaterial(const std::string& name, const LLRect& rect,
  66. const std::string& title, const LLUUID& item_uuid,
  67. const LLUUID& object_uuid);
  68. ~LLPreviewMaterial() override;
  69. bool setFromGltfModel(const tinygltf::Model& model, S32 index,
  70. bool set_textures = false);
  71. void setFromGltfMetaData(const std::string& filename,
  72. const tinygltf::Model& model, S32 index);
  73. // For live preview, applies current material to currently selected object
  74. void applyToSelection();
  75. void getGLTFMaterial(LLGLTFMaterial* matp);
  76. void setMaterialName(const std::string& name);
  77. LL_INLINE LLUUID getBaseColorId()
  78. {
  79. return getTextureId(mBaseColorTexCtrl);
  80. }
  81. LL_INLINE void setBaseColorId(const LLUUID& id)
  82. {
  83. setTextureId(mBaseColorTexCtrl, id);
  84. }
  85. LL_INLINE void setBaseColorUploadId(const LLUUID& id)
  86. {
  87. setTextureUploadId(mBaseColorTexCtrl, id);
  88. }
  89. // Gets/sets both base color and transparency
  90. LLColor4 getBaseColor() const;
  91. void setBaseColor(const LLColor4& color);
  92. LL_INLINE F32 getTransparency() const
  93. {
  94. // Note: spinner is from 0 to 100% for 1.0 to 0.0 alpha value. HB
  95. return 1.f - getCtrlValue(mTransparencyCtrl) / 100.f;
  96. }
  97. LL_INLINE void setTransparency(F32 transparency)
  98. {
  99. // Note: spinner is from 0 to 100% for 1.0 to 0.0 alpha value. HB
  100. setCtrlValue(mTransparencyCtrl, (1.f - transparency) * 100.f);
  101. }
  102. std::string getAlphaMode() const;
  103. void setAlphaMode(const std::string& alpha_mode);
  104. LL_INLINE F32 getAlphaCutoff() const
  105. {
  106. return getCtrlValue(mAlphaCutoffCtrl);
  107. }
  108. LL_INLINE void setAlphaCutoff(F32 alpha_cutoff)
  109. {
  110. setCtrlValue(mAlphaCutoffCtrl, alpha_cutoff);
  111. }
  112. LL_INLINE LLUUID getMetallicRoughnessId() const
  113. {
  114. return getTextureId(mMetallicTexCtrl);
  115. }
  116. LL_INLINE void setMetallicRoughnessId(const LLUUID& id)
  117. {
  118. setTextureId(mMetallicTexCtrl, id);
  119. }
  120. LL_INLINE void setMetallicRoughnessUploadId(const LLUUID& id)
  121. {
  122. setTextureUploadId(mMetallicTexCtrl, id);
  123. }
  124. LL_INLINE F32 getMetalnessFactor() const
  125. {
  126. return getCtrlValue(mMetalnessCtrl);
  127. }
  128. LL_INLINE void setMetalnessFactor(F32 factor)
  129. {
  130. setCtrlValue(mMetalnessCtrl, factor);
  131. }
  132. LL_INLINE F32 getRoughnessFactor() const
  133. {
  134. return getCtrlValue(mRoughnessCtrl);
  135. }
  136. LL_INLINE void setRoughnessFactor(F32 factor)
  137. {
  138. setCtrlValue(mRoughnessCtrl, factor);
  139. }
  140. LL_INLINE LLUUID getEmissiveId() const
  141. {
  142. return getTextureId(mEmissiveTexCtrl);
  143. }
  144. LL_INLINE void setEmissiveId(const LLUUID& id)
  145. {
  146. setTextureId(mEmissiveTexCtrl, id);
  147. }
  148. LL_INLINE void setEmissiveUploadId(const LLUUID& id)
  149. {
  150. setTextureUploadId(mEmissiveTexCtrl, id);
  151. }
  152. LLColor4 getEmissiveColor() const;
  153. void setEmissiveColor(const LLColor4& color);
  154. LL_INLINE LLUUID getNormalId() const
  155. {
  156. return getTextureId(mNormalTexCtrl);
  157. }
  158. LL_INLINE void setNormalId(const LLUUID& id)
  159. {
  160. setTextureId(mNormalTexCtrl, id);
  161. }
  162. LL_INLINE void setNormalUploadId(const LLUUID& id)
  163. {
  164. setTextureUploadId(mNormalTexCtrl, id);
  165. }
  166. bool getDoubleSided() const;
  167. void setDoubleSided(bool double_sided);
  168. // Returns a pointer on the last opened preview floater on success (there
  169. // may be several opened floaters when the file contains more than one
  170. // material and 'index' is ommitted or negative), or NULL on failure. HB
  171. static LLPreviewMaterial* loadFromFile(const std::string& filename,
  172. S32 index = -1);
  173. static bool canModifyObjectsMaterial();
  174. static bool canSaveObjectsMaterial();
  175. static void saveObjectsMaterial();
  176. static void loadLive();
  177. static void markForLiveUpdate();
  178. static void updateLive(const LLUUID& object_id, S32 te);
  179. static void closeLiveEditorInstance();
  180. static LLPreviewMaterial* getLiveEditorInstance();
  181. // Called on live overrides selection changes
  182. static void onSelectionChanged();
  183. // Initializes the UI from a default GLTF material
  184. void loadDefaults();
  185. LL_INLINE U32 getUnsavedChangesFlags() const { return mUnsavedChanges; }
  186. LL_INLINE U32 getRevertedChangesFlags() const { return mRevertedChanges; }
  187. // Local textures support
  188. const LLUUID& getLocalTexTrackingIdFromFlag(U32 flag) const;
  189. bool updateMaterialLocalSubscription(LLGLTFMaterial* matp);
  190. private:
  191. // LLView overrides
  192. void draw() override;
  193. // LLPanel override
  194. bool postBuild() override;
  195. // LLVOInventoryListener override
  196. void inventoryChanged(LLViewerObject*, LLInventoryObject::object_list_t*,
  197. S32, void*) override;
  198. void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null);
  199. // LLPreview overrides
  200. void loadAsset() override;
  201. LL_INLINE const char* getTitleName() const override { return "Material"; }
  202. void setItemID(const LLUUID& object_id) override;
  203. void setAuxItem(const LLInventoryItem* itemp) override;
  204. LLUUID getTextureId(LLTextureCtrl* ctrlp) const;
  205. void setTextureId(LLTextureCtrl* ctrlp, const LLUUID& id);
  206. void setTextureUploadId(LLTextureCtrl* ctrlp, const LLUUID& id);
  207. F32 getCtrlValue(LLSpinCtrl* ctrlp) const;
  208. void setCtrlValue(LLSpinCtrl* ctrlp, F32 value);
  209. // Utility method for converting image URI into a texture name.
  210. std::string getImageNameFromUri(std::string image_uri,
  211. std::string texture_type);
  212. // Utility method for building a description of the imported material.
  213. std::string buildMaterialDescription();
  214. void resetUnsavedChanges();
  215. void markChangesUnsaved(U32 dirty_flag);
  216. // Saves textures to inventory if needed; returns number of scheduled
  217. // uploads.
  218. U32 saveTextures();
  219. bool saveTexture(LLImageJ2C* imagep, U32 tex_type, const std::string& name,
  220. const LLUUID& asset_id);
  221. void setFailedToUploadTexture();
  222. // Upload and inventory updates callbacks
  223. static void uploadFailure(void* userdata);
  224. static void uploadSuccess(const LLUUID& asset_id, const LLSD& response,
  225. U32 tex_type, void* userdata);
  226. static void finishInventoryUpload(const LLUUID& item_id,
  227. const LLUUID& new_asset_id,
  228. const LLUUID& new_item_id,
  229. void* userdata);
  230. static void finishTaskUpload(const LLUUID& item_id,
  231. const LLUUID& new_asset_id,
  232. const LLUUID& task_id, void* userdata);
  233. bool updateInventoryItem(const std::string& buffer,
  234. const LLUUID& item_id,
  235. const LLUUID& task_id);
  236. static void createInventoryItem(const std::string& buffer,
  237. const std::string& name,
  238. const std::string& desc,
  239. const LLPermissions& permissions);
  240. void clearTextures();
  241. void getGLTFModel(tinygltf::Model& model);
  242. std::string getEncodedAsset();
  243. bool decodeAsset(const std::string& buffer);
  244. void saveIfNeeded();
  245. static void finishInventoryUpload(LLUUID item_id, LLUUID new_asset_id,
  246. LLUUID new_item_id);
  247. static void finishTaskUpload(LLUUID item_id, LLUUID new_asset_id);
  248. static LLPreviewMaterial* getInstance(const LLUUID& uuid);
  249. static void onLoadComplete(const LLUUID& asset_id, LLAssetType::EType type,
  250. void* userdata, S32 status, LLExtStat);
  251. static void onSaveComplete(const LLUUID& asset_uuid, void* user_data,
  252. S32 status, LLExtStat);
  253. bool handleSaveChangesDialog(const LLSD& notification,
  254. const LLSD& response);
  255. void setEnableEditing(bool can_modify);
  256. void setFromGLTFMaterial(LLGLTFMaterial* matp);
  257. bool setFromSelection();
  258. void loadMaterial(const tinygltf::Model& model,
  259. const std::string& filename, S32 index);
  260. // Resolves what type of parameter get dirtied from the UI control that got
  261. // touched. Used from UI controls callbacks to avoid having to pass more
  262. // parameters (the dirty flag) to them. HB
  263. U32 getDirtyFlagFromCtrl(LLUICtrl* ctrlp);
  264. // Local textures support.
  265. void subscribeToLocalTexture(U32 dirty_flag, const LLUUID& tracking_id);
  266. void replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id);
  267. // Notifications callback methods
  268. bool onCancelMsgCallback(const LLSD& notification, const LLSD& response);
  269. bool onSaveAsMsgCallback(const LLSD& notification, const LLSD& response);
  270. static bool onSaveObjectsMaterialCB(const LLSD& notification,
  271. const LLSD& response,
  272. const LLPermissions& permissions);
  273. void finishSaveAs(const LLUUID& new_item_id, const std::string& buffer);
  274. static void saveMaterial(const LLGLTFMaterial* render_matp,
  275. const LLLocalGLTFMaterial* local_matp);
  276. static void onCancelCtrl(LLUICtrl* ctrlp, void* userdata);
  277. static void onSelectCtrl(LLUICtrl* ctrlp, void* userdata);
  278. static void onTextureCtrl(LLUICtrl* ctrlp, void* userdata);
  279. static void onClickCancel(void* userdata);
  280. static void onClickOK(void* userdata);
  281. static void onClickSave(void* userdata);
  282. static void onClickSaveAs(void* userdata);
  283. private:
  284. LLUUID mAssetID;
  285. LLUUID mBaseColorTextureUploadId;
  286. LLUUID mMetallicTextureUploadId;
  287. LLUUID mEmissiveTextureUploadId;
  288. LLUUID mNormalTextureUploadId;
  289. // We keep pointers to fetched textures or viewer will remove them if user
  290. // temporary selects something else with 'apply now'.
  291. LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
  292. LLPointer<LLViewerFetchedTexture> mNormalFetched;
  293. LLPointer<LLViewerFetchedTexture> mMetallicRoughnessFetched;
  294. LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
  295. // J2C versions of packed buffers for uploading
  296. LLPointer<LLImageJ2C> mBaseColorJ2C;
  297. LLPointer<LLImageJ2C> mNormalJ2C;
  298. LLPointer<LLImageJ2C> mMetallicRoughnessJ2C;
  299. LLPointer<LLImageJ2C> mEmissiveJ2C;
  300. // Local textures support
  301. struct LocalTexConnection
  302. {
  303. LLUUID mTrackingId;
  304. boost::signals2::connection mConnection;
  305. };
  306. typedef fast_hmap<S32, LocalTexConnection> connection_map_t;
  307. connection_map_t mTextureChangesUpdates;
  308. LLCheckBoxCtrl* mDoubleSidedCheck;
  309. LLTextBox* mUploadFeeText;
  310. LLTextureCtrl* mBaseColorTexCtrl;
  311. LLTextureCtrl* mMetallicTexCtrl;
  312. LLTextureCtrl* mEmissiveTexCtrl;
  313. LLTextureCtrl* mNormalTexCtrl;
  314. LLColorSwatchCtrl* mBaseColorCtrl;
  315. LLColorSwatchCtrl* mEmissiveColorCtrl;
  316. LLComboBox* mAlphaModeCombo;
  317. LLSpinCtrl* mTransparencyCtrl;
  318. LLSpinCtrl* mAlphaCutoffCtrl;
  319. LLSpinCtrl* mMetalnessCtrl;
  320. LLSpinCtrl* mRoughnessCtrl;
  321. LLButton* mSaveButton;
  322. LLButton* mSaveAsButton;
  323. LLButton* mCancelButton;
  324. std::string mMaterialName;
  325. std::string mMaterialNameShort;
  326. // Last known name of each texture
  327. std::string mBaseColorName;
  328. std::string mMetallicRoughnessName;
  329. std::string mEmissiveName;
  330. std::string mNormalName;
  331. // Flags to indicate individual changed parameters
  332. U32 mUnsavedChanges;
  333. // Flags to indicate individual reverted parameters
  334. U32 mRevertedChanges;
  335. S32 mUploadingTexturesCount;
  336. S32 mExpectedUploadCost;
  337. bool mIsOverride;
  338. bool mCanCopy;
  339. bool mCanModify;
  340. bool mHasSelection;
  341. bool mUploadingTexturesFailure;
  342. };
  343. #endif // LL_LLPREVIEWMATERIAL_H