summaryrefslogtreecommitdiff
path: root/indra/newview/llfloaterregioninfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloaterregioninfo.cpp')
-rw-r--r--indra/newview/llfloaterregioninfo.cpp527
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;
}