summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/app_settings/settings.xml44
-rw-r--r--indra/newview/llappviewer.cpp1
-rw-r--r--indra/newview/lldrawpoolterrain.cpp63
-rw-r--r--indra/newview/lldrawpoolterrain.h2
-rw-r--r--indra/newview/llviewercontrol.cpp15
-rw-r--r--indra/newview/llvlcomposition.cpp345
-rw-r--r--indra/newview/llvlcomposition.h44
7 files changed, 328 insertions, 186 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 09eda2534c..013f0ca8ff 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16443,6 +16443,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LocalTerrainAsset1</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset2</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset3</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset4</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index cf84094aa4..edbae465f7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -227,6 +227,7 @@
#include "pipeline.h"
#include "llgesturemgr.h"
#include "llsky.h"
+#include "llvlcomposition.h"
#include "llvlmanager.h"
#include "llviewercamera.h"
#include "lldrawpoolbump.h"
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 204fbc56fd..8755e53763 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -249,10 +249,11 @@ void LLDrawPoolTerrain::drawLoop()
void LLDrawPoolTerrain::renderFullShader()
{
+ const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE);
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- const BOOL use_textures = compp->useTextures();
+ const BOOL use_textures = !use_local_materials && compp->useTextures();
if (use_textures)
{
@@ -266,7 +267,7 @@ void LLDrawPoolTerrain::renderFullShader()
// Use materials
sShader = &gDeferredPBRTerrainProgram;
sShader->bind();
- renderFullShaderPBR();
+ renderFullShaderPBR(use_local_materials);
}
}
@@ -371,12 +372,18 @@ void LLDrawPoolTerrain::renderFullShaderTextures()
}
// TODO: Investigate use of bindFast for PBR terrain textures
-void LLDrawPoolTerrain::renderFullShaderPBR()
+void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
{
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLPointer<LLFetchedGLTFMaterial>(& materials)[LLVLComposition::ASSET_COUNT] = compp->mDetailMaterials;
+ LLPointer<LLFetchedGLTFMaterial> (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+
+ if (local_materials)
+ {
+ // Override region terrain with the global local override terrain
+ materials = &gLocalTerrainMaterials.mDetailMaterials;
+ }
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
@@ -395,28 +402,58 @@ void LLDrawPoolTerrain::renderFullShaderPBR()
for (U32 i = 0; i < terrain_material_count; ++i)
{
- LLViewerTexture *detail_basecolor_texturep = materials[i]->mBaseColorTexture;
- LLViewerTexture *detail_normal_texturep = materials[i]->mNormalTexture;
- LLViewerTexture *detail_metalrough_texturep = materials[i]->mMetallicRoughnessTexture;
- LLViewerTexture *detail_emissive_texturep = materials[i]->mEmissiveTexture;
+ const LLFetchedGLTFMaterial* material = (*materials)[i].get();
+
+ LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture;
+ LLViewerTexture *detail_normal_texturep = material->mNormalTexture;
+ LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture;
+ LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture;
detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
- gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep);
+ if (detail_basecolor_texturep)
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_basecolor[i])->activate();
detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
- gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ if (detail_normal_texturep)
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
+ }
gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_normal[i])->activate();
detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
- gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ if (detail_metalrough_texturep)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_metalrough[i])->activate();
detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
- gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep);
+ if (detail_emissive_texturep)
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_emissive[i])->activate();
}
@@ -447,7 +484,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR()
F32 minimum_alphas[terrain_material_count];
for (U32 i = 0; i < terrain_material_count; ++i)
{
- const LLFetchedGLTFMaterial* material = materials[i].get();
+ const LLFetchedGLTFMaterial* material = (*materials)[i].get();
base_color_factors[i] = material->mBaseColor;
metallic_factors[i] = material->mMetallicFactor;
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 2a487228ed..1a27cc8be0 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -81,7 +81,7 @@ protected:
void renderFull4TU();
void renderFullShader();
void renderFullShaderTextures();
- void renderFullShaderPBR();
+ void renderFullShaderPBR(BOOL local_materials = false);
void drawLoop();
private:
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index aae4409167..4e0ad11597 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -54,6 +54,7 @@
#include "llvotree.h"
#include "llvovolume.h"
#include "llworld.h"
+#include "llvlcomposition.h"
#include "pipeline.h"
#include "llviewerjoystick.h"
#include "llviewerobjectlist.h"
@@ -656,6 +657,16 @@ void handleFPSTuningStrategyChanged(const LLSD& newValue)
const auto newval = gSavedSettings.getU32("TuningFPSStrategy");
LLPerfStats::tunables.userFPSTuningStrategy = newval;
}
+
+void handleLocalTerrainChanged(const LLSD& newValue)
+{
+ for (U32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ const auto setting = gSavedSettings.getString(std::string("LocalTerrainAsset") + std::to_string(i + 1));
+ const LLUUID materialID(setting);
+ gLocalTerrainMaterials.setDetailAssetID(i, materialID);
+ }
+}
////////////////////////////////////////////////////////////////////////////
LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
@@ -834,6 +845,10 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset1", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset2", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset3", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset4", handleLocalTerrainChanged);
setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 815489f753..c4bed85be7 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -42,6 +42,8 @@
#include "llviewercontrol.h"
+static const U32 BASE_SIZE = 128;
+
F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac)
{
@@ -59,40 +61,40 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F
return result;
}
-
-LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
- LLViewerLayer(width, scale)
+LLTerrainMaterials::LLTerrainMaterials()
{
- mSurfacep = surfacep;
-
- // Load Terrain Textures - Original ones
- setDetailAssetID(0, TERRAIN_DIRT_DETAIL);
- setDetailAssetID(1, TERRAIN_GRASS_DETAIL);
- setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL);
- setDetailAssetID(3, TERRAIN_ROCK_DETAIL);
-
- // Initialize the texture matrix to defaults.
- for (S32 i = 0; i < CORNER_COUNT; ++i)
- {
- mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
- mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
- }
-
for (S32 i = 0; i < ASSET_COUNT; ++i)
{
mMaterialTexturesSet[i] = false;
}
}
-
-LLVLComposition::~LLVLComposition()
+LLTerrainMaterials::~LLTerrainMaterials()
{
}
+BOOL LLTerrainMaterials::generateMaterials()
+{
+ if (texturesReady(TRUE))
+ {
+ return TRUE;
+ }
-void LLVLComposition::setSurface(LLSurface *surfacep)
+ if (materialsReady(TRUE))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset)
{
- mSurfacep = surfacep;
+ llassert(mDetailTextures[asset] && mDetailMaterials[asset]);
+ // *HACK: Assume both the the material and texture were fetched in the same
+ // way using the same UUID. However, we may not know at this point which
+ // one will load.
+ return mDetailTextures[asset]->getID();
}
LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
@@ -107,126 +109,51 @@ LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
return tex;
}
-void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
+void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id)
{
- if(id.isNull())
- {
- return;
- }
// This is terrain texture, but we are not setting it as BOOST_TERRAIN
// since we will be manipulating it later as needed.
mDetailTextures[asset] = fetch_terrain_texture(id);
- mRawImages[asset] = NULL;
LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[asset];
mat = gGLTFMaterialList.getMaterial(id);
mMaterialTexturesSet[asset] = false;
}
-BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
- const F32 width, const F32 height)
+BOOL LLTerrainMaterials::useTextures()
{
- if (!mParamsReady)
- {
- // All the parameters haven't been set yet (we haven't gotten the message from the sim)
- return FALSE;
- }
-
- llassert(mSurfacep);
-
- if (!mSurfacep || !mSurfacep->getRegion())
- {
- // We don't always have the region yet here....
- return FALSE;
- }
-
- S32 x_begin, y_begin, x_end, y_end;
+ LL_PROFILE_ZONE_SCOPED;
- x_begin = ll_round( x * mScaleInv );
- y_begin = ll_round( y * mScaleInv );
- x_end = ll_round( (x + width) * mScaleInv );
- y_end = ll_round( (y + width) * mScaleInv );
+ return texturesReady() || !materialsReady();
+}
- if (x_end > mWidth)
- {
- x_end = mWidth;
- }
- if (y_end > mWidth)
+BOOL LLTerrainMaterials::texturesReady(BOOL boost)
+{
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- y_end = mWidth;
+ if (!textureReady(mDetailTextures[i], boost))
+ {
+ return FALSE;
+ }
}
+ return TRUE;
+}
- LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
-
- // For perlin noise generation...
- const F32 slope_squared = 1.5f*1.5f;
- const F32 xyScale = 4.9215f; //0.93284f;
- const F32 zScale = 4; //0.92165f;
- const F32 z_offset = 0.f;
- const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
- // simple height)
-
- const F32 xyScaleInv = (1.f / xyScale);
- const F32 zScaleInv = (1.f / zScale);
-
- const F32 inv_width = 1.f/mWidth;
-
- // OK, for now, just have the composition value equal the height at the point.
- for (S32 j = y_begin; j < y_end; j++)
+BOOL LLTerrainMaterials::materialsReady(BOOL boost)
+{
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- for (S32 i = x_begin; i < x_end; i++)
- {
-
- F32 vec[3];
- F32 vec1[3];
- F32 twiddle;
-
- // Bilinearly interpolate the start height and height range of the textures
- F32 start_height = bilinear(mStartHeight[SOUTHWEST],
- mStartHeight[SOUTHEAST],
- mStartHeight[NORTHWEST],
- mStartHeight[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
- F32 height_range = bilinear(mHeightRange[SOUTHWEST],
- mHeightRange[SOUTHEAST],
- mHeightRange[NORTHWEST],
- mHeightRange[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
-
- LLVector3 location(i*mScale, j*mScale, 0.f);
-
- F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
-
- // Step 0: Measure the exact height at this texel
- vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
- 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
- //
- vec1[0] = vec[0]*(0.2222222222f);
- vec1[1] = vec[1]*(0.2222222222f);
- vec1[2] = vec[2]*(0.2222222222f);
- twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
-
- twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
- twiddle *= noise_magnitude;
-
- F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range;
-
- scaled_noisy_height = llmax(0.f, scaled_noisy_height);
- scaled_noisy_height = llmin(3.f, scaled_noisy_height);
- *(mDatap + i + j*mWidth) = scaled_noisy_height;
- }
- }
- return TRUE;
+ if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
-static const U32 BASE_SIZE = 128;
-
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
// static
-BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
+BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
{
llassert(tex.notNull());
@@ -266,9 +193,9 @@ BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL
// Boost the loading priority of every known texture in the material
// Return true when ready to use (i.e. material and all textures within are sufficiently loaded)
// static
-BOOL LLVLComposition::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
+BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
{
- if (!mat->isLoaded())
+ if (!mat || !mat->isLoaded())
{
return FALSE;
}
@@ -308,37 +235,140 @@ BOOL LLVLComposition::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool&
return TRUE;
}
-BOOL LLVLComposition::useTextures()
+
+LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
+ LLTerrainMaterials(),
+ LLViewerLayer(width, scale)
+{
+ // Load Terrain Textures - Original ones
+ setDetailAssetID(0, TERRAIN_DIRT_DETAIL);
+ setDetailAssetID(1, TERRAIN_GRASS_DETAIL);
+ setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL);
+ setDetailAssetID(3, TERRAIN_ROCK_DETAIL);
+
+ mSurfacep = surfacep;
+
+ // Initialize the texture matrix to defaults.
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
+ mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
+ }
+}
+
+
+LLVLComposition::~LLVLComposition()
{
- LL_PROFILE_ZONE_SCOPED;
+ LLTerrainMaterials::~LLTerrainMaterials();
+}
- return texturesReady() || !materialsReady();
+
+void LLVLComposition::setSurface(LLSurface *surfacep)
+{
+ mSurfacep = surfacep;
}
-BOOL LLVLComposition::texturesReady(BOOL boost)
+BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
+ const F32 width, const F32 height)
{
- for (S32 i = 0; i < ASSET_COUNT; i++)
+ if (!mParamsReady)
{
- if (!textureReady(mDetailTextures[i], boost))
- {
- return FALSE;
- }
+ // All the parameters haven't been set yet (we haven't gotten the message from the sim)
+ return FALSE;
}
- return TRUE;
-}
-BOOL LLVLComposition::materialsReady(BOOL boost)
-{
- for (S32 i = 0; i < ASSET_COUNT; i++)
+ llassert(mSurfacep);
+
+ if (!mSurfacep || !mSurfacep->getRegion())
{
- if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
- {
- return FALSE;
- }
- }
- return TRUE;
+ // We don't always have the region yet here....
+ return FALSE;
+ }
+
+ S32 x_begin, y_begin, x_end, y_end;
+
+ x_begin = ll_round( x * mScaleInv );
+ y_begin = ll_round( y * mScaleInv );
+ x_end = ll_round( (x + width) * mScaleInv );
+ y_end = ll_round( (y + width) * mScaleInv );
+
+ if (x_end > mWidth)
+ {
+ x_end = mWidth;
+ }
+ if (y_end > mWidth)
+ {
+ y_end = mWidth;
+ }
+
+ LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
+
+ // For perlin noise generation...
+ const F32 slope_squared = 1.5f*1.5f;
+ const F32 xyScale = 4.9215f; //0.93284f;
+ const F32 zScale = 4; //0.92165f;
+ const F32 z_offset = 0.f;
+ const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
+ // simple height)
+
+ const F32 xyScaleInv = (1.f / xyScale);
+ const F32 zScaleInv = (1.f / zScale);
+
+ const F32 inv_width = 1.f/mWidth;
+
+ // OK, for now, just have the composition value equal the height at the point.
+ for (S32 j = y_begin; j < y_end; j++)
+ {
+ for (S32 i = x_begin; i < x_end; i++)
+ {
+
+ F32 vec[3];
+ F32 vec1[3];
+ F32 twiddle;
+
+ // Bilinearly interpolate the start height and height range of the textures
+ F32 start_height = bilinear(mStartHeight[SOUTHWEST],
+ mStartHeight[SOUTHEAST],
+ mStartHeight[NORTHWEST],
+ mStartHeight[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+ F32 height_range = bilinear(mHeightRange[SOUTHWEST],
+ mHeightRange[SOUTHEAST],
+ mHeightRange[NORTHWEST],
+ mHeightRange[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+
+ LLVector3 location(i*mScale, j*mScale, 0.f);
+
+ F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
+
+ // Step 0: Measure the exact height at this texel
+ vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
+ 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
+ //
+ vec1[0] = vec[0]*(0.2222222222f);
+ vec1[1] = vec[1]*(0.2222222222f);
+ vec1[2] = vec[2]*(0.2222222222f);
+ twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
+
+ twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
+ twiddle *= noise_magnitude;
+
+ F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range;
+
+ scaled_noisy_height = llmax(0.f, scaled_noisy_height);
+ scaled_noisy_height = llmin(3.f, scaled_noisy_height);
+ *(mDatap + i + j*mWidth) = scaled_noisy_height;
+ }
+ }
+ return TRUE;
}
+LLTerrainMaterials gLocalTerrainMaterials;
+
BOOL LLVLComposition::generateComposition()
{
if (!mParamsReady)
@@ -347,17 +377,7 @@ BOOL LLVLComposition::generateComposition()
return FALSE;
}
- if (texturesReady(TRUE))
- {
- return TRUE;
- }
-
- if (materialsReady(TRUE))
- {
- return TRUE;
- }
-
- return FALSE;
+ return LLTerrainMaterials::generateMaterials();
}
// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful.
@@ -592,18 +612,19 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
return TRUE;
}
-LLUUID LLVLComposition::getDetailAssetID(S32 corner)
+F32 LLVLComposition::getStartHeight(S32 corner)
{
- llassert(mDetailTextures[corner] && mDetailMaterials[corner]);
- // *HACK: Assume both the the material and texture were fetched in the same
- // way using the same UUID. However, we may not know at this point which
- // one will load.
- return mDetailTextures[corner]->getID();
+ return mStartHeight[corner];
}
-F32 LLVLComposition::getStartHeight(S32 corner)
+void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
{
- return mStartHeight[corner];
+ if (id.isNull())
+ {
+ return;
+ }
+ LLTerrainMaterials::setDetailAssetID(asset, id);
+ mRawImages[asset] = NULL;
}
void LLVLComposition::setStartHeight(S32 corner, const F32 start_height)
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index 504441d0f2..9dc0b7221e 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -37,7 +37,38 @@ class LLSurface;
class LLViewerFetchedTexture;
class LLFetchedGLTFMaterial;
-class LLVLComposition : public LLViewerLayer
+class LLTerrainMaterials
+{
+public:
+ friend class LLDrawPoolTerrain;
+
+ LLTerrainMaterials();
+ virtual ~LLTerrainMaterials();
+
+ // 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;
+
+ BOOL generateMaterials();
+
+ LLUUID getDetailAssetID(S32 asset);
+ virtual void setDetailAssetID(S32 asset, const LLUUID& id);
+ BOOL useTextures();
+ BOOL texturesReady(BOOL boost = FALSE);
+ BOOL materialsReady(BOOL boost = FALSE);
+
+protected:
+ static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
+ static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+ LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
+ LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
+ bool mMaterialTexturesSet[ASSET_COUNT];
+};
+
+// Local materials to override all regions
+extern LLTerrainMaterials gLocalTerrainMaterials;
+
+class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer
{
public:
LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale);
@@ -65,11 +96,10 @@ public:
CORNER_COUNT = 4
};
- LLUUID getDetailAssetID(S32 asset);
+ void setDetailAssetID(S32 asset, const LLUUID& id) override;
F32 getStartHeight(S32 corner);
F32 getHeightRange(S32 corner);
- void setDetailAssetID(S32 asset, const LLUUID& id);
void setStartHeight(S32 corner, F32 start_height);
void setHeightRange(S32 corner, F32 range);
@@ -77,9 +107,6 @@ public:
friend class LLDrawPoolTerrain;
void setParamsReady() { mParamsReady = TRUE; }
BOOL getParamsReady() const { return mParamsReady; }
- BOOL useTextures();
- BOOL texturesReady(BOOL boost = FALSE);
- BOOL materialsReady(BOOL boost = FALSE);
protected:
static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
@@ -88,10 +115,7 @@ protected:
BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;
- LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
- LLPointer<LLImageRaw> mRawImages[ASSET_COUNT];
- LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
- bool mMaterialTexturesSet[ASSET_COUNT];
+ LLPointer<LLImageRaw> mRawImages[LLTerrainMaterials::ASSET_COUNT];
F32 mStartHeight[CORNER_COUNT];
F32 mHeightRange[CORNER_COUNT];