diff options
Diffstat (limited to 'indra/newview/llfloaterregioninfo.cpp')
-rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 527 |
1 files changed, 473 insertions, 54 deletions
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index a9ec392129..073cef3d73 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -62,11 +62,13 @@ #include "llfloaterreg.h" #include "llfloaterregiondebugconsole.h" #include "llfloatertelehub.h" +#include "llgltfmateriallist.h" #include "llinventorymodel.h" #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llpbrterrainfeatures.h" #include "llregioninfomodel.h" #include "llscrolllistitem.h" #include "llsliderctrl.h" @@ -86,7 +88,6 @@ #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" -#include "llvlcomposition.h" #include "lltrans.h" #include "llagentui.h" #include "llmeshrepository.h" @@ -100,7 +101,6 @@ #include "llavatarnamecache.h" #include "llenvironment.h" -const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; const U32 MAX_LISTED_NAMES = 100; @@ -264,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; @@ -340,7 +349,6 @@ void LLFloaterRegionInfo::onRegionChanged() } } -// static void LLFloaterRegionInfo::requestRegionInfo() { LLTabContainer* tab = findChild<LLTabContainer>("region_panels"); @@ -556,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"); @@ -605,6 +627,16 @@ LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment() return panel; } +LLTerrainMaterials::Type material_type_from_ctrl(LLCheckBoxCtrl* ctrl) +{ + return ctrl->get() ? LLTerrainMaterials::Type::PBR : LLTerrainMaterials::Type::TEXTURE; +} + +void material_type_to_ctrl(LLCheckBoxCtrl* ctrl, LLTerrainMaterials::Type new_type) +{ + ctrl->set(new_type == LLTerrainMaterials::Type::PBR); +} + // static LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() { @@ -817,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"); @@ -1307,16 +1346,23 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) bool LLPanelRegionTerrainInfo::validateTextureSizes() { - static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + if (mMaterialTypeCtrl) { - std::string buffer; - buffer = llformat("texture_detail_%d", i); - LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(buffer); + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); + const bool is_material_selected = material_type == LLTerrainMaterials::Type::PBR; + if (is_material_selected) { return true; } + } + + bool valid = true; + static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); + const S32 max_terrain_texture_size = (S32)max_texture_resolution; + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i]; if (!texture_ctrl) continue; LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); + LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); S32 components = img->getComponents(); // Must ask for highest resolution version's width. JC S32 width = img->getFullWidth(); @@ -1324,31 +1370,133 @@ bool LLPanelRegionTerrainInfo::validateTextureSizes() //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL; - if (components != 3) + if (components != 3 && components != 4) { LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); - args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; + args["MAX_SIZE"] = max_terrain_texture_size; LLNotificationsUtil::add("InvalidTerrainBitDepth", args); - return false; + valid = false; + continue; } - if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE) + if (components == 4) + { + if (!img->hasSavedRawImage()) + { + // Raw image isn't loaded yet + // Assume it's invalid due to presence of alpha channel + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + LLNotificationsUtil::add("InvalidTerrainAlphaNotFullyLoaded", args); + valid = false; + } + else + { + // Slower path: Calculate alpha from raw image pixels (not needed + // for GLTF materials, which use alphaMode to determine + // transparency) + // Raw image is pretty much guaranteed to be saved due to the texture swatches + LLImageRaw* raw = img->getSavedRawImage(); + if (raw->checkHasTransparentPixels()) + { + LLSD args; + args["TEXTURE_NUM"] = i+1; + LLNotificationsUtil::add("InvalidTerrainAlpha", args); + valid = false; + } + LL_WARNS() << "Terrain texture image in slot " << i << " with ID " << image_asset_id << " has alpha channel, but pixels are opaque. Is alpha being optimized away in the texture uploader?" << LL_ENDL; + } + } + + if (width > max_terrain_texture_size || height > max_terrain_texture_size) { LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_SIZE_X"] = width; args["TEXTURE_SIZE_Y"] = height; - args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; + args["MAX_SIZE"] = max_terrain_texture_size; LLNotificationsUtil::add("InvalidTerrainSize", args); - return false; + valid = false; + } + } + + return valid; +} +bool LLPanelRegionTerrainInfo::validateMaterials() +{ + if (mMaterialTypeCtrl) + { + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); + const bool is_texture_selected = material_type == LLTerrainMaterials::Type::TEXTURE; + if (is_texture_selected) { return true; } + } + + // *TODO: If/when we implement additional GLTF extensions, they may not be + // compatible with our GLTF terrain implementation. We may want to disallow + // materials with some features from being set on terrain, if their + // implementation on terrain is not compliant with the spec: + // - KHR_materials_transmission: Probably OK? + // - KHR_materials_ior: Probably OK? + // - KHR_materials_volume: Likely incompatible, as our terrain + // heightmaps cannot currently be described as finite enclosed + // volumes. + // See also LLGLTFMaterial +#ifdef LL_WINDOWS + llassert(sizeof(LLGLTFMaterial) == 232); +#endif + + bool valid = true; + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i]; + if (!material_ctrl) { continue; } + + const LLUUID& material_asset_id = material_ctrl->getImageAssetID(); + llassert(material_asset_id.notNull()); + if (material_asset_id.isNull()) { return false; } + const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id); + if (!material->isLoaded()) + { + if (material->isFetching()) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialNotLoaded", args); + } + else // Loading failed + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialLoadFailed", args); + } + valid = false; + continue; + } + + if (material->mDoubleSided) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialDoubleSided", args); + valid = false; + } + if (material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE && material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_MASK) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + const char* alpha_mode = material->getAlphaMode(); + args["MATERIAL_ALPHA_MODE"] = alpha_mode; + LLNotificationsUtil::add("InvalidTerrainMaterialAlphaMode", args); + valid = false; } } - return true; + return valid; } bool LLPanelRegionTerrainInfo::validateTextureHeights() @@ -1370,6 +1518,27 @@ bool LLPanelRegionTerrainInfo::validateTextureHeights() ///////////////////////////////////////////////////////////////////////////// // LLPanelRegionTerrainInfo ///////////////////////////////////////////////////////////////////////////// + +LLPanelRegionTerrainInfo::LLPanelRegionTerrainInfo() +: LLPanelRegionInfo() +{ + 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]; + mLastSetMaterials[i] = BLANK_MATERIAL_ASSET_ID; + + mMaterialScaleUCtrl[i] = nullptr; + mMaterialScaleVCtrl[i] = nullptr; + mMaterialRotationCtrl[i] = nullptr; + mMaterialOffsetUCtrl[i] = nullptr; + mMaterialOffsetVCtrl[i] = nullptr; + } +} + // Initialize statics bool LLPanelRegionTerrainInfo::postBuild() @@ -1380,11 +1549,25 @@ bool LLPanelRegionTerrainInfo::postBuild() initCtrl("terrain_raise_spin"); initCtrl("terrain_lower_spin"); + mMaterialTypeCtrl = findChild<LLCheckBoxCtrl>("terrain_material_type"); + if (mMaterialTypeCtrl) { mMaterialTypeCtrl->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); } + std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - initCtrl(buffer); + initAndSetCtrl(mTextureDetailCtrl[i], llformat("texture_detail_%d", i)); + if (mTextureDetailCtrl[i]) + { + mTextureDetailCtrl[i]->setBakeTextureEnabled(false); + } + 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) @@ -1405,6 +1588,68 @@ bool LLPanelRegionTerrainInfo::postBuild() return LLPanelRegionInfo::postBuild(); } +void LLPanelRegionTerrainInfo::onSelectMaterialType() +{ + updateForMaterialType(); + onChangeAnything(); +} + +void LLPanelRegionTerrainInfo::updateForMaterialType() +{ + if (!mMaterialTypeCtrl) { return; } + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); + const bool show_texture_controls = material_type == LLTerrainMaterials::Type::TEXTURE; + const bool show_material_controls = material_type == LLTerrainMaterials::Type::PBR; + + // Toggle visibility of correct swatches + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i]; + if (texture_ctrl) + { + texture_ctrl->setVisible(show_texture_controls); + } + } + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i]; + if (material_ctrl) + { + material_ctrl->setVisible(show_material_controls); + } + } + + // 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); } + LLUICtrl* material_label = findChild<LLUICtrl>("detail_material_text"); + if (material_label) { material_label->setVisible(show_material_controls); } + + // Toggle visibility of documentation labels for terrain blending ranges + const std::vector<std::string> doc_suffixes { "5", "10", "11" }; + std::string buffer; + for (const std::string& suffix : doc_suffixes) + { + buffer = "height_text_lbl" + suffix; + LLUICtrl* texture_doc_label = findChild<LLUICtrl>(buffer); + if (texture_doc_label) { texture_doc_label->setVisible(show_texture_controls); } + buffer += "_material"; + LLUICtrl* material_doc_label = findChild<LLUICtrl>(buffer); + if (material_doc_label) { material_doc_label->setVisible(show_material_controls); } + } +} + // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { @@ -1421,21 +1666,114 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) getChild<LLUICtrl>("region_text")->setValue(LLSD(region->getName())); LLVLComposition* compp = region->getComposition(); - LLTextureCtrl* texture_ctrl; - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + + static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); + + const bool textures_ready = compp->texturesReady(false, false); + const bool materials_ready = feature_pbr_terrain_enabled && compp->materialsReady(false, false); + + bool set_texture_swatches; + bool set_material_swatches; + bool reset_texture_swatches; + bool reset_material_swatches; + LLTerrainMaterials::Type material_type; + if (!textures_ready && !materials_ready) + { + // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set + // the IDs on both pickers for now. + material_type = LLTerrainMaterials::Type::TEXTURE; + set_texture_swatches = true; + set_material_swatches = true; + reset_texture_swatches = false; + reset_material_swatches = false; + } + else + { + material_type = compp->getMaterialType(); + set_texture_swatches = material_type == LLTerrainMaterials::Type::TEXTURE; + set_material_swatches = !set_texture_swatches; + reset_texture_swatches = !set_texture_swatches; + reset_material_swatches = !set_material_swatches; + } + + if (mMaterialTypeCtrl) + { + material_type_to_ctrl(mMaterialTypeCtrl, material_type); + updateForMaterialType(); + mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled); + } + + if (set_texture_swatches) + { + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; + if(asset_ctrl) + { + LL_DEBUGS("Terrain", "Texture") << "Detail Texture " << i << ": " + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); + asset_ctrl->setImageAssetID(tmp_id); + } + } + } + if (set_material_swatches) + { + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; + if(asset_ctrl) + { + LL_DEBUGS("Terrain", "Material") << "Detail Material " << i << ": " + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); + asset_ctrl->setImageAssetID(tmp_id); + } + } + } + if (reset_texture_swatches) + { + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LL_DEBUGS("Terrain", "Texture") << "Reset Texture swatch " << i + << LL_ENDL; + LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; + if(asset_ctrl) + { + asset_ctrl->setImageAssetID(mLastSetTextures[i]); + } + } + } + if (reset_material_swatches) { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild<LLTextureCtrl>(buffer); - if(texture_ctrl) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - LL_DEBUGS() << "Detail Texture " << i << ": " - << compp->getDetailTextureID(i) << LL_ENDL; - LLUUID tmp_id(compp->getDetailTextureID(i)); - texture_ctrl->setImageAssetID(tmp_id); + LL_DEBUGS("Terrain", "Material") << "Reset Material swatch " << i + << LL_ENDL; + LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; + if(asset_ctrl) + { + asset_ctrl->setImageAssetID(mLastSetMaterials[i]); + } } } + 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) { buffer = llformat("height_start_spin_%d", i); @@ -1450,6 +1788,9 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) getChild<LLUICtrl>("region_text")->setValue(LLSD("")); } + // Update visibility of terrain swatches, etc + refresh(); + getChildView("download_raw_btn")->setEnabled(owner_or_god); getChildView("upload_raw_btn")->setEnabled(owner_or_god); getChildView("bake_terrain_btn")->setEnabled(owner_or_god); @@ -1461,22 +1802,14 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) // virtual bool LLPanelRegionTerrainInfo::sendUpdate() { - LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL; - std::string buffer; - strings_t strings; - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LL_INFOS() << __FUNCTION__ << LL_ENDL; - // update the model - LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); - region_info.mWaterHeight = (F32) getChild<LLUICtrl>("water_height_spin")->getValue().asReal(); - region_info.mTerrainRaiseLimit = (F32) getChild<LLUICtrl>("terrain_raise_spin")->getValue().asReal(); - region_info.mTerrainLowerLimit = (F32) getChild<LLUICtrl>("terrain_lower_spin")->getValue().asReal(); - - // and sync the region with it - region_info.sendRegionTerrain(invoice); - - // ======================================= - // Assemble and send texturedetail message + 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()) @@ -1484,6 +1817,12 @@ bool LLPanelRegionTerrainInfo::sendUpdate() return false; } + // Prevent applying unsupported alpha blend/double-sided materials + if (!validateMaterials()) + { + return false; + } + // Check if terrain Elevation Ranges are correct if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights()) { @@ -1499,20 +1838,55 @@ bool LLPanelRegionTerrainInfo::sendUpdate() } } - LLTextureCtrl* texture_ctrl; + std::string buffer; + strings_t strings; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + // update the model + LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); + region_info.mWaterHeight = (F32) getChild<LLUICtrl>("water_height_spin")->getValue().asReal(); + region_info.mTerrainRaiseLimit = (F32) getChild<LLUICtrl>("terrain_raise_spin")->getValue().asReal(); + region_info.mTerrainLowerLimit = (F32) getChild<LLUICtrl>("terrain_lower_spin")->getValue().asReal(); + + // and sync the region with it + region_info.sendRegionTerrain(invoice); + + // ======================================= + // Assemble and send texturedetail message + std::string id_str; LLMessageSystem* msg = gMessageSystem; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + // Send either material IDs instead of texture IDs depending on + // material_type - they both occupy the same slot. + const LLTerrainMaterials::Type material_type = mMaterialTypeCtrl ? material_type_from_ctrl(mMaterialTypeCtrl) : LLTerrainMaterials::Type::TEXTURE; + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild<LLTextureCtrl>(buffer); - if(texture_ctrl) + LLTextureCtrl* asset_ctrl; + if (material_type == LLTerrainMaterials::Type::PBR) + { + asset_ctrl = mMaterialDetailCtrl[i]; + } + else + { + asset_ctrl = mTextureDetailCtrl[i]; + } + + if (!asset_ctrl) { continue; } + + LLUUID tmp_id(asset_ctrl->getImageAssetID()); + tmp_id.toString(id_str); + buffer = llformat("%d %s", i, id_str.c_str()); + strings.push_back(buffer); + + // Store asset for later terrain editing + if (material_type == LLTerrainMaterials::Type::PBR) { - LLUUID tmp_id(texture_ctrl->getImageAssetID()); - tmp_id.toString(id_str); - buffer = llformat("%d %s", i, id_str.c_str()); - strings.push_back(buffer); + mLastSetMaterials[i] = tmp_id; + } + else + { + mLastSetTextures[i] = tmp_id; } } sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); @@ -1536,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; } |