Merge pull request #962 from BeamNG/fix_opengl_new_terrain_blend

Fix OpenGL new terrain blend
This commit is contained in:
LuisAntonRebollo 2014-11-30 05:12:06 +01:00
commit a0d5dc25cd
39 changed files with 842 additions and 86 deletions

View file

@ -379,6 +379,9 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
// new terrain
bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
@ -447,6 +450,95 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
// New terrain
Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
if (!lerpBlend)
{
lerpBlend = new Var;
lerpBlend->setType("float");
lerpBlend->setName("lerpBlend");
lerpBlend->uniform = true;
lerpBlend->constSortPos = cspPrimitive;
}
Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
if (!blendDepth)
{
blendDepth = new Var;
blendDepth->setType("float");
blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
blendDepth->uniform = true;
blendDepth->constSortPos = cspPrimitive;
}
Var *baseColor = (Var*)LangElement::find("baseColor");
Var *outColor = (Var*)LangElement::find(getOutputTargetVarName(DefaultTarget));
if (!outColor)
{
// create color var
outColor = new Var;
outColor->setType("float4");
outColor->setName("col");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(outColor)));
//outColor->setStructName("OUT");
}
Var *detailColor = (Var*)LangElement::find("detailColor");
if (!detailColor)
{
detailColor = new Var;
detailColor->setType("float4");
detailColor->setName("detailColor");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor)));
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType("sampler2D");
detailMap->setName(String::ToString("detailMap%d", detailIndex));
detailMap->uniform = true;
detailMap->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// Get the normal map texture.
Var *normalMap = _getNormalMapTex();
// Issue happens somewhere here -----
// Sample the normal map.
//
// We take two normal samples and lerp between them for
// side projection layers... else a single sample.
LangElement *texOp;
// Note that we're doing the standard greyscale detail
// map technique here which can darken and lighten the
// diffuse texture.
//
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex));
texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
normalMap, inDet, normalMap, inDet, inTex);
}
else
{
meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet));
texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
}
// New terrain
// Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal )
@ -460,6 +552,95 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// Add to the blend total.
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
// New terrain
Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
Var *invBlend = (Var*)LangElement::find("invBlend");
Var *currentAlpha = (Var*)LangElement::find("currentAlpha");
Var *ma = (Var*)LangElement::find("ma");
Var *b1 = (Var*)LangElement::find("b1");
Var *b2 = (Var*)LangElement::find("b2");
// Get a var and accumulate the blend amount.
if (!currentAlpha)
{
currentAlpha = new Var;
currentAlpha->setName("currentAlpha");
currentAlpha->setType("float");
meta->addStatement(new GenOp(" @ = 0;\r\n", new DecOp(currentAlpha)));
}
if (hasNormal)
{
// create bump normal
bool bumpNormWasDefined = bumpNorm ? true : false;
LangElement *bumpNormDecl = bumpNorm;
if (!bumpNormWasDefined)
{
bumpNorm = new Var;
bumpNorm->setName("bumpNormal");
bumpNorm->setType("float4");
bumpNormDecl = new DecOp(bumpNorm);
}
meta->addStatement(new GenOp(" @ = @;\r\n", bumpNormDecl, texOp));
meta->addStatement(new GenOp(" @.a = max(@.a, 0.000001);\r\n", bumpNorm, bumpNorm));
// -----
// Get a var and accumulate the blend amount.
if (!invBlend)
{
invBlend = new Var;
invBlend->setName("invBlend");
invBlend->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(invBlend)));
}
// Get a var and accumulate the blend amount.
if (!ma)
{
ma = new Var;
ma->setName("ma");
ma->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(ma)));
}
// Get a var and accumulate the blend amount.
if (!b1)
{
b1 = new Var;
b1->setName("b1");
b1->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(b1)));
}
// Get a var and accumulate the blend amount.
if (!b2)
{
b2 = new Var;
b2->setName("b2");
b2->setType("float");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(b2)));
}
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n { \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = 1-@;\r\n", invBlend, detailBlend));
meta->addStatement(new GenOp(" @ = max(@.a + @, @ + @) - @;\r\n", ma, bumpNorm, detailBlend, currentAlpha, invBlend, blendDepth));
meta->addStatement(new GenOp(" @ = max(@.a + @ - @, 0);\r\n", b1, bumpNorm, detailBlend, ma));
meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n", b2, currentAlpha, invBlend, ma));
meta->addStatement(new GenOp(" }\r\n"));
}
else
{
meta->addStatement(new GenOp(" @ = max(@,@);\r\n", currentAlpha, currentAlpha, detailBlend));
}
// New terrain
// If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending.
if ( fd.features.hasFeature( MFT_TerrainParallaxMap, detailIndex ) )
@ -495,58 +676,36 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
return;
}
Var *detailColor = (Var*)LangElement::find( "detailColor" );
if ( !detailColor )
{
detailColor = new Var;
detailColor->setType( "vec4" );
detailColor->setName( "detailColor" );
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType( "sampler2D" );
detailMap->setName( String::ToString( "detailMap%d", detailIndex ) );
detailMap->uniform = true;
detailMap->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// used as texture unit num here
// If we're using SM 3.0 then take advantage of
// dynamic branching to skip layers per-pixel.
if ( GFX->getPixelShaderVersion() >= 3.0f )
meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
meta->addStatement( new GenOp( " {\r\n" ) );
// Note that we're doing the standard greyscale detail
// map technique here which can darken and lighten the
// diffuse texture.
//
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
{
meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
}
else
{
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
}
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
// New terrain
if (hasNormal)
{
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @.rgb = ((@ + @).rgb * @ + @.rgb * @) / (@ + @);\r\n", outColor, baseColor, detailColor, b1, outColor, b2, b1, b2));
meta->addStatement(new GenOp(" else\r\n"));
}
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
// New terrain
if (hasNormal)
{
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = (@.a * @ + @ * @) / (@ + @);\r\n", currentAlpha, bumpNorm, b1, currentAlpha, b2, b1, b2));
}
meta->addStatement( new GenOp( " }\r\n" ) );
@ -812,13 +971,9 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, outColor, detailColor, detailBlend ) );
//outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
meta->addStatement( new GenOp( " }\r\n" ) );
output = meta;
@ -920,15 +1075,36 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
// create bump normal
Var *bumpNorm = new Var;
bumpNorm->setName( "bumpNormal" );
bumpNorm->setType( "vec4" );
// New terrain
Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
bool bumpNormWasDefined = bumpNorm ? true : false;
LangElement *bumpNormDecl = bumpNorm;
if (!bumpNormWasDefined)
{
bumpNorm = new Var;
bumpNorm->setName("bumpNormal");
bumpNorm->setType("float4");
bumpNormDecl = new DecOp(bumpNorm);
}
LangElement *bumpNormDecl = new DecOp( bumpNorm );
meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
// New terrain
Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
AssertFatal(lerpBlend, "The lerpBlend is missing!");
Var *b1 = (Var*)LangElement::find("b1");
AssertFatal(b1, "The b1 is missing!");
Var *b2 = (Var*)LangElement::find("b2");
AssertFatal(b2, "The b2 is missing!");
// Normalize is done later...
// Note: The reverse mul order is intentional. Affine matrix.
// New terrain
meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend));
meta->addStatement(new GenOp(" @ = (tMul( @.xyz, @ ).rgb * @ + @.rgb * @) / (@ + @);\r\n", gbNormal, bumpNorm, viewToTangent, b1, gbNormal, b2, b1, b2));
meta->addStatement(new GenOp(" else\r\n"));
meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );

View file

@ -574,6 +574,10 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );
// New blending
matInfo->lerpBlend = pass->shader->getShaderConstHandle("$lerpBlend");
matInfo->blendDepth = pass->shader->getShaderConstHandle(avar("$blendDepth%d", i));
matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
if ( matInfo->detailTexConst->isValid() )
{
@ -711,6 +715,11 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
// New blending
bool lerpBlend = Con::getBoolVariable("$Pref::Terrain::LerpBlend", true);
pass->consts->setSafe(matInfo->lerpBlend, lerpBlend ? 1.0f : 0.0f);
pass->consts->setSafe(matInfo->blendDepth, matInfo->mat->getBlendDepth());
// macro texture info
F32 macroSize = matInfo->mat->getMacroSize();

View file

@ -80,6 +80,10 @@ protected:
GFXShaderConstHandle *detailInfoVConst;
GFXShaderConstHandle *detailInfoPConst;
// New blending
GFXShaderConstHandle *lerpBlend;
GFXShaderConstHandle *blendDepth;
GFXShaderConstHandle *macroInfoVConst;
GFXShaderConstHandle *macroInfoPConst;
};

View file

@ -65,7 +65,8 @@ TerrainMaterial::TerrainMaterial()
mMacroSize( 200.0f ),
mMacroStrength( 0.7f ),
mMacroDistance( 500.0f ),
mParallaxScale( 0.0f )
mParallaxScale(0.0f),
mBlendDepth(0.4f)
{
}
@ -97,6 +98,9 @@ void TerrainMaterial::initPersistFields()
addField( "parallaxScale", TypeF32, Offset( mParallaxScale, TerrainMaterial ), "Used to scale the height from the normal map to give some self "
"occlusion effect (aka parallax) to the terrain material" );
addField("blendDepth", TypeF32, Offset(mBlendDepth, TerrainMaterial), "Depth for blending the textures using the new blending method by Lukas Joergensen."
"Higher numbers = larger blend radius.");
Parent::initPersistFields();
// Gotta call this at least once or it won't get created!

View file

@ -74,6 +74,11 @@ protected:
///
F32 mParallaxScale;
/// Depth for blending the textures using the new
/// blending method. Higher numbers = larger blend
/// radius.
F32 mBlendDepth;
public:
TerrainMaterial();
@ -119,6 +124,8 @@ public:
F32 getParallaxScale() const { return mParallaxScale; }
F32 getBlendDepth() const { return mBlendDepth; }
};
#endif // _TERRMATERIAL_H_

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

View file

@ -20,3 +20,228 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Sample grass
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_grass1)
{
mapTo = "grass1";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.42 0.42 0 1";
effectColor[1] = "0.42 0.42 0 1";
impactSoundId = "0";
};
new TerrainMaterial()
{
internalName = "grass1";
diffuseMap = "art/terrains/Example/grass1";
detailMap = "art/terrains/Example/grass1_d";
detailSize = "10";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/grass1_n";
detailDistance = "1000";
};
singleton Material(TerrainFX_grass2)
{
mapTo = "grass2";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.42 0.42 0 1";
effectColor[1] = "0.42 0.42 0 1";
impactSoundId = "0";
};
new TerrainMaterial()
{
internalName = "grass2";
diffuseMap = "art/terrains/Example/grass2";
detailMap = "art/terrains/Example/grass2_d";
detailSize = "10";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
};
singleton Material(TerrainFX_grass1dry)
{
mapTo = "grass1_dry";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.63 0.55 0 1";
};
new TerrainMaterial()
{
internalName = "grass1_dry";
diffuseMap = "art/terrains/Example/grass1_dry";
detailMap = "art/terrains/Example/grass1_dry_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "250";
detailStrength = "2";
normalMap = "art/terrains/Example/grass1_dry_n";
};
singleton Material(TerrainFX_dirt_grass)
{
mapTo = "dirt_grass";
footstepSoundId = 0;
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.63 0.55 0 1";
diffuseMap = "art/terrains/Example/dirt_grass";
diffuseSize = "200";
normalMap = "art/terrains/Example/dirt_grass_n";
detailMap = "art/terrains/Example/dirt_grass_d";
detailDistance = "100";
internalName = "dirt_grass";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "dirt_grass";
diffuseMap = "art/terrains/Example/dirt_grass";
detailMap = "art/terrains/Example/dirt_grass_d";
detailSize = "5";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
};
// ----------------------------------------------------------------------------
// Sample rock
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_rocktest)
{
mapTo = "rocktest";
footstepSoundId = "1";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/rocktest";
diffuseSize = "400";
normalMap = "art/terrains/Example/rocktest_n";
detailMap = "art/terrains/Example/rocktest_d";
detailSize = "10";
detailDistance = "100";
internalName = "rocktest";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "rocktest";
diffuseMap = "art/terrains/Example/rocktest";
detailMap = "art/terrains/Example/rocktest_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "400";
};
// ----------------------------------------------------------------------------
// Sample rock
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_stone)
{
mapTo = "stone";
footstepSoundId = "1";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/stone";
diffuseSize = "400";
normalMap = "art/terrains/Example/stone_n";
detailMap = "art/terrains/Example/stone_d";
detailSize = "10";
detailDistance = "100";
internalName = "stone";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
{
internalName = "stone";
diffuseMap = "art/terrains/Example/stone";
detailMap = "art/terrains/Example/stone_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "400";
useSideProjection = "0";
};
// ----------------------------------------------------------------------------
// Sample sand
// ----------------------------------------------------------------------------
singleton Material(TerrainFX_sand)
{
mapTo = "sand";
footstepSoundId = "3";
terrainMaterials = "1";
ShowDust = "1";
showFootprints = "1";
materialTag0 = "Terrain";
specularPower[0] = "1";
effectColor[0] = "0.84 0.71 0.5 1";
effectColor[1] = "0.84 0.71 0.5 0.349";
};
new TerrainMaterial()
{
internalName = "sand";
diffuseMap = "art/terrains/Example/sand";
detailMap = "art/terrains/Example/sand_d";
detailSize = "10";
detailDistance = "100";
isManaged = "1";
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/sand_n";
};

View file

@ -32,10 +32,12 @@ float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample
vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 );
float noBlend = float(any( bvec4(1 - diff) ));
// Use step to see if any of the layer samples
// match the current texture id.
vec4 factors = step( texId, layerSample );
vec4 factors = vec4(0);
for(int i = 0; i < 4; i++)
if(layerSample[i] == texId)
factors[i] = 1;
// This is a custom bilinear filter.
vec2 uv = layerCoord * layerSize;

View file

@ -210,7 +210,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "270 3";
position = "250 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -222,7 +222,7 @@
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "262 5";
Position = "242 5";
Extent = "256 50";
MinExtent = "8 2";
canSave = "1";
@ -370,7 +370,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "525 3";
position = "495 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -382,7 +382,7 @@
Profile = "ToolsGuiTransparentProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "540 5";
position = "510 5";
Extent = "120 50";
MinExtent = "8 2";
canSave = "1";
@ -454,6 +454,53 @@
bitmap = "tools/gui/images/dropslider";
};
};
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "618 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
};
new GuiControl(LerpBlendCheckButtonContainer,EditorGuiGroup) {
position = "628 5";
extent = "70 50";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTransparentProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
new GuiCheckBoxCtrl() {
text = " LerpBlend";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "0 2";
extent = "140 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
command = "ETerrainEditor.toggleBlendType($ThisControl);";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "LerpBlendCheckBox";
canSave = "1";
canSaveDynamicFields = "0";
};
};
};
};
//--- OBJECT WRITE END ---
@ -634,4 +681,3 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) {
value = "0";
};
};

View file

@ -20,8 +20,8 @@
HorizSizing = "center";
VertSizing = "center";
position = "221 151";
Extent = "394 432";
MinExtent = "358 432";
Extent = "394 452";
MinExtent = "358 452";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
@ -106,7 +106,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "202 26";
Extent = "185 363";
Extent = "185 383";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -439,7 +439,7 @@
HorizSizing = "width";
VertSizing = "bottom";
position = "6 295";
Extent = "185 50";
Extent = "185 80";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -621,6 +621,78 @@
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiSliderCtrl(TerrainMaterialDlgBlendDepthSlider) {
range = "0.01 0.99";
ticks = "0";
snap = "0";
value = "0.5";
position = "39 61";
extent = "70 14";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthSliderCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl() {
text = "Blend Depth";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "115 61";
extent = "58 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextEditCtrl(TerrainMaterialDlgBlendDepthTextEdit) {
historySize = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
password = "0";
passwordMask = "*";
text = "0.3";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "0";
anchorBottom = "0";
anchorLeft = "0";
anchorRight = "0";
position = "1 59";
extent = "35 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTextEditProfile";
visible = "1";
active = "1";
tooltipProfile = "ToolsGuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthTextEditCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
};
new GuiBitmapCtrl() {
@ -1260,7 +1332,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "6 42";
Extent = "189 373";
Extent = "189 393";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1274,7 +1346,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "0 0";
Extent = "189 374";
Extent = "189 394";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1333,7 +1405,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "202 394";
position = "202 414";
Extent = "98 22";
MinExtent = "8 2";
canSave = "1";
@ -1352,7 +1424,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "307 394";
position = "307 414";
Extent = "80 22";
MinExtent = "8 2";
canSave = "1";
@ -1372,7 +1444,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "199 23";
Extent = "190 267";
Extent = "190 287";
isContainer = true;
Visible = false;
bitmap = "tools/gui/images/inactive-overlay";
@ -1389,4 +1461,4 @@
};
};
};
//--- OBJECT WRITE END ---
//--- OBJECT WRITE END ---

View file

@ -222,6 +222,8 @@ function EPainter::setup( %this, %matIndex )
ETerrainEditor.setAction( ETerrainEditor.currentAction );
EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc);
ETerrainEditor.renderVertexSelection = true;
EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend);
}
function onNeedRelight()
@ -257,6 +259,11 @@ function TerrainEditor::toggleBrushType( %this, %brush )
%this.setBrushType( %brush.internalName );
}
function TerrainEditor::toggleBlendType( %this, %check )
{
$Pref::Terrain::LerpBlend = %check.getValue();
}
function TerrainEditor::offsetBrush(%this, %x, %y)
{
%curPos = %this.getBrushPos();

View file

@ -401,6 +401,9 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
%this-->detDistanceCtrl.setText( %mat.detailDistance );
%this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
%this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
%blendDepth = mFloor(%mat.blendDepth * 1000)/1000;
%this-->blendDepthTextEditCtrl.setText( %blendDepth );
%this-->blendDepthSliderCtrl.setValue( %mat.blendDepth );
%this-->macroSizeCtrl.setText( %mat.macroSize );
%this-->macroStrengthCtrl.setText( %mat.macroStrength );
@ -454,6 +457,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%detailDistance = %this-->detDistanceCtrl.getText();
%useSideProjection = %this-->sideProjectionCtrl.getValue();
%parallaxScale = %this-->parallaxScaleCtrl.getText();
%blendDepth = %this-->blendDepthTextEditCtrl.getText();
%macroSize = %this-->macroSizeCtrl.getText();
%macroStrength = %this-->macroStrengthCtrl.getText();
@ -475,7 +479,8 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.macroSize == %macroSize &&
%mat.macroStrength == %macroStrength &&
%mat.macroDistance == %macroDistance &&
%mat.parallaxScale == %parallaxScale )
%mat.parallaxScale == %parallaxScale &&
%mat.blendDepth == %blendDepth)
return;
// Make sure the material name is unique.
@ -509,6 +514,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.macroDistance = %macroDistance;
%mat.useSideProjection = %useSideProjection;
%mat.parallaxScale = %parallaxScale;
%mat.blendDepth = %blendDepth;
// Mark the material as dirty and needing saving.
@ -554,6 +560,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
macroDistance = %mat.macroDistance;
useSideProjection = %mat.useSideProjection;
parallaxScale = %mat.parallaxScale;
blendDepth = %mat.blendDepth;
};
}
}
@ -588,6 +595,7 @@ function TerrainMaterialDlg::restoreMaterials( %this )
%mat.macroDistance = %obj.macroDistance;
%mat.useSideProjection = %obj.useSideProjection;
%mat.parallaxScale = %obj.parallaxScale;
%mat.blendDepth = %obj.blendDepth;
}
}
@ -623,3 +631,17 @@ function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName )
return %file;
}
function TerrainMaterialDlgBlendDepthSlider::onMouseDragged(%this)
{
%value = mFloor(%this.value * 1000)/1000;
TerrainMaterialDlgBlendDepthTextEdit.setText(%value);
TerrainMaterialDlg.activeMat.blendDepth = %this.value;
}
function TerrainMaterialDlgBlendDepthTextEdit::onValidate(%this)
{
TerrainMaterialDlgBlendDepthSlider.setValue(%this.getText());
TerrainMaterialDlg.activeMat.blendDepth = %this.getText();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

View file

@ -47,6 +47,8 @@ new TerrainMaterial()
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/grass1_n";
detailDistance = "1000";
};
singleton Material(TerrainFX_grass2)
@ -97,6 +99,7 @@ new TerrainMaterial()
Enabled = "1";
diffuseSize = "250";
detailStrength = "2";
normalMap = "art/terrains/Example/grass1_dry_n";
};
singleton Material(TerrainFX_dirt_grass)
@ -108,6 +111,15 @@ singleton Material(TerrainFX_dirt_grass)
showFootprints = "1";
materialTag0 = "Terrain";
effectColor[0] = "0.63 0.55 0 1";
diffuseMap = "art/terrains/Example/dirt_grass";
diffuseSize = "200";
normalMap = "art/terrains/Example/dirt_grass_n";
detailMap = "art/terrains/Example/dirt_grass_d";
detailDistance = "100";
internalName = "dirt_grass";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
@ -138,6 +150,16 @@ singleton Material(TerrainFX_rocktest)
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/rocktest";
diffuseSize = "400";
normalMap = "art/terrains/Example/rocktest_n";
detailMap = "art/terrains/Example/rocktest_d";
detailSize = "10";
detailDistance = "100";
internalName = "rocktest";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
@ -168,6 +190,16 @@ singleton Material(TerrainFX_stone)
impactSoundId = "1";
effectColor[0] = "0.25 0.25 0.25 1";
effectColor[1] = "0.25 0.25 0.25 0";
diffuseMap = "art/terrains/Example/stone";
diffuseSize = "400";
normalMap = "art/terrains/Example/stone_n";
detailMap = "art/terrains/Example/stone_d";
detailSize = "10";
detailDistance = "100";
internalName = "stone";
isManaged = "1";
detailBrightness = "1";
enabled = "1";
};
new TerrainMaterial()
@ -211,4 +243,5 @@ new TerrainMaterial()
detailBrightness = "1";
Enabled = "1";
diffuseSize = "200";
normalMap = "art/terrains/Example/sand_n";
};

View file

@ -32,10 +32,12 @@ float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample
vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 );
float noBlend = float(any( bvec4(1 - diff) ));
// Use step to see if any of the layer samples
// match the current texture id.
vec4 factors = step( texId, layerSample );
vec4 factors = vec4(0);
for(int i = 0; i < 4; i++)
if(layerSample[i] == texId)
factors[i] = 1;
// This is a custom bilinear filter.
vec2 uv = layerCoord * layerSize;

View file

@ -210,7 +210,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "270 3";
position = "250 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -222,7 +222,7 @@
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "262 5";
Position = "242 5";
Extent = "256 50";
MinExtent = "8 2";
canSave = "1";
@ -370,7 +370,7 @@
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "525 3";
position = "495 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
@ -382,7 +382,7 @@
Profile = "ToolsGuiTransparentProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "540 5";
position = "510 5";
Extent = "120 50";
MinExtent = "8 2";
canSave = "1";
@ -454,6 +454,53 @@
bitmap = "tools/gui/images/dropslider";
};
};
new GuiBitmapCtrl() {
Enabled = "1";
Profile = "ToolsGuiDefaultProfile";
position = "618 3";
Extent = "2 26";
MinExtent = "1 1";
bitmap = "tools/gui/images/separator-h.png";
};
new GuiControl(LerpBlendCheckButtonContainer,EditorGuiGroup) {
position = "628 5";
extent = "70 50";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTransparentProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
new GuiCheckBoxCtrl() {
text = " LerpBlend";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "0 2";
extent = "140 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
command = "ETerrainEditor.toggleBlendType($ThisControl);";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "LerpBlendCheckBox";
canSave = "1";
canSaveDynamicFields = "0";
};
};
};
};
//--- OBJECT WRITE END ---
@ -634,4 +681,3 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) {
value = "0";
};
};

View file

@ -20,8 +20,8 @@
HorizSizing = "center";
VertSizing = "center";
position = "221 151";
Extent = "394 432";
MinExtent = "358 432";
Extent = "394 452";
MinExtent = "358 452";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
@ -106,7 +106,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "202 26";
Extent = "185 363";
Extent = "185 383";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -439,7 +439,7 @@
HorizSizing = "width";
VertSizing = "bottom";
position = "6 295";
Extent = "185 50";
Extent = "185 80";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -621,6 +621,78 @@
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiSliderCtrl(TerrainMaterialDlgBlendDepthSlider) {
range = "0.01 0.99";
ticks = "0";
snap = "0";
value = "0.5";
position = "39 61";
extent = "70 14";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiSliderProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthSliderCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl() {
text = "Blend Depth";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "115 61";
extent = "58 15";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextEditCtrl(TerrainMaterialDlgBlendDepthTextEdit) {
historySize = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
password = "0";
passwordMask = "*";
text = "0.3";
maxLength = "1024";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "0";
anchorBottom = "0";
anchorLeft = "0";
anchorRight = "0";
position = "1 59";
extent = "35 18";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "ToolsGuiTextEditProfile";
visible = "1";
active = "1";
tooltipProfile = "ToolsGuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "blendDepthTextEditCtrl";
canSave = "1";
canSaveDynamicFields = "0";
};
};
new GuiBitmapCtrl() {
@ -1260,7 +1332,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "6 42";
Extent = "189 373";
Extent = "189 393";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1274,7 +1346,7 @@
HorizSizing = "width";
VertSizing = "height";
position = "0 0";
Extent = "189 374";
Extent = "189 394";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1333,7 +1405,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "202 394";
position = "202 414";
Extent = "98 22";
MinExtent = "8 2";
canSave = "1";
@ -1352,7 +1424,7 @@
Profile = "ToolsGuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "307 394";
position = "307 414";
Extent = "80 22";
MinExtent = "8 2";
canSave = "1";
@ -1372,7 +1444,7 @@
HorizSizing = "left";
VertSizing = "height";
position = "199 23";
Extent = "190 267";
Extent = "190 287";
isContainer = true;
Visible = false;
bitmap = "tools/gui/images/inactive-overlay";
@ -1389,4 +1461,4 @@
};
};
};
//--- OBJECT WRITE END ---
//--- OBJECT WRITE END ---

View file

@ -222,6 +222,8 @@ function EPainter::setup( %this, %matIndex )
ETerrainEditor.setAction( ETerrainEditor.currentAction );
EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc);
ETerrainEditor.renderVertexSelection = true;
EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend);
}
function onNeedRelight()
@ -257,6 +259,11 @@ function TerrainEditor::toggleBrushType( %this, %brush )
%this.setBrushType( %brush.internalName );
}
function TerrainEditor::toggleBlendType( %this, %check )
{
$Pref::Terrain::LerpBlend = %check.getValue();
}
function TerrainEditor::offsetBrush(%this, %x, %y)
{
%curPos = %this.getBrushPos();

View file

@ -401,6 +401,9 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
%this-->detDistanceCtrl.setText( %mat.detailDistance );
%this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
%this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
%blendDepth = mFloor(%mat.blendDepth * 1000)/1000;
%this-->blendDepthTextEditCtrl.setText( %blendDepth );
%this-->blendDepthSliderCtrl.setValue( %mat.blendDepth );
%this-->macroSizeCtrl.setText( %mat.macroSize );
%this-->macroStrengthCtrl.setText( %mat.macroStrength );
@ -454,6 +457,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%detailDistance = %this-->detDistanceCtrl.getText();
%useSideProjection = %this-->sideProjectionCtrl.getValue();
%parallaxScale = %this-->parallaxScaleCtrl.getText();
%blendDepth = %this-->blendDepthTextEditCtrl.getText();
%macroSize = %this-->macroSizeCtrl.getText();
%macroStrength = %this-->macroStrengthCtrl.getText();
@ -475,7 +479,8 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.macroSize == %macroSize &&
%mat.macroStrength == %macroStrength &&
%mat.macroDistance == %macroDistance &&
%mat.parallaxScale == %parallaxScale )
%mat.parallaxScale == %parallaxScale &&
%mat.blendDepth == %blendDepth)
return;
// Make sure the material name is unique.
@ -509,6 +514,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.macroDistance = %macroDistance;
%mat.useSideProjection = %useSideProjection;
%mat.parallaxScale = %parallaxScale;
%mat.blendDepth = %blendDepth;
// Mark the material as dirty and needing saving.
@ -554,6 +560,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
macroDistance = %mat.macroDistance;
useSideProjection = %mat.useSideProjection;
parallaxScale = %mat.parallaxScale;
blendDepth = %mat.blendDepth;
};
}
}
@ -588,6 +595,7 @@ function TerrainMaterialDlg::restoreMaterials( %this )
%mat.macroDistance = %obj.macroDistance;
%mat.useSideProjection = %obj.useSideProjection;
%mat.parallaxScale = %obj.parallaxScale;
%mat.blendDepth = %obj.blendDepth;
}
}
@ -623,3 +631,17 @@ function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName )
return %file;
}
function TerrainMaterialDlgBlendDepthSlider::onMouseDragged(%this)
{
%value = mFloor(%this.value * 1000)/1000;
TerrainMaterialDlgBlendDepthTextEdit.setText(%value);
TerrainMaterialDlg.activeMat.blendDepth = %this.value;
}
function TerrainMaterialDlgBlendDepthTextEdit::onValidate(%this)
{
TerrainMaterialDlgBlendDepthSlider.setValue(%this.getText());
TerrainMaterialDlg.activeMat.blendDepth = %this.getText();
}