diff options
-rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 4 | ||||
-rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 2 | ||||
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 146 | ||||
-rw-r--r-- | indra/newview/llfloaterregioninfo.h | 89 | ||||
-rw-r--r-- | indra/newview/llpbrterrainfeatures.cpp | 198 | ||||
-rw-r--r-- | indra/newview/llpbrterrainfeatures.h | 48 | ||||
-rwxr-xr-x | indra/newview/llviewerregion.cpp | 43 | ||||
-rw-r--r-- | indra/newview/llvlcomposition.cpp | 30 | ||||
-rw-r--r-- | indra/newview/llvlcomposition.h | 26 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_region_terrain_texture_transform.xml | 263 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_settings_terrain_elevation.xml | 307 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_settings_terrain_transform.xml | 365 |
14 files changed, 1456 insertions, 78 deletions
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 94bc5ef74c..008c72462c 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -681,7 +681,7 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) } } -void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) +void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) const { LL_PROFILE_ZONE_SCOPED; llassert(data.isUndefined()); @@ -690,7 +690,7 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) { - LLUUID& texture_id = mTextureId[i]; + const LLUUID& texture_id = mTextureId[i]; const LLUUID& override_texture_id = override_mat.mTextureId[i]; if (override_texture_id.notNull() && override_texture_id != texture_id) { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 67b22f56e2..e04b6d5eee 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -202,7 +202,7 @@ public: // Get the given override on this LLGLTFMaterial as LLSD // override_mat -- the override source data // data -- output LLSD object (should be passed in empty) - void getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data); + void getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) const; // For base materials only (i.e. assets). Clears transforms to // default since they're not supported in assets yet. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e56534b84d..7568c08430 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -502,6 +502,7 @@ set(viewer_SOURCE_FILES llpathfindingobject.cpp llpathfindingobjectlist.cpp llpathfindingpathtool.cpp + llpbrterrainfeatures.cpp llpersistentnotificationstorage.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp @@ -1148,6 +1149,7 @@ set(viewer_HEADER_FILES llpathfindingobject.h llpathfindingobjectlist.h llpathfindingpathtool.h + llpbrterrainfeatures.h llpersistentnotificationstorage.h llphysicsmotion.h llphysicsshapebuilderutil.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3dc72553dc..498b14e211 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9308,6 +9308,17 @@ <key>Value</key> <real>8.0</real> </map> + <key>RenderTerrainPBRTransformsEnabled</key> + <map> + <key>Comment</key> + <string>EXPERIMENTAL: Enable PBR Terrain texture transforms.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderTerrainPBRNormalsEnabled</key> <map> <key>Comment</key> diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 1f84da4b07..1c4874eae5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -68,6 +68,7 @@ #include "llnamelistctrl.h" #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llpbrterrainfeatures.h" #include "llregioninfomodel.h" #include "llscrolllistitem.h" #include "llsliderctrl.h" @@ -263,7 +264,16 @@ bool LLFloaterRegionInfo::postBuild() panel = new LLPanelRegionTerrainInfo; mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_terrain.xml"); + static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); + static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false); + if (!feature_pbr_terrain_transforms_enabled || !feature_pbr_terrain_enabled) + { + panel->buildFromFile("panel_region_terrain.xml"); + } + else + { + panel->buildFromFile("panel_region_terrain_texture_transform.xml"); + } mTab->addTabPanel(panel); mEnvironmentPanel = new LLPanelRegionEnvironment; @@ -554,6 +564,20 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) } // static +void LLFloaterRegionInfo::sRefreshFromRegion(LLViewerRegion* region) +{ + if (region != gAgent.getRegion()) { return; } + + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); + if (!floater) { return; } + + if (floater->getVisible() && region == gAgent.getRegion()) + { + floater->refreshFromRegion(region); + } +} + +// static LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() { LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); @@ -825,6 +849,13 @@ void LLPanelRegionInfo::initCtrl(const std::string& name) getChild<LLUICtrl>(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this)); } +template<typename CTRL> +void LLPanelRegionInfo::initAndSetCtrl(CTRL*& ctrl, const std::string& name) +{ + initCtrl(name); + ctrl = findChild<CTRL>(name); +} + void LLPanelRegionInfo::onClickManageTelehub() { LLFloaterReg::hideInstance("region_info"); @@ -1494,11 +1525,17 @@ LLPanelRegionTerrainInfo::LLPanelRegionTerrainInfo() const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { + mTextureDetailCtrl[i] = nullptr; + mMaterialDetailCtrl[i] = nullptr; + mLastSetTextures[i] = default_textures[i]; - } - for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) - { mLastSetMaterials[i] = BLANK_MATERIAL_ASSET_ID; + + mMaterialScaleUCtrl[i] = nullptr; + mMaterialScaleVCtrl[i] = nullptr; + mMaterialRotationCtrl[i] = nullptr; + mMaterialOffsetUCtrl[i] = nullptr; + mMaterialOffsetVCtrl[i] = nullptr; } } @@ -1519,19 +1556,18 @@ bool LLPanelRegionTerrainInfo::postBuild() for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - initCtrl(buffer); - mTextureDetailCtrl[i] = findChild<LLTextureCtrl>(buffer); - if (mTextureDetailCtrl) + initAndSetCtrl(mTextureDetailCtrl[i], llformat("texture_detail_%d", i)); + if (mTextureDetailCtrl[i]) { mTextureDetailCtrl[i]->setBakeTextureEnabled(false); } - } - for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - initCtrl(buffer); - mMaterialDetailCtrl[i] = findChild<LLTextureCtrl>(buffer); + initAndSetCtrl(mMaterialDetailCtrl[i], llformat("material_detail_%d", i)); + + initAndSetCtrl(mMaterialScaleUCtrl[i], llformat("terrain%dScaleU", i)); + initAndSetCtrl(mMaterialScaleVCtrl[i], llformat("terrain%dScaleV", i)); + initAndSetCtrl(mMaterialRotationCtrl[i], llformat("terrain%dRotation", i)); + initAndSetCtrl(mMaterialOffsetUCtrl[i], llformat("terrain%dOffsetU", i)); + initAndSetCtrl(mMaterialOffsetVCtrl[i], llformat("terrain%dOffsetV", i)); } for(S32 i = 0; i < CORNER_COUNT; ++i) @@ -1583,6 +1619,17 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() } } + // Toggle visibility of terrain tabs + LLTabContainer* terrain_tabs = findChild<LLTabContainer>("terrain_tabs"); + if (terrain_tabs) + { + LLPanel* pbr_terrain_repeats_tab = findChild<LLPanel>("terrain_transform_panel"); + if (pbr_terrain_repeats_tab) + { + terrain_tabs->setTabVisibility(pbr_terrain_repeats_tab, show_material_controls); + } + } + // Toggle visibility of labels LLUICtrl* texture_label = findChild<LLUICtrl>("detail_texture_text"); if (texture_label) { texture_label->setVisible(show_texture_controls); } @@ -1711,6 +1758,21 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) } } + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + if (!mMaterialScaleUCtrl[i] || !mMaterialScaleVCtrl[i] || !mMaterialRotationCtrl[i] || !mMaterialOffsetUCtrl[i] || !mMaterialOffsetVCtrl[i]) { continue; } + const LLGLTFMaterial* mat_override = compp->getMaterialOverride(i); + if (!mat_override) { mat_override = &LLGLTFMaterial::sDefault; } + + // Assume all texture transforms have the same value + const LLGLTFMaterial::TextureTransform& transform = mat_override->mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]; + mMaterialScaleUCtrl[i]->setValue(transform.mScale.mV[VX]); + mMaterialScaleVCtrl[i]->setValue(transform.mScale.mV[VY]); + mMaterialRotationCtrl[i]->setValue(transform.mRotation * RAD_TO_DEG); + mMaterialOffsetUCtrl[i]->setValue(transform.mOffset.mV[VX]); + mMaterialOffsetVCtrl[i]->setValue(transform.mOffset.mV[VY]); + } + std::string buffer; for(S32 i = 0; i < CORNER_COUNT; ++i) { @@ -1725,7 +1787,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LL_DEBUGS() << "no region set" << LL_ENDL; getChild<LLUICtrl>("region_text")->setValue(LLSD("")); } - + // Update visibility of terrain swatches, etc refresh(); @@ -1740,7 +1802,14 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) // virtual bool LLPanelRegionTerrainInfo::sendUpdate() { - LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL; + LL_INFOS() << __FUNCTION__ << LL_ENDL; + + LLUICtrl* apply_btn = getChild<LLUICtrl>("apply_btn"); + if (apply_btn && !apply_btn->getEnabled()) + { + LL_WARNS() << "Duplicate update, ignored" << LL_ENDL; + return false; + } // Make sure user hasn't chosen wacky textures. if (!validateTextureSizes()) @@ -1841,6 +1910,51 @@ bool LLPanelRegionTerrainInfo::sendUpdate() sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); + // ======================================== + // POST to ModifyRegion endpoint, if enabled + + static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false); + if (material_type == LLTerrainMaterials::Type::PBR && feature_pbr_terrain_transforms_enabled) + { + LLTerrainMaterials composition; + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLPointer<LLGLTFMaterial> mat_override = new LLGLTFMaterial(); + + const bool transform_controls_valid = mMaterialScaleUCtrl[i] && mMaterialScaleVCtrl[i] && mMaterialRotationCtrl[i] && mMaterialOffsetUCtrl[i] && mMaterialOffsetVCtrl[i]; + if (transform_controls_valid) + { + // Set texture transforms for all texture infos to the same value, + // because the PBR terrain shader doesn't currently support + // different transforms per texture info. See also + // LLDrawPoolTerrain::renderFullShaderPBR . + for (U32 tt = 0; tt < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++tt) + { + LLGLTFMaterial::TextureTransform& transform = mat_override->mTextureTransform[tt]; + transform.mScale.mV[VX] = mMaterialScaleUCtrl[i]->getValue().asReal(); + transform.mScale.mV[VY] = mMaterialScaleVCtrl[i]->getValue().asReal(); + transform.mRotation = mMaterialRotationCtrl[i]->getValue().asReal() * DEG_TO_RAD; + transform.mOffset.mV[VX] = mMaterialOffsetUCtrl[i]->getValue().asReal(); + transform.mOffset.mV[VY] = mMaterialOffsetVCtrl[i]->getValue().asReal(); + } + } + + if (*mat_override == LLGLTFMaterial::sDefault) { mat_override = nullptr; } + composition.setMaterialOverride(i, mat_override.get()); + } + + // queueModify leads to a few messages being sent back and forth: + // viewer: POST ModifyRegion + // simulator: RegionHandshake + // viewer: GET ModifyRegion + LLViewerRegion* region = gAgent.getRegion(); + llassert(region); + if (region) + { + LLPBRTerrainFeatures::queueModify(*region, composition); + } + } + return true; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 4b81a26210..1634683d90 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -1,4 +1,4 @@ -/** +/** * @file llfloaterregioninfo.h * @author Aaron Brashears * @brief Declaration of the region info and controls floater and panels. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -85,6 +85,7 @@ public: // get and process region info if necessary. static void processRegionInfo(LLMessageSystem* msg); + static void sRefreshFromRegion(LLViewerRegion* region); static const LLUUID& getLastInvoice() { return sRequestInvoice; } static void nextInvoice() { sRequestInvoice.generate(); } @@ -101,14 +102,14 @@ public: // from LLPanel void refresh() override; - + void onRegionChanged(); void requestRegionInfo(); void enableTopButtons(); void disableTopButtons(); private: - + LLFloaterRegionInfo(const LLSD& seed); ~LLFloaterRegionInfo(); @@ -137,30 +138,31 @@ class LLPanelRegionInfo : public LLPanel { public: LLPanelRegionInfo(); - + void onBtnSet(); void onChangeChildCtrl(LLUICtrl* ctrl); void onChangeAnything(); static void onChangeText(LLLineEditor* caller, void* user_data); - + virtual bool refreshFromRegion(LLViewerRegion* region); virtual bool estateUpdate(LLMessageSystem* msg) { return true; } - + bool postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); - + void enableButton(const std::string& btn_name, bool enable = true); void disableButton(const std::string& btn_name); - + void onClickManageTelehub(); - + protected: void initCtrl(const std::string& name); - + template<typename CTRL> void initAndSetCtrl(CTRL*& ctrl, const std::string& name); + // Returns true if update sent and apply button should be // disabled. virtual bool sendUpdate() { return true; } - + typedef std::vector<std::string> strings_t; //typedef std::vector<U32> integers_t; void sendEstateOwnerMessage( @@ -168,8 +170,8 @@ protected: const std::string& request, const LLUUID& invoice, const strings_t& strings); - - + + // member data LLHost mHost; }; @@ -180,16 +182,16 @@ protected: class LLPanelRegionGeneralInfo : public LLPanelRegionInfo { - + public: LLPanelRegionGeneralInfo() : LLPanelRegionInfo() {} ~LLPanelRegionGeneralInfo() {} - + bool refreshFromRegion(LLViewerRegion* region) override; - + bool postBuild() override; - + void onBtnSet(); void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;} @@ -217,9 +219,9 @@ public: ~LLPanelRegionDebugInfo() {} bool postBuild() override; - + bool refreshFromRegion(LLViewerRegion* region) override; - + protected: bool sendUpdate() override; @@ -233,7 +235,7 @@ protected: bool callbackRestart(const LLSD& notification, const LLSD& response); static void onClickCancelRestart(void* data); static void onClickDebugConsole(void* data); - + private: LLUUID mTargetAvatar; }; @@ -247,9 +249,9 @@ class LLPanelRegionTerrainInfo : public LLPanelRegionInfo public: LLPanelRegionTerrainInfo(); ~LLPanelRegionTerrainInfo() {} - + bool postBuild() override; - + bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region @@ -258,7 +260,7 @@ public: bool validateTextureHeights(); //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button - + void onSelectMaterialType(); void updateForMaterialType(); @@ -277,8 +279,15 @@ private: LLCheckBoxCtrl* mMaterialTypeCtrl = nullptr; LLTextureCtrl* mTextureDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; LLTextureCtrl* mMaterialDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT]; LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT]; + + LLSpinCtrl* mMaterialScaleUCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLSpinCtrl* mMaterialScaleVCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLSpinCtrl* mMaterialRotationCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLSpinCtrl* mMaterialOffsetUCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLSpinCtrl* mMaterialOffsetVCtrl[LLTerrainMaterials::ASSET_COUNT]; }; ///////////////////////////////////////////////////////////////////////////// @@ -287,13 +296,13 @@ class LLPanelEstateInfo : public LLPanelRegionInfo { public: static void initDispatch(LLDispatcher& dispatch); - + void onChangeFixedSun(); void onChangeUseGlobalTime(); void onChangeAccessOverride(); - + void onClickEditSky(); - void onClickEditSkyHelp(); + void onClickEditSkyHelp(); void onClickEditDayCycle(); void onClickEditDayCycleHelp(); @@ -305,26 +314,26 @@ public: void onKickUserCommit(const uuid_vec_t& ids); static void onClickMessageEstate(void* data); bool onMessageCommit(const LLSD& notification, const LLSD& response); - + LLPanelEstateInfo(); ~LLPanelEstateInfo() {} - + void updateControls(LLViewerRegion* region); - + static void updateEstateName(const std::string& name); static void updateEstateOwnerName(const std::string& name); bool refreshFromRegion(LLViewerRegion* region) override; bool estateUpdate(LLMessageSystem* msg) override; - + bool postBuild() override; void updateChild(LLUICtrl* child_ctrl) override; void refresh() override; void refreshFromEstate(); - + static bool isLindenEstate(); - + const std::string getOwnerName() const; void setOwnerName(const std::string& name); @@ -335,7 +344,7 @@ protected: void commitEstateAccess(); void commitEstateManagers(); - + bool checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; @@ -348,7 +357,7 @@ class LLPanelEstateCovenant : public LLPanelRegionInfo public: LLPanelEstateCovenant(); ~LLPanelEstateCovenant() {} - + bool postBuild() override; void updateChild(LLUICtrl* child_ctrl) override; bool refreshFromRegion(LLViewerRegion* region) override; @@ -411,7 +420,7 @@ class LLPanelRegionExperiences : public LLPanelRegionInfo public: LLPanelRegionExperiences(){} bool postBuild() override; - + static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); @@ -473,7 +482,7 @@ private: void onAllowedSearchEdit(const std::string& search_string); void onAllowedGroupsSearchEdit(const std::string& search_string); void onBannedSearchEdit(const std::string& search_string); - + // Group picker callback is different, can't use core methods below bool addAllowedGroup(const LLSD& notification, const LLSD& response); void addAllowedGroup2(LLUUID id); diff --git a/indra/newview/llpbrterrainfeatures.cpp b/indra/newview/llpbrterrainfeatures.cpp new file mode 100644 index 0000000000..bb771c6963 --- /dev/null +++ b/indra/newview/llpbrterrainfeatures.cpp @@ -0,0 +1,198 @@ +/** + * @file llpbrterrainfeatures.cpp + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpbrterrainfeatures.h" + +#include "llappviewer.h" +#include "llgltfmaterial.h" +#include "llviewerregion.h" +#include "llvlcomposition.h" + +LLPBRTerrainFeatures gPBRTerrainFeatures; + +// static +void LLPBRTerrainFeatures::queueQuery(LLViewerRegion& region, void(*done_callback)(LLUUID, bool, const LLModifyRegion&)) +{ + llassert(on_main_thread()); + llassert(LLCoros::on_main_coro()); + + LLUUID region_id = region.getRegionID(); + + LLCoros::instance().launch("queryRegionCoro", + std::bind(&LLPBRTerrainFeatures::queryRegionCoro, + region.getCapability("ModifyRegion"), + region_id, + done_callback)); +} + +// static +void LLPBRTerrainFeatures::queueModify(LLViewerRegion& region, const LLModifyRegion& composition) +{ + llassert(on_main_thread()); + llassert(LLCoros::on_main_coro()); + + LLSD updates = LLSD::emptyMap(); + + LLSD override_updates = LLSD::emptyArray(); + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + const LLGLTFMaterial* material_override = composition.getMaterialOverride(i); + LLSD override_update; + if (material_override) + { + LLGLTFMaterial::sDefault.getOverrideLLSD(*material_override, override_update); + } + else + { + override_update = LLSD::emptyMap(); + } + override_updates.append(override_update); + } + updates["overrides"] = override_updates; + + LLCoros::instance().launch("modifyRegionCoro", + std::bind(&LLPBRTerrainFeatures::modifyRegionCoro, + region.getCapability("ModifyRegion"), + updates, + nullptr)); +} + +// static +void LLPBRTerrainFeatures::queryRegionCoro(std::string cap_url, LLUUID region_id, void(*done_callback)(LLUUID, bool, const LLModifyRegion&) ) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("queryRegionCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + + LL_DEBUGS("GLTF") << "Querying features via ModifyRegion endpoint" << LL_ENDL; + + LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + bool success = true; + if (!status || !result["success"].asBoolean()) + { + if (result["message"].isUndefined()) + { + LL_WARNS("PBRTerrain") << "Failed to query PBR terrain features." << LL_ENDL; + } + else + { + LL_WARNS("PBRTerrain") << "Failed to query PBR terrain features: " << result["message"] << LL_ENDL; + } + success = false; + } + + LLTerrainMaterials* composition = new LLTerrainMaterials(); + + if (success) + { + const LLSD& overrides = result["overrides"]; + if (!overrides.isArray() || overrides.size() < LLTerrainMaterials::ASSET_COUNT) + { + LL_WARNS("PBRTerrain") << "Invalid composition format: Missing/invalid overrides" << LL_ENDL; + success = false; + } + else + { + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + const LLSD& override_llsd = overrides[i]; + LLPointer<LLGLTFMaterial> material_override = new LLGLTFMaterial(); + material_override->applyOverrideLLSD(override_llsd); + if (*material_override == LLGLTFMaterial::sDefault) + { + material_override = nullptr; + } + composition->setMaterialOverride(i, material_override.get()); + } + } + } + + if (done_callback) + { + LLAppViewer::instance()->postToMainCoro([=]() + { + done_callback(region_id, success, *composition); + delete composition; + }); + } + else + { + delete composition; + } +} + +// static +void LLPBRTerrainFeatures::modifyRegionCoro(std::string cap_url, LLSD updates, void(*done_callback)(bool) ) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyRegionCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + + LL_DEBUGS("GLTF") << "Applying features via ModifyRegion endpoint: " << updates << LL_ENDL; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, updates, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + bool success = true; + if (!status || !result["success"].asBoolean()) + { + if (result["message"].isUndefined()) + { + LL_WARNS("PBRTerrain") << "Failed to modify PBR terrain features." << LL_ENDL; + } + else + { + LL_WARNS("PBRTerrain") << "Failed to modify PBR terrain features: " << result["message"] << LL_ENDL; + } + success = false; + } + + if (done_callback) + { + LLAppViewer::instance()->postToMainCoro([=]() + { + done_callback(success); + }); + } +} + diff --git a/indra/newview/llpbrterrainfeatures.h b/indra/newview/llpbrterrainfeatures.h new file mode 100644 index 0000000000..f29d4ebf50 --- /dev/null +++ b/indra/newview/llpbrterrainfeatures.h @@ -0,0 +1,48 @@ +/** + * @file llpbrterrainfeatures.h + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#pragma once + +#include <string> + +class LLViewerRegion; +class LLMessageSystem; +class LLModifyRegion; + +// Queries/modifies PBR terrain repeats, possibly other features in the future +class LLPBRTerrainFeatures +{ +public: + static void queueQuery(LLViewerRegion& region, void(*done_callback)(LLUUID, bool, const LLModifyRegion&)); + static void queueModify(LLViewerRegion& region, const LLModifyRegion& composition); + +private: + static void queryRegionCoro(std::string cap_url, LLUUID region_id, void(*done_callback)(LLUUID, bool, const LLModifyRegion&) ); + static void modifyRegionCoro(std::string cap_url, LLSD updates, void(*done_callback)(bool) ); +}; + +extern LLPBRTerrainFeatures gPBRTerrainFeatures; + diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index bf4bdfd252..699cde8969 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -55,6 +55,7 @@ #include "llfloaterregioninfo.h" #include "llgltfmateriallist.h" #include "llhttpnode.h" +#include "llpbrterrainfeatures.h" #include "llregioninfomodel.h" #include "llsdutil.h" #include "llstartup.h" @@ -2462,6 +2463,26 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) gSavedSettings.setS32("max_texture_dimension_Y", 1024); } + if (features.has("PBRTerrainEnabled")) + { + bool enabled = features["PBRTerrainEnabled"]; + gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled); + } + else + { + gSavedSettings.setBOOL("RenderTerrainPBREnabled", false); + } + + if (features.has("PBRMaterialSwatchEnabled")) + { + bool enabled = features["PBRMaterialSwatchEnabled"]; + gSavedSettings.setBOOL("UIPreviewMaterial", enabled); + } + else + { + gSavedSettings.setBOOL("UIPreviewMaterial", false); + } + if (features.has("GLTFEnabled")) { bool enabled = features["GLTFEnabled"]; @@ -2471,6 +2492,16 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) { gSavedSettings.setBOOL("GLTFEnabled", false); } + + if (features.has("PBRTerrainTransformsEnabled")) + { + bool enabled = features["PBRTerrainTransformsEnabled"]; + gSavedSettings.setBOOL("RenderTerrainTransformsPBREnabled", enabled); + } + else + { + gSavedSettings.setBOOL("RenderTerrainTransformsPBREnabled", false); + } }; @@ -3109,6 +3140,17 @@ void LLViewerRegion::unpackRegionHandshake() { compp->setParamsReady(); } + + LLPBRTerrainFeatures::queueQuery(*this, [](LLUUID region_id, bool success, const LLModifyRegion& composition_changes) + { + if (!success) { return; } + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(region_id); + if (!region) { return; } + LLVLComposition* compp = region->getComposition(); + if (!compp) { return; } + compp->apply(composition_changes); + LLFloaterRegionInfo::sRefreshFromRegion(region); + }); } @@ -3206,6 +3248,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("MapLayerGod"); capabilityNames.append("MeshUploadFlag"); capabilityNames.append("ModifyMaterialParams"); + capabilityNames.append("ModifyRegion"); capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ObjectAnimation"); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index bc2fab99c0..c509d656e1 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvlcomposition.cpp * @brief Viewer-side representation of a composition layer... * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -115,6 +115,16 @@ LLTerrainMaterials::~LLTerrainMaterials() unboost(); } +void LLTerrainMaterials::apply(const LLModifyRegion& other) +{ + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + const LLGLTFMaterial* other_override = other.getMaterialOverride(i); + LLGLTFMaterial* material_override = other_override ? new LLGLTFMaterial(*other_override) : nullptr; + setMaterialOverride(i, material_override); + } +} + bool LLTerrainMaterials::generateMaterials() { if (texturesReady(true, true)) @@ -192,7 +202,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -const LLGLTFMaterial* LLTerrainMaterials::getMaterialOverride(S32 asset) +const LLGLTFMaterial* LLTerrainMaterials::getMaterialOverride(S32 asset) const { return mDetailMaterialOverrides[asset]; } @@ -461,7 +471,7 @@ bool LLVLComposition::generateHeights(const F32 x, const F32 y, llassert(mSurfacep); - if (!mSurfacep || !mSurfacep->getRegion()) + if (!mSurfacep || !mSurfacep->getRegion()) { // We don't always have the region yet here.... return false; @@ -529,7 +539,7 @@ bool LLVLComposition::generateHeights(const F32 x, const F32 y, vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; vec[2] = height*zScaleInv; // - // Choose material value by adding to the exact height a random value + // Choose material value by adding to the exact height a random value // vec1[0] = vec[0]*(0.2222222222f); vec1[1] = vec[1]*(0.2222222222f); @@ -863,7 +873,7 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, U32 st_comps = 3; U32 st_width = BASE_SIZE; U32 st_height = BASE_SIZE; - + if (tex_comps != st_comps) { llassert(false); @@ -968,7 +978,7 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { unboost_minimap_material(mDetailMaterials[i]); } - + return true; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index f7590348f0..a003f74eda 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -1,25 +1,25 @@ -/** +/** * @file llvlcomposition.h * @brief Viewer-side representation of a composition layer... * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,7 +38,13 @@ class LLViewerFetchedTexture; class LLGLTFMaterial; class LLFetchedGLTFMaterial; -class LLTerrainMaterials +class LLModifyRegion +{ +public: + virtual const LLGLTFMaterial* getMaterialOverride(S32 asset) const = 0; +}; + +class LLTerrainMaterials : public LLModifyRegion { public: friend class LLDrawPoolTerrain; @@ -46,6 +52,8 @@ public: LLTerrainMaterials(); virtual ~LLTerrainMaterials(); + void apply(const LLModifyRegion& other); + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; @@ -63,7 +71,7 @@ public: virtual LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - virtual const LLGLTFMaterial* getMaterialOverride(S32 asset); + const LLGLTFMaterial* getMaterialOverride(S32 asset) const override; virtual void setMaterialOverride(S32 asset, LLGLTFMaterial* mat_override); Type getMaterialType(); bool texturesReady(bool boost, bool strict); @@ -107,8 +115,8 @@ public: bool generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); bool generateComposition(); // Generate texture from composition values. - bool generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); - bool generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); + bool generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); + bool generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); // Use these as indeces ito the get/setters below that use 'corner' enum ECorner diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain_texture_transform.xml b/indra/newview/skins/default/xui/en/panel_region_terrain_texture_transform.xml new file mode 100644 index 0000000000..cbcbe418cd --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_region_terrain_texture_transform.xml @@ -0,0 +1,263 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel + border="true" + follows="top|left" + height="460" + help_topic="panel_region_terrain_tab" + label="Terrain" + layout="topleft" + left="0" + name="Terrain" + top="320" + width="480"> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left="10" + name="region_text_lbl" + top="10" + width="100"> + Region: + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="region_text" + top_delta="0" + width="400"> + unknown + </text> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="detail_texture_text" + left="10" + top="35" + width="170"> + Terrain Textures + </text> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="detail_material_text" + left="10" + top="35" + width="170"> + Terrain Materials + </text> + <check_box + height="20" + halign="left" + valign="center" + follows="left|top" + layout="topleft" + top_delta="1" + left_delta="180" + label="PBR Metallic Roughness" + name="terrain_material_type" + tool_tip="If checked, use PBR Metallic Roughness materials for terrain. Otherwise, use textures." + left_pad="2" + width="200" /> + <texture_picker + follows="left|top" + height="121" + layout="topleft" + left="10" + name="texture_detail_0" + default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5" + top_delta="30" + width="100" /> + <texture_picker + follows="top" + height="121" + layout="topleft" + left_pad="10" + name="texture_detail_1" + default_image_id="63338ede-0037-c4fd-855b-015d77112fc8" + top_delta="0" + width="100" /> + <texture_picker + follows="left|top" + height="121" + layout="topleft" + left_pad="10" + name="texture_detail_2" + default_image_id="303cd381-8560-7579-23f1-f0a880799740" + top_delta="0" + width="100" /> + <texture_picker + follows="left|top" + height="121" + layout="topleft" + left_pad="10" + name="texture_detail_3" + default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c" + top_delta="0" + width="100" /> + <texture_picker + visible="false" + follows="left|top" + height="121" + layout="topleft" + left="10" + name="material_detail_0" + pick_type="material" + default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a" + top_delta="0" + width="100" /> + <texture_picker + visible="false" + follows="left|top" + height="121" + layout="topleft" + left_pad="10" + name="material_detail_1" + pick_type="material" + default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a" + top_delta="0" + width="100" /> + <texture_picker + visible="false" + follows="left|top" + height="121" + layout="topleft" + left_pad="10" + name="material_detail_2" + pick_type="material" + default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a" + top_delta="0" + width="100" /> + <texture_picker + visible="false" + follows="left|top" + height="121" + layout="topleft" + left_pad="10" + name="material_detail_3" + pick_type="material" + default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a" + top_delta="0" + width="100" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl" + top_delta="104" + width="65"> + 1 (Low) + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="45" + name="height_text_lbl2" + top_delta="0" + width="100"> + 2 + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl3" + top_delta="0" + width="100"> + 3 + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl4" + top_delta="0" + width="100"> + 4 (High) + </text> + <layout_stack name="terrain_features_stack" + width="477" + height="230" + follows="all" + animate="false" + left="0" + top_delta="22" + orientation="vertical"> + <layout_panel name="frame_settings_terrain" + auto_resize="true" + user_resize="false" + height="230" + width="467" + min_height="0" + visible="true"> + <tab_container + follows="all" + halign="left" + height="230" + visible="true" + layout="topleft" + left="0" + name="terrain_tabs" + tab_position="top" + tab_width="100" + tab_padding_right="3" + top_pad="0" + width="700"> + <panel + border="true" + class="panel_settings_terrain_elevation" + filename="panel_settings_terrain_elevation.xml" + label="Elevation" + layout="topleft" + left_delta="0" + top_pad="5" + name="terrain_elevation_panel" /> + <panel + border="true" + class="panel_settings_terrain_transform" + filename="panel_settings_terrain_transform.xml" + label="Transforms" + layout="topleft" + left_delta="0" + top_pad="5" + name="terrain_transform_panel" /> + </tab_container> + </layout_panel> + </layout_stack> + <button + enabled="true" + follows="left|top" + height="20" + label="Apply" + layout="topleft" + left="353" + name="apply_btn" + top_delta="290" + width="100" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_terrain_elevation.xml b/indra/newview/skins/default/xui/en/panel_settings_terrain_elevation.xml new file mode 100644 index 0000000000..89443290ce --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_terrain_elevation.xml @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel + border="true" + follows="all" + label="Elevation" + layout="topleft" + left="0" + name="panel_settings_terrain_elevation" + top="0"> + <spinner + follows="left|top" + height="20" + label="Water Height" + label_width="120" + layout="topleft" + left="15" + max_val="100" + name="water_height_spin" + top_delta="18" + width="180" /> + <spinner + follows="left|top" + height="20" + increment="0.2" + label="Terrain Raise Limit" + label_width="120" + layout="topleft" + left="240" + max_val="100" + name="terrain_raise_spin" + top_delta="0" + width="180" /> + <spinner + follows="left|top" + height="20" + increment="0.2" + label="Terrain Lower Limit" + label_width="120" + layout="topleft" + left="240" + max_val="0" + min_val="-100" + name="terrain_lower_spin" + top_delta="20" + width="180" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + left="8" + top_delta="-30" + width="460" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl5" + top_delta="74" + width="300"> + Texture Elevation Ranges + </text> + <text + visible="false" + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl5_material" + top_delta="0" + width="300"> + Material Elevation Ranges + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl10" + top_delta="30" + width="200" + word_wrap="true"> + These values represent the blend range for the textures above. + </text> + <text + visible="false" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl10_material" + top_delta="0" + width="200" + word_wrap="true"> + These values represent the blend range for the materials above. + </text> + <text + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + name="height_text_lbl11" + top_delta="32" + width="200" + word_wrap="true"> + Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4. + </text> + <text + visible="false" + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + name="height_text_lbl11_material" + top_delta="0" + width="200" + word_wrap="true"> + Measured in meters, the LOW value is the MAXIMUM height of Material #1, and the HIGH value is the MINIMUM height of Material #4. + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left="270" + name="height_text_lbl6" + top_delta="-62" + width="100"> + Northwest + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl7" + top_delta="0" + width="100"> + Northeast + </text> +<!-- northwest low--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left="230" + max_val="500" + min_val="-500" + name="height_start_spin_1" + top_delta="15" + width="100" /> +<!-- northeast low--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_start_spin_3" + top_delta="0" + width="100" /> +<!-- northwest high--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left="230" + max_val="500" + min_val="-500" + name="height_range_spin_1" + top_delta="20" + width="100" /> +<!-- northeast high--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_range_spin_3" + top_delta="0" + width="100" /> + <text + follows="left|top" + height="20" + layout="topleft" + left="270" + name="height_text_lbl8" + top_pad="10" + width="100"> + Southwest + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl9" + top_delta="0" + width="100"> + Southeast + </text> +<!-- southwest low--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left="230" + max_val="500" + min_val="-500" + name="height_start_spin_0" + top_delta="15" + width="100" /> +<!-- southeast low--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_start_spin_2" + top_delta="0" + width="100" /> +<!--southwest high--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left="230" + max_val="500" + min_val="-500" + name="height_range_spin_0" + top_delta="20" + width="100" /> +<!-- southeast high--> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_range_spin_2" + top_delta="0" + width="100" /> +<!-- Terrain Download/Upload/Bake buttons --> + <button + follows="left|top" + height="20" + label="Download RAW terrain..." + layout="topleft" + left="10" + name="download_raw_btn" + tool_tip="Available only to estate owners, not managers" + top_delta="40" + width="160" /> + <button + follows="left|top" + height="20" + label="Upload RAW terrain..." + layout="topleft" + left_pad="10" + top_delta="0" + name="upload_raw_btn" + tool_tip="Available only to estate owners, not managers" + width="160" /> + <button + follows="left|top" + height="20" + label="Bake Terrain" + layout="topleft" + left_pad="10" + name="bake_terrain_btn" + tool_tip="Set current terrain as mid-point for raise/lower limits" + width="100" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_terrain_transform.xml b/indra/newview/skins/default/xui/en/panel_settings_terrain_transform.xml new file mode 100644 index 0000000000..7052622813 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_terrain_transform.xml @@ -0,0 +1,365 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel + border="true" + follows="all" + label="Samping" + layout="topleft" + left="0" + name="panel_settings_terrain_transform" + top="0"> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="terrain0ScaleU_label" + left="10" + top_pad="3" + width="170"> + Scale u + </text> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + top_pad="-2" + name="terrain0ScaleU_horizontal" + width="430" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left="10" + min_val="-100" + max_val="100" + name="terrain0ScaleU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain1ScaleU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain2ScaleU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain3ScaleU" + width="64" /> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="terrain0ScaleV_label" + left="10" + top_pad="3" + width="170"> + Scale v + </text> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + top_pad="-2" + name="terrain0ScaleV_horizontal" + width="430" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale v" + label_width="0" + layout="topleft" + left="10" + min_val="-100" + max_val="100" + name="terrain0ScaleV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain1ScaleV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain2ScaleV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="1" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain3ScaleV" + width="64" /> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="terrain0Rotation_label" + left="10" + top_pad="3" + width="170"> + Rotation + </text> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + top_pad="-2" + name="terrain0Rotation_horizontal" + width="430" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Rotation" + label_width="0" + layout="topleft" + left="10" + min_val="-360" + max_val="360" + name="terrain0Rotation" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain1Rotation" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain2Rotation" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain3Rotation" + width="64" /> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="terrain0OffsetU_label" + left="10" + top_pad="3" + width="170"> + Offset y + </text> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + top_pad="-2" + name="terrain0OffsetU_horizontal" + width="430" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Offset u" + label_width="0" + layout="topleft" + left="10" + min_val="-999" + max_val="999" + name="terrain0OffsetU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain1OffsetU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain2OffsetU" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain3OffsetU" + width="64" /> + <text + type="string" + length="1" + halign="left" + valign="center" + follows="left|top" + height="20" + layout="topleft" + name="terrain0OffsetV_label" + left="10" + top_pad="3" + width="170"> + Offset v + </text> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + top_pad="-2" + name="terrain0OffsetV_horizontal" + width="430" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Offset v" + label_width="0" + layout="topleft" + left="10" + min_val="-999" + max_val="999" + name="terrain0OffsetV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain1OffsetV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain2OffsetV" + width="64" /> + <spinner + follows="left|top" + height="19" + initial_value="0" + label="Scale u" + label_width="0" + layout="topleft" + left_delta="110" + min_val="-100" + max_val="100" + name="terrain3OffsetV" + width="64" /> +</panel> |