summaryrefslogtreecommitdiff
path: root/indra/newview/llvlcomposition.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvlcomposition.cpp')
-rw-r--r--indra/newview/llvlcomposition.cpp610
1 files changed, 310 insertions, 300 deletions
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index bc2fab99c0..4c226073d3 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))
@@ -161,7 +171,7 @@ LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset)
// 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] ? mDetailTextures[asset]->getID() : LLUUID::null;
+ return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null;
}
LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
@@ -183,16 +193,16 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id)
unboost_minimap_texture(mDetailTextures[asset]);
unboost_minimap_material(mDetailMaterials[asset]);
- // 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);
+ // 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);
LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[asset];
mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id);
mDetailRenderMaterials[asset] = nullptr;
mMaterialTexturesSet[asset] = false;
}
-const LLGLTFMaterial* LLTerrainMaterials::getMaterialOverride(S32 asset)
+const LLGLTFMaterial* LLTerrainMaterials::getMaterialOverride(S32 asset) const
{
return mDetailMaterialOverrides[asset];
}
@@ -208,7 +218,7 @@ void LLTerrainMaterials::setMaterialOverride(S32 asset, LLGLTFMaterial* mat_over
LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType()
{
- LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_ZONE_SCOPED;
const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false);
return use_textures ? Type::TEXTURE : Type::PBR;
@@ -418,24 +428,24 @@ const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT]
LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
LLTerrainMaterials(),
- LLViewerLayer(width, scale),
- mParamsReady(false)
+ LLViewerLayer(width, scale),
+ mParamsReady(false)
{
- // Load Terrain Textures - Original ones
+ // Load Terrain Textures - Original ones
const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures();
for (S32 i = 0; i < ASSET_COUNT; ++i)
{
setDetailAssetID(i, default_textures[i]);
}
- mSurfacep = surfacep;
+ 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");
- }
+ // Initialize the texture matrix to defaults.
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
+ mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
+ }
}
@@ -447,117 +457,117 @@ LLVLComposition::~LLVLComposition()
void LLVLComposition::setSurface(LLSurface *surfacep)
{
- mSurfacep = surfacep;
+ mSurfacep = surfacep;
}
bool LLVLComposition::generateHeights(const F32 x, const F32 y,
- const F32 width, const F32 height)
+ const F32 width, const F32 height)
{
- 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;
-
- 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;
+ 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;
+
+ 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)
- {
- // All the parameters haven't been set yet (we haven't gotten the message from the sim)
- return false;
- }
+ if (!mParamsReady)
+ {
+ // All the parameters haven't been set yet (we haven't gotten the message from the sim)
+ return false;
+ }
return LLTerrainMaterials::generateMaterials();
}
@@ -665,22 +675,22 @@ namespace
};
bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
- const F32 width, const F32 height)
+ const F32 width, const F32 height)
{
- LL_PROFILE_ZONE_SCOPED
- llassert(mSurfacep);
- llassert(x >= 0.f);
- llassert(y >= 0.f);
+ LL_PROFILE_ZONE_SCOPED
+ llassert(mSurfacep);
+ llassert(x >= 0.f);
+ llassert(y >= 0.f);
- ///////////////////////////
- //
- // Generate raw data arrays for surface textures
- //
- //
+ ///////////////////////////
+ //
+ // Generate raw data arrays for surface textures
+ //
+ //
- // These have already been validated by generateComposition.
- U8* st_data[ASSET_COUNT];
- S32 st_data_size[ASSET_COUNT]; // for debugging
+ // These have already been validated by generateComposition.
+ U8* st_data[ASSET_COUNT];
+ S32 st_data_size[ASSET_COUNT]; // for debugging
const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
if (use_textures)
@@ -692,11 +702,11 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
if (!materialsReady(true, true)) { return false; }
}
- for (S32 i = 0; i < ASSET_COUNT; i++)
- {
- if (mRawImages[i].isNull())
- {
- // Read back a raw image for this discard level, if it exists
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ if (mRawImages[i].isNull())
+ {
+ // Read back a raw image for this discard level, if it exists
LLViewerFetchedTexture* tex;
LLViewerFetchedTexture* tex_emissive; // Can be null
bool has_base_color_factor;
@@ -769,14 +779,14 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
raw_emissive = newraw_emissive;
}
}
- if (has_base_color_factor ||
+ if (has_base_color_factor ||
raw_emissive ||
has_alpha ||
tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE ||
- tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE ||
- tex->getComponents() != 3)
- {
- LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
+ tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE ||
+ tex->getComponents() != 3)
+ {
+ LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
if (has_alpha)
{
// Approximate the water underneath terrain alpha with solid water color
@@ -786,7 +796,7 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
MAX_WATER_COLOR.mV[VZ],
255);
}
- newraw->composite(mRawImagesBaseColor[i]);
+ newraw->composite(mRawImagesBaseColor[i]);
if (has_base_color_factor)
{
newraw->tint(base_color_factor);
@@ -797,8 +807,8 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
newraw->addEmissive(raw_emissive);
}
- mRawImages[i] = newraw; // deletes old
- }
+ mRawImages[i] = newraw; // deletes old
+ }
if (delete_raw_post)
{
@@ -812,150 +822,150 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
// Remove intermediary image references
mRawImagesBaseColor[i] = nullptr;
mRawImagesEmissive[i] = nullptr;
- }
- st_data[i] = mRawImages[i]->getData();
- st_data_size[i] = mRawImages[i]->getDataSize();
- }
-
- ///////////////////////////////////////
- //
- // Generate and clamp x/y bounding box.
- //
- //
-
- S32 x_begin, y_begin, x_end, y_end;
- x_begin = (S32)(x * mScaleInv);
- y_begin = (S32)(y * mScaleInv);
- x_end = ll_round( (x + width) * mScaleInv );
- y_end = ll_round( (y + width) * mScaleInv );
-
- if (x_end > mWidth)
- {
+ }
+ st_data[i] = mRawImages[i]->getData();
+ st_data_size[i] = mRawImages[i]->getDataSize();
+ }
+
+ ///////////////////////////////////////
+ //
+ // Generate and clamp x/y bounding box.
+ //
+ //
+
+ S32 x_begin, y_begin, x_end, y_end;
+ x_begin = (S32)(x * mScaleInv);
+ y_begin = (S32)(y * mScaleInv);
+ x_end = ll_round( (x + width) * mScaleInv );
+ y_end = ll_round( (y + width) * mScaleInv );
+
+ if (x_end > mWidth)
+ {
llassert(false);
- x_end = mWidth;
- }
- if (y_end > mWidth)
- {
+ x_end = mWidth;
+ }
+ if (y_end > mWidth)
+ {
llassert(false);
- y_end = mWidth;
- }
-
-
- ///////////////////////////////////////////
- //
- // Generate target texture information, stride ratios.
- //
- //
-
- LLViewerTexture *texturep;
- U32 tex_width, tex_height, tex_comps;
- U32 tex_stride;
- F32 tex_x_scalef, tex_y_scalef;
- S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
- F32 tex_x_ratiof, tex_y_ratiof;
-
- texturep = mSurfacep->getSTexture();
- tex_width = texturep->getWidth();
- tex_height = texturep->getHeight();
- tex_comps = texturep->getComponents();
- tex_stride = tex_width * tex_comps;
-
- U32 st_comps = 3;
- U32 st_width = BASE_SIZE;
- U32 st_height = BASE_SIZE;
-
- if (tex_comps != st_comps)
- {
+ y_end = mWidth;
+ }
+
+
+ ///////////////////////////////////////////
+ //
+ // Generate target texture information, stride ratios.
+ //
+ //
+
+ LLViewerTexture *texturep;
+ U32 tex_width, tex_height, tex_comps;
+ U32 tex_stride;
+ F32 tex_x_scalef, tex_y_scalef;
+ S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
+ F32 tex_x_ratiof, tex_y_ratiof;
+
+ texturep = mSurfacep->getSTexture();
+ tex_width = texturep->getWidth();
+ tex_height = texturep->getHeight();
+ tex_comps = texturep->getComponents();
+ tex_stride = tex_width * tex_comps;
+
+ U32 st_comps = 3;
+ U32 st_width = BASE_SIZE;
+ U32 st_height = BASE_SIZE;
+
+ if (tex_comps != st_comps)
+ {
llassert(false);
- return false;
- }
-
- tex_x_scalef = (F32)tex_width / (F32)mWidth;
- tex_y_scalef = (F32)tex_height / (F32)mWidth;
- tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
- tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
- tex_x_end = (S32)((F32)x_end * tex_x_scalef);
- tex_y_end = (S32)((F32)y_end * tex_y_scalef);
-
- tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
- tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;
-
- LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
- U8 *rawp = raw->getData();
-
- F32 st_x_stride, st_y_stride;
- st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
- st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
-
- llassert(st_x_stride > 0.f);
- llassert(st_y_stride > 0.f);
- ////////////////////////////////
- //
- // Iterate through the target texture, striding through the
- // subtextures and interpolating appropriately.
- //
- //
-
- F32 sti, stj;
- S32 st_offset;
- sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
- stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));
-
- st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
- for (S32 j = tex_y_begin; j < tex_y_end; j++)
- {
- U32 offset = j * tex_stride + tex_x_begin * tex_comps;
- sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
- for (S32 i = tex_x_begin; i < tex_x_end; i++)
- {
- S32 tex0, tex1;
- F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);
-
- tex0 = llfloor( composition );
- tex0 = llclamp(tex0, 0, 3);
- composition -= tex0;
- tex1 = tex0 + 1;
- tex1 = llclamp(tex1, 0, 3);
-
- st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
- for (U32 k = 0; k < tex_comps; k++)
- {
- // Linearly interpolate based on composition.
- if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
- {
- // SJB: This shouldn't be happening, but does... Rounding error?
- //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL;
- //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL;
- }
- else
- {
- F32 a = *(st_data[tex0] + st_offset);
- F32 b = *(st_data[tex1] + st_offset);
- rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
- }
- offset++;
- st_offset++;
- }
-
- sti += st_x_stride;
- if (sti >= st_width)
- {
- sti -= st_width;
- }
- }
-
- stj += st_y_stride;
- if (stj >= st_height)
- {
- stj -= st_height;
- }
- }
-
- if (!texturep->hasGLTexture())
- {
- texturep->createGLTexture(0, raw);
- }
- texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
+ return false;
+ }
+
+ tex_x_scalef = (F32)tex_width / (F32)mWidth;
+ tex_y_scalef = (F32)tex_height / (F32)mWidth;
+ tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
+ tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
+ tex_x_end = (S32)((F32)x_end * tex_x_scalef);
+ tex_y_end = (S32)((F32)y_end * tex_y_scalef);
+
+ tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
+ tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
+ U8 *rawp = raw->getData();
+
+ F32 st_x_stride, st_y_stride;
+ st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
+ st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
+
+ llassert(st_x_stride > 0.f);
+ llassert(st_y_stride > 0.f);
+ ////////////////////////////////
+ //
+ // Iterate through the target texture, striding through the
+ // subtextures and interpolating appropriately.
+ //
+ //
+
+ F32 sti, stj;
+ S32 st_offset;
+ sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
+ stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));
+
+ st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
+ for (S32 j = tex_y_begin; j < tex_y_end; j++)
+ {
+ U32 offset = j * tex_stride + tex_x_begin * tex_comps;
+ sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
+ for (S32 i = tex_x_begin; i < tex_x_end; i++)
+ {
+ S32 tex0, tex1;
+ F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);
+
+ tex0 = llfloor( composition );
+ tex0 = llclamp(tex0, 0, 3);
+ composition -= tex0;
+ tex1 = tex0 + 1;
+ tex1 = llclamp(tex1, 0, 3);
+
+ st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
+ for (U32 k = 0; k < tex_comps; k++)
+ {
+ // Linearly interpolate based on composition.
+ if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
+ {
+ // SJB: This shouldn't be happening, but does... Rounding error?
+ //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL;
+ //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL;
+ }
+ else
+ {
+ F32 a = *(st_data[tex0] + st_offset);
+ F32 b = *(st_data[tex1] + st_offset);
+ rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
+ }
+ offset++;
+ st_offset++;
+ }
+
+ sti += st_x_stride;
+ if (sti >= st_width)
+ {
+ sti -= st_width;
+ }
+ }
+
+ stj += st_y_stride;
+ if (stj >= st_height)
+ {
+ stj -= st_height;
+ }
+ }
+
+ if (!texturep->hasGLTexture())
+ {
+ texturep->createGLTexture(0, raw);
+ }
+ texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
// Un-boost detail textures (will get re-boosted if rendering in high detail)
for (S32 i = 0; i < ASSET_COUNT; i++)
@@ -968,38 +978,38 @@ bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
{
unboost_minimap_material(mDetailMaterials[i]);
}
-
- return true;
+
+ return true;
}
F32 LLVLComposition::getStartHeight(S32 corner)
{
- return mStartHeight[corner];
+ return mStartHeight[corner];
}
void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
{
- if (id.isNull())
- {
+ if (id.isNull())
+ {
return;
}
LLTerrainMaterials::setDetailAssetID(asset, id);
- mRawImages[asset] = NULL;
- mRawImagesBaseColor[asset] = NULL;
- mRawImagesEmissive[asset] = NULL;
+ mRawImages[asset] = NULL;
+ mRawImagesBaseColor[asset] = NULL;
+ mRawImagesEmissive[asset] = NULL;
}
void LLVLComposition::setStartHeight(S32 corner, const F32 start_height)
{
- mStartHeight[corner] = start_height;
+ mStartHeight[corner] = start_height;
}
F32 LLVLComposition::getHeightRange(S32 corner)
{
- return mHeightRange[corner];
+ return mHeightRange[corner];
}
void LLVLComposition::setHeightRange(S32 corner, const F32 range)
{
- mHeightRange[corner] = range;
+ mHeightRange[corner] = range;
}