Browse Source

Terrain Macro Texture

Adds another layer of detail-like texture to the terrain and the
interface updates in the Terrain Painter.
xoltan 12 years ago
parent
commit
add2f8cb47

+ 300 - 0
Engine/source/terrain/hlsl/terrFeatureHLSL.cpp

@@ -43,6 +43,7 @@ MODULE_BEGIN( TerrainFeatHLSL )
       FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureHLSL( "Terrain Parallax Texture" ) );   
       FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
       FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
@@ -85,6 +86,25 @@ Var* TerrainFeatHLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList
    return inDet;
 }
 
+Var* TerrainFeatHLSL::_getInMacroCoord( Vector<ShaderComponent*> &componentList )
+{
+   String name( String::ToString( "macroCoord%d", getProcessIndex() ) );
+   Var *inDet = (Var*)LangElement::find( name );
+
+   if ( !inDet )
+   {
+      ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+
+      inDet = connectComp->getElement( RT_TEXCOORD );
+      inDet->setName( name );
+      inDet->setStructName( "IN" );
+      inDet->setType( "float4" );
+      inDet->mapsToSampler = true;
+   }
+
+   return inDet;
+}
+
 Var* TerrainFeatHLSL::_getNormalMapTex()
 {
    String name( String::ToString( "normalMap%d", getProcessIndex() ) );
@@ -120,6 +140,24 @@ Var* TerrainFeatHLSL::_getDetailIdStrengthParallax()
    return detailInfo;
 }
 
+Var* TerrainFeatHLSL::_getMacroIdStrengthParallax()
+{
+   String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) );
+
+   Var *detailInfo = (Var*)LangElement::find( name );
+   if ( !detailInfo )
+   {
+      detailInfo = new Var;
+      detailInfo->setType( "float3" );
+      detailInfo->setName( name );
+      detailInfo->uniform = true;
+      detailInfo->constSortPos = cspPotentialPrimitive;
+   }
+
+   return detailInfo;
+}
+
+
 void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
 {
@@ -537,6 +575,268 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
    return res;
 }
 
+
+TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
+   :  mTorqueDep( "shaders/common/torque.hlsl" ),
+      mTerrainDep( "shaders/common/terrain/terrain.hlsl" )
+      
+{
+   addDependency( &mTorqueDep );
+   addDependency( &mTerrainDep );
+}
+
+
+void TerrainMacroMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
+                                             const MaterialFeatureData &fd )
+{
+   const U32 detailIndex = getProcessIndex();
+
+   // Grab incoming texture coords... the base map feature
+   // made sure this was created.
+   Var *inTex = (Var*)LangElement::find( "texCoord" );
+   AssertFatal( inTex, "The texture coord is missing!" );
+
+   // Grab the input position.
+   Var *inPos = (Var*)LangElement::find( "inPosition" );
+   if ( !inPos )
+      inPos = (Var*)LangElement::find( "position" );
+
+   // Get the object space eye position.
+   Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive );
+
+   MultiLine *meta = new MultiLine;
+
+   // Get the distance from the eye to this vertex.
+   Var *dist = (Var*)LangElement::find( "macroDist" );
+   if ( !dist )
+   {
+      dist = new Var;
+      dist->setType( "float" );
+      dist->setName( "macroDist" );  
+
+      meta->addStatement( new GenOp( "   @ = distance( @.xyz, @ );\r\n", 
+                                       new DecOp( dist ), inPos, eyePos ) );
+   }
+
+   // grab connector texcoord register
+   ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+   Var *outTex = connectComp->getElement( RT_TEXCOORD );
+   outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
+   outTex->setStructName( "OUT" );
+   outTex->setType( "float4" );
+   outTex->mapsToSampler = true;
+
+   // Get the detail scale and fade info.
+   Var *detScaleAndFade = new Var;
+   detScaleAndFade->setType( "float4" );
+   detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
+   detScaleAndFade->uniform = true;
+   detScaleAndFade->constSortPos = cspPotentialPrimitive;
+
+   // Setup the detail coord.
+   meta->addStatement( new GenOp( "   @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
+
+   // And sneak the detail fade thru the w detailCoord.
+   meta->addStatement( new GenOp( "   @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", 
+                                    outTex, detScaleAndFade, dist, detScaleAndFade ) );   
+
+   output = meta;
+}
+
+
+void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
+                                             const MaterialFeatureData &fd )
+{
+   const U32 detailIndex = getProcessIndex();
+   Var *inTex = getVertTexCoord( "texCoord" );
+   
+   MultiLine *meta = new MultiLine;
+
+   // We need the negative tangent space view vector
+   // as in parallax mapping we step towards the camera.
+   Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
+   if (  !negViewTS &&
+         fd.features.hasFeature( MFT_TerrainParallaxMap ) )
+   {
+      Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
+      if ( !inNegViewTS )
+      {
+         ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+         inNegViewTS = connectComp->getElement( RT_TEXCOORD );
+         inNegViewTS->setName( "outNegViewTS" );
+         inNegViewTS->setStructName( "IN" );
+         inNegViewTS->setType( "float3" );
+      }
+
+      negViewTS = new Var( "negViewTS", "float3" );
+      meta->addStatement( new GenOp( "   @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
+   }
+
+   // Get the layer samples.
+   Var *layerSample = (Var*)LangElement::find( "layerSample" );
+   if ( !layerSample )
+   {
+      layerSample = new Var;
+      layerSample->setType( "float4" );
+      layerSample->setName( "layerSample" );
+
+      // Get the layer texture var
+      Var *layerTex = new Var;
+      layerTex->setType( "sampler2D" );
+      layerTex->setName( "macrolayerTex" );
+      layerTex->uniform = true;
+      layerTex->sampler = true;
+      layerTex->constNum = Var::getTexUnitNum();
+
+      // Read the layer texture to get the samples.
+      meta->addStatement( new GenOp( "   @ = round( tex2D( @, @.xy ) * 255.0f );\r\n", 
+                                       new DecOp( layerSample ), layerTex, inTex ) );
+   }
+
+   Var *layerSize = (Var*)LangElement::find( "layerSize" );
+   if ( !layerSize )
+   {
+      layerSize = new Var;
+      layerSize->setType( "float" );
+      layerSize->setName( "layerSize" );
+      layerSize->uniform = true;
+      layerSize->constSortPos = cspPass;
+   }
+
+   // Grab the incoming detail coord.
+   Var *inDet = _getInMacroCoord( componentList );
+
+   // Get the detail id.
+   Var *detailInfo = _getMacroIdStrengthParallax();
+
+   // Create the detail blend var.
+   Var *detailBlend = new Var;
+   detailBlend->setType( "float" );
+   detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
+
+   // Calculate the blend for this detail texture.
+   meta->addStatement( new GenOp( "   @ = calcBlend( @.x, @.xy, @, @ );\r\n", 
+                                    new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
+
+   // Get a var and accumulate the blend amount.
+   Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
+   if ( !blendTotal )
+   {
+      blendTotal = new Var;
+      //blendTotal->setName( "blendTotal" );
+      blendTotal->setName( "blendTotal" );
+      blendTotal->setType( "float" );
+      meta->addStatement( new GenOp( "   @ = 0;\r\n", new DecOp( blendTotal ) ) );
+   }
+
+   // Add to the blend total.
+   meta->addStatement( new GenOp( "   @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
+
+   // If this is a prepass then we skip color.
+   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
+   {
+      // Check to see if we have a gbuffer normal.
+      Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
+
+      // If we have a gbuffer normal and we don't have a
+      // normal map feature then we need to lerp in a 
+      // default normal else the normals below this layer
+      // will show thru.
+      if (  gbNormal && 
+            !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
+      {
+         Var *viewToTangent = getInViewToTangent( componentList );
+
+         meta->addStatement( new GenOp( "   @ = lerp( @, @[2], min( @, @.w ) );\r\n", 
+            gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
+      }
+
+      output = meta;
+      return;
+   }
+
+   Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
+   if ( !detailColor )
+   {
+      detailColor = new Var;
+      detailColor->setType( "float4" );
+      detailColor->setName( "macroColor" );
+      meta->addStatement( new GenOp( "   @;\r\n", new DecOp( detailColor ) ) );
+   }
+
+   // Get the detail texture.
+   Var *detailMap = new Var;
+   detailMap->setType( "sampler2D" );
+   detailMap->setName( String::ToString( "macroMap%d", detailIndex ) );
+   detailMap->uniform = true;
+   detailMap->sampler = true;
+   detailMap->constNum = Var::getTexUnitNum();     // 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" );
+
+   meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
+                                    outColor, outColor, outColor, detailColor, detailBlend ) );
+   //outColor, outColor, baseColor, detailColor, detailBlend ) );
+
+   meta->addStatement( new GenOp( "   }\r\n" ) );
+
+   output = meta;
+}
+
+
+
+ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
+{
+   Resources res;
+
+   if ( getProcessIndex() == 0 )
+   {
+      // If this is the first detail pass then we 
+      // samples from the layer tex.
+      res.numTex += 1;
+   }
+
+   // If this isn't the prepass then we sample 
+   // from the detail texture for diffuse coloring.
+   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
+      res.numTex += 1;
+
+   // Finally we always send the detail texture 
+   // coord to the pixel shader.
+   res.numTexReg += 1;
+
+   return res;
+}
+
 void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
 {

+ 26 - 0
Engine/source/terrain/hlsl/terrFeatureHLSL.h

@@ -39,11 +39,14 @@ protected:
 
    Var* _getInDetailCoord(Vector<ShaderComponent*> &componentList );
 
+   Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );
+
    Var* _getNormalMapTex();
 
    static Var* _getUniformVar( const char *name, const char *type, ConstantSortPosition csp );
 
    Var* _getDetailIdStrengthParallax();
+   Var* _getMacroIdStrengthParallax();
 
 };
 
@@ -87,6 +90,29 @@ public:
 };
 
 
+class TerrainMacroMapFeatHLSL : public TerrainFeatHLSL
+{
+protected:
+
+   ShaderIncludeDependency mTorqueDep;
+   ShaderIncludeDependency mTerrainDep;
+
+public:
+
+   TerrainMacroMapFeatHLSL();
+
+   virtual void processVert(  Vector<ShaderComponent*> &componentList,
+                              const MaterialFeatureData &fd );
+
+   virtual void processPix(   Vector<ShaderComponent*> &componentList, 
+                              const MaterialFeatureData &fd );
+
+   virtual Resources getResources( const MaterialFeatureData &fd );
+
+   virtual String getName() { return "Terrain Macro Texture"; }
+};
+
+
 class TerrainNormalMapFeatHLSL : public TerrainFeatHLSL
 {
 public:

+ 69 - 0
Engine/source/terrain/terrCellMaterial.cpp

@@ -101,6 +101,19 @@ void TerrainCellMaterial::_updateDefaultAnisotropy()
                   desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
             }
 
+            if ( matInfo->macroTexConst->isValid() )
+            {
+               const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
+
+               if ( maxAnisotropy > 1 )
+               {
+                  desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
+                  desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
+               }
+               else
+                  desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
+            }
+
             if ( matInfo->normalTexConst->isValid() )
             {
                const S32 sampler = matInfo->normalTexConst->getSamplerRegister();
@@ -369,6 +382,10 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
 
          S32 featureIndex = pass->materials.size();
 
+		 // check for macro detail texture
+         if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
+	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
+
          features.addFeature( MFT_TerrainDetailMap, featureIndex );
 
          pass->materials.push_back( (*materials)[i] );
@@ -567,6 +584,31 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
             &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" );
       }
 
+      matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) );
+      matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) );
+
+      matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) );
+      if ( matInfo->macroTexConst->isValid() )
+      {
+         const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
+
+         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
+         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
+         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;
+
+         if ( maxAnisotropy > 1 )
+         {
+            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
+            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
+         }
+         else
+            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
+
+         matInfo->macroTex.set( matInfo->mat->getMacroMap(), 
+            &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" );
+      }
+	  //end macro texture
+
       matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) );
       if ( matInfo->normalTexConst->isValid() )
       {
@@ -657,6 +699,31 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
 
       pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
       pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
+
+	// macro texture info
+
+      F32 macroSize = matInfo->mat->getMacroSize();
+      F32 macroScale = 1.0f;
+      if ( !mIsZero( macroSize ) )
+         macroScale = mTerrain->getWorldBlockSize() / macroSize;
+
+      // Scale the distance by the global scalar.
+      const F32 macroDistance = mTerrain->smDetailScale * matInfo->mat->getMacroDistance();
+
+      Point4F macroScaleAndFade(   macroScale,
+                                    -macroScale,
+                                    macroDistance, 
+                                    0 );
+
+      if ( !mIsZero( macroDistance ) )
+         macroScaleAndFade.w = 1.0f / macroDistance;
+
+      Point3F macroIdStrengthParallax( matInfo->layerId,
+                                        matInfo->mat->getMacroStrength(),
+                                        0 );
+
+      pass->consts->setSafe( matInfo->macroInfoVConst, macroScaleAndFade );
+      pass->consts->setSafe( matInfo->macroInfoPConst, macroIdStrengthParallax );
    }
 }
 
@@ -706,6 +773,8 @@ bool TerrainCellMaterial::setupPass(   const SceneRenderState *state,
 
       if ( matInfo->detailTexConst->isValid() )
          GFX->setTexture( matInfo->detailTexConst->getSamplerRegister(), matInfo->detailTex );
+      if ( matInfo->macroTexConst->isValid() )
+         GFX->setTexture( matInfo->macroTexConst->getSamplerRegister(), matInfo->macroTex );
       if ( matInfo->normalTexConst->isValid() )
          GFX->setTexture( matInfo->normalTexConst->getSamplerRegister(), matInfo->normalTex );
    }

+ 6 - 0
Engine/source/terrain/terrCellMaterial.h

@@ -71,11 +71,17 @@ protected:
       GFXShaderConstHandle *detailTexConst;
       GFXTexHandle detailTex;
 
+      GFXShaderConstHandle *macroTexConst;
+      GFXTexHandle macroTex;
+
       GFXShaderConstHandle *normalTexConst;
       GFXTexHandle normalTex;
 
       GFXShaderConstHandle *detailInfoVConst;
       GFXShaderConstHandle *detailInfoPConst;
+
+	  GFXShaderConstHandle *macroInfoVConst;
+      GFXShaderConstHandle *macroInfoPConst;
    };
 
    class Pass

+ 3 - 2
Engine/source/terrain/terrFeatureTypes.cpp

@@ -30,7 +30,8 @@ ImplementFeatureType( MFT_TerrainBaseMap, MFG_Texture, 100.0f, false );
 ImplementFeatureType( MFT_TerrainParallaxMap, MFG_Texture, 101.0f, false );
 ImplementFeatureType( MFT_TerrainDetailMap, MFG_Texture, 102.0f, false );
 ImplementFeatureType( MFT_TerrainNormalMap, MFG_Texture, 103.0f, false );
-ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 104.0f, false );
-ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 105.0f, false );
+ImplementFeatureType( MFT_TerrainMacroMap, MFG_Texture, 104.0f, false );
+ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 105.0f, false );
+ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 106.0f, false );
 ImplementFeatureType( MFT_TerrainAdditive, MFG_PostProcess, 999.0f, false );
 

+ 1 - 0
Engine/source/terrain/terrFeatureTypes.h

@@ -28,6 +28,7 @@
 #endif
 
 DeclareFeatureType( MFT_TerrainBaseMap );
+DeclareFeatureType( MFT_TerrainMacroMap );
 DeclareFeatureType( MFT_TerrainDetailMap );
 DeclareFeatureType( MFT_TerrainNormalMap );
 DeclareFeatureType( MFT_TerrainParallaxMap );

+ 12 - 0
Engine/source/terrain/terrMaterial.cpp

@@ -62,6 +62,9 @@ TerrainMaterial::TerrainMaterial()
       mDetailSize( 5.0f ),
       mDetailStrength( 1.0f ),
       mDetailDistance( 50.0f ),
+      mMacroSize( 200.0f ),
+      mMacroStrength( 0.7f ),
+      mMacroDistance( 500.0f ),
       mParallaxScale( 0.0f )
 {
 }
@@ -84,6 +87,13 @@ void TerrainMaterial::initPersistFields()
    addField( "detailDistance", TypeF32, Offset( mDetailDistance, TerrainMaterial ), "Changes how far camera can see the detail map rendering on the material" );
    addField( "useSideProjection", TypeBool, Offset( mSideProjection, TerrainMaterial ),"Makes that terrain material project along the sides of steep "
 	   "slopes instead of projected downwards");
+
+   //Macro maps additions
+   addField( "macroMap", TypeStringFilename, Offset( mMacroMap, TerrainMaterial ), "Macro map for the material" );
+   addField( "macroSize", TypeF32, Offset( mMacroSize, TerrainMaterial ), "Used to scale the Macro map to the material square" );
+   addField( "macroStrength", TypeF32, Offset( mMacroStrength, TerrainMaterial ), "Exponentially sharpens or lightens the Macro map rendering on the material" );
+   addField( "macroDistance", TypeF32, Offset( mMacroDistance, TerrainMaterial ), "Changes how far camera can see the Macro map rendering on the material" );
+
    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" );
 
@@ -157,6 +167,8 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
       mat->mDiffuseSize = 500;
       mat->mDetailMap = GFXTextureManager::getWarningTexturePath();
       mat->mDetailSize = 5;
+	  mat->mMacroMap = GFXTextureManager::getWarningTexturePath();
+	  mat->mMacroSize = 200;
       mat->registerObject();
       
       Sim::getRootGroup()->addObject( mat );

+ 13 - 0
Engine/source/terrain/terrMaterial.h

@@ -66,6 +66,11 @@ protected:
    /// planes.
    bool mSideProjection;
 
+   FileName mMacroMap;
+   F32 mMacroSize;
+   F32 mMacroStrength;
+   F32 mMacroDistance;
+
    ///
    F32 mParallaxScale;
 
@@ -96,12 +101,20 @@ public:
 
    const String& getDetailMap() const { return mDetailMap; }
 
+   const String& getMacroMap() const { return mMacroMap; }
+
    F32 getDetailSize() const { return mDetailSize; }
 
    F32 getDetailStrength() const { return mDetailStrength; }
 
    F32 getDetailDistance() const { return mDetailDistance; }
 
+   F32 getMacroSize() const { return mMacroSize; }
+
+   F32 getMacroDistance() const { return mMacroDistance; }
+
+   F32 getMacroStrength() const { return mMacroStrength; }
+
    bool useSideProjection() const { return mSideProjection; }
 
    F32 getParallaxScale() const { return mParallaxScale; }

+ 4 - 0
Engine/source/terrain/terrRender.cpp

@@ -94,6 +94,10 @@ void TerrainBlock::_updateMaterials()
       if (  mat->getDetailMap().isNotEmpty() &&
             mat->getDetailDistance() > mMaxDetailDistance )
          mMaxDetailDistance = mat->getDetailDistance();
+
+      if (  mat->getMacroMap().isNotEmpty() &&
+            mat->getMacroDistance() > mMaxDetailDistance )
+         mMaxDetailDistance = mat->getMacroDistance();
    }
 
    if ( mCell )

File diff suppressed because it is too large
+ 410 - 83
Templates/Empty PhysX/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui


+ 57 - 0
Templates/Empty PhysX/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs

@@ -247,6 +247,29 @@ function TerrainMaterialDlg::changeDetail( %this )
    %ctrl.setBitmap( %file );  
 }
 
+//----------------------------------------------------------------------------
+
+function TerrainMaterialDlg::changeMacro( %this )
+{
+   %ctrl = %this-->macroTexCtrl;
+   %file = %ctrl.bitmap;
+   if( getSubStr( %file, 0 , 6 ) $= "tools/" )
+      %file = "";
+
+   %file = TerrainMaterialDlg._selectTextureFileDialog( %file );  
+   if( %file $= "" )
+   {
+      if( %ctrl.bitmap !$= "" )
+         %file = %ctrl.bitmap;
+      else
+         %file = "tools/materialeditor/gui/unknownImage";
+   }
+   
+   %file = makeRelativePath( %file, getMainDotCsDir() );
+   %ctrl.setBitmap( %file );  
+}
+
+
 //-----------------------------------------------------------------------------
 
 function TerrainMaterialDlg::changeNormal( %this )
@@ -362,6 +385,11 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       }else{
          %this-->detailTexCtrl.setBitmap( %mat.detailMap );
       }
+      if (%mat.macroMap $= ""){
+         %this-->macroTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
+      }else{
+         %this-->macroTexCtrl.setBitmap( %mat.macroMap );
+      }      
       if (%mat.normalMap $= ""){
          %this-->normTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
       }else{
@@ -373,6 +401,10 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       %this-->detDistanceCtrl.setText( %mat.detailDistance );      
       %this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
       %this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
+
+      %this-->macroSizeCtrl.setText( %mat.macroSize );
+      %this-->macroStrengthCtrl.setText( %mat.macroStrength );
+      %this-->macroDistanceCtrl.setText( %mat.macroDistance );      
             
       %this.activateMaterialCtrls( true );      
    }
@@ -411,12 +443,21 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    }else{
       %newDetail = %this-->detailTexCtrl.bitmap;  
    }
+   if (%this-->macroTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){
+      %newMacro = "";
+   }else{
+      %newMacro = %this-->macroTexCtrl.bitmap;  
+   }
    %detailSize = %this-->detSizeCtrl.getText();      
    %diffuseSize = %this-->baseSizeCtrl.getText();     
    %detailStrength = %this-->detStrengthCtrl.getText();
    %detailDistance = %this-->detDistanceCtrl.getText();   
    %useSideProjection = %this-->sideProjectionCtrl.getValue();   
    %parallaxScale = %this-->parallaxScaleCtrl.getText();
+
+   %macroSize = %this-->macroSizeCtrl.getText();      
+   %macroStrength = %this-->macroStrengthCtrl.getText();
+   %macroDistance = %this-->macroDistanceCtrl.getText();   
    
    // If no properties of this materials have changed,
    // return.
@@ -425,11 +466,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
          %mat.diffuseMap $= %newDiffuse &&
          %mat.normalMap $= %newNormal &&
          %mat.detailMap $= %newDetail &&
+         %mat.macroMap $= %newMacro &&
          %mat.detailSize == %detailSize &&
          %mat.diffuseSize == %diffuseSize &&
          %mat.detailStrength == %detailStrength &&
          %mat.detailDistance == %detailDistance &&         
          %mat.useSideProjection == %useSideProjection &&
+         %mat.macroSize == %macroSize &&
+         %mat.macroStrength == %macroStrength &&
+         %mat.macroDistance == %macroDistance &&         
          %mat.parallaxScale == %parallaxScale )               
       return;
       
@@ -454,10 +499,14 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    %mat.diffuseMap = %newDiffuse;    
    %mat.normalMap = %newNormal;    
    %mat.detailMap = %newDetail;    
+   %mat.macroMap = %newMacro;
    %mat.detailSize = %detailSize;  
    %mat.diffuseSize = %diffuseSize;
    %mat.detailStrength = %detailStrength;    
    %mat.detailDistance = %detailDistance;    
+   %mat.macroSize = %macroSize;  
+   %mat.macroStrength = %macroStrength;    
+   %mat.macroDistance = %macroDistance;    
    %mat.useSideProjection = %useSideProjection;
    %mat.parallaxScale = %parallaxScale;
    
@@ -495,10 +544,14 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
          diffuseMap = %mat.diffuseMap;
          normalMap = %mat.normalMap;
          detailMap = %mat.detailMap;
+         macroMap = %mat.macroMap;
          detailSize = %mat.detailSize;
          diffuseSize = %mat.diffuseSize;
          detailStrength = %mat.detailStrength;
          detailDistance = %mat.detailDistance;
+         macroSize = %mat.macroSize;
+         macroStrength = %mat.macroStrength;
+         macroDistance = %mat.macroDistance;
          useSideProjection = %mat.useSideProjection;
          parallaxScale = %mat.parallaxScale;
       };
@@ -525,10 +578,14 @@ function TerrainMaterialDlg::restoreMaterials( %this )
       %mat.diffuseMap = %obj.diffuseMap;
       %mat.normalMap = %obj.normalMap;
       %mat.detailMap = %obj.detailMap;
+      %mat.macroMap = %obj.macroMap;
       %mat.detailSize = %obj.detailSize;
       %mat.diffuseSize = %obj.diffuseSize;
       %mat.detailStrength = %obj.detailStrength;
       %mat.detailDistance = %obj.detailDistance;
+      %mat.macroSize = %obj.macroSize;
+      %mat.macroStrength = %obj.macroStrength;
+      %mat.macroDistance = %obj.macroDistance;
       %mat.useSideProjection = %obj.useSideProjection;
       %mat.parallaxScale = %obj.parallaxScale;
    }

+ 338 - 11
Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui

@@ -6,7 +6,7 @@
    HorizSizing = "right";
    VertSizing = "bottom";
    position = "0 0";
-   Extent = "800 600";
+   Extent = "800 768";
    MinExtent = "8 2";
    canSave = "1";
    Visible = "1";
@@ -20,8 +20,8 @@
       HorizSizing = "center";
       VertSizing = "center";
       position = "221 151";
-      Extent = "394 322";
-      MinExtent = "358 298";
+      Extent = "394 432";
+      MinExtent = "358 432";
       canSave = "1";
       Visible = "1";
       tooltipprofile = "ToolsGuiToolTipProfile";
@@ -106,7 +106,7 @@
          HorizSizing = "left";
          VertSizing = "height";
          position = "202 26";
-         Extent = "185 263";
+         Extent = "185 363";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -132,7 +132,7 @@
             Visible = "1";
             tooltipprofile = "ToolsGuiToolTipProfile";
             hovertime = "1000";
-            bitmap = "tools/gui/images/separator-v";
+            bitmap = "core/art/gui/images/separator-v";
             wrap = "0";
          };
          new GuiTextCtrl() {
@@ -438,7 +438,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "width";
             VertSizing = "bottom";
-            position = "6 206";
+            position = "6 295";
             Extent = "185 50";
             MinExtent = "8 2";
             canSave = "1";
@@ -622,6 +622,333 @@
                passwordMask = "*";
             };
          };
+
+         new GuiBitmapCtrl() {
+            bitmap = "tools/gui/images/separator-v";
+            wrap = "0";
+            position = "6 288";
+            extent = "175 2";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "ToolsGuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiContainer() {
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "6 122";
+            extent = "185 72";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "ToolsGuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiBitmapCtrl() {
+               bitmap = "tools/materialeditor/gui/unknownImage";
+               wrap = "0";
+               position = "1 1";
+               extent = "47 47";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroTexCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiBitmapButtonCtrl() {
+               bitmap = "tools/materialEditor/gui/cubemapBtnBorder";
+               bitmapMode = "Stretched";
+               autoFitExtents = "0";
+               useModifiers = "0";
+               useStates = "1";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "1 1";
+               extent = "48 48";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg.changeMacro();";
+               tooltipProfile = "ToolsGuiDefaultProfile";
+               tooltip = "Change the active Macro Map for this layer.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Macro";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "56 -3";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "EditorTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "None";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "56 17";
+               extent = "116 17";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiButtonCtrl() {
+               text = "Edit";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "116 0";
+               extent = "40 16";
+               minExtent = "8 2";
+               horizSizing = "left";
+               vertSizing = "bottom";
+               profile = "ToolsGuiButtonProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg.changeMacro();";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiBitmapButtonCtrl() {
+               bitmap = "tools/gui/images/delete";
+               bitmapMode = "Stretched";
+               autoFitExtents = "0";
+               useModifiers = "0";
+               useStates = "1";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "159 0";
+               extent = "16 16";
+               minExtent = "8 2";
+               horizSizing = "left";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg-->macroTexCtrl.setBitmap(\"tools/materialeditor/gui/unknownImage\");";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Size";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "132 33";
+               extent = "39 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "94 32";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroSizeCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Strength";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "39 54";
+               extent = "46 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "1 53";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroStrengthCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Distance";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "132 54";
+               extent = "45 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "94 53";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroDistanceCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         
          new GuiBitmapCtrl() {
             canSaveDynamicFields = "0";
             isContainer = "0";
@@ -644,7 +971,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "width";
             VertSizing = "bottom";
-            position = "6 122";
+            position = "6 206";
             Extent = "185 72";
             MinExtent = "8 2";
             canSave = "1";
@@ -933,7 +1260,7 @@
          HorizSizing = "width";
          VertSizing = "height";
          position = "6 42";
-         Extent = "189 273";
+         Extent = "189 373";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -947,7 +1274,7 @@
             HorizSizing = "width";
             VertSizing = "height";
             position = "0 0";
-            Extent = "189 274";
+            Extent = "189 374";
             MinExtent = "8 2";
             canSave = "1";
             Visible = "1";
@@ -1006,7 +1333,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "202 294";
+         position = "202 394";
          Extent = "98 22";
          MinExtent = "8 2";
          canSave = "1";
@@ -1025,7 +1352,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "307 294";
+         position = "307 394";
          Extent = "80 22";
          MinExtent = "8 2";
          canSave = "1";

+ 57 - 0
Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs

@@ -247,6 +247,29 @@ function TerrainMaterialDlg::changeDetail( %this )
    %ctrl.setBitmap( %file );  
 }
 
+//----------------------------------------------------------------------------
+
+function TerrainMaterialDlg::changeMacro( %this )
+{
+   %ctrl = %this-->macroTexCtrl;
+   %file = %ctrl.bitmap;
+   if( getSubStr( %file, 0 , 6 ) $= "tools/" )
+      %file = "";
+
+   %file = TerrainMaterialDlg._selectTextureFileDialog( %file );  
+   if( %file $= "" )
+   {
+      if( %ctrl.bitmap !$= "" )
+         %file = %ctrl.bitmap;
+      else
+         %file = "tools/materialeditor/gui/unknownImage";
+   }
+   
+   %file = makeRelativePath( %file, getMainDotCsDir() );
+   %ctrl.setBitmap( %file );  
+}
+
+
 //-----------------------------------------------------------------------------
 
 function TerrainMaterialDlg::changeNormal( %this )
@@ -362,6 +385,11 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       }else{
          %this-->detailTexCtrl.setBitmap( %mat.detailMap );
       }
+      if (%mat.macroMap $= ""){
+         %this-->macroTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
+      }else{
+         %this-->macroTexCtrl.setBitmap( %mat.macroMap );
+      }      
       if (%mat.normalMap $= ""){
          %this-->normTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
       }else{
@@ -373,6 +401,10 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       %this-->detDistanceCtrl.setText( %mat.detailDistance );      
       %this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
       %this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
+
+      %this-->macroSizeCtrl.setText( %mat.macroSize );
+      %this-->macroStrengthCtrl.setText( %mat.macroStrength );
+      %this-->macroDistanceCtrl.setText( %mat.macroDistance );      
             
       %this.activateMaterialCtrls( true );      
    }
@@ -411,12 +443,21 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    }else{
       %newDetail = %this-->detailTexCtrl.bitmap;  
    }
+   if (%this-->macroTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){
+      %newMacro = "";
+   }else{
+      %newMacro = %this-->macroTexCtrl.bitmap;  
+   }
    %detailSize = %this-->detSizeCtrl.getText();      
    %diffuseSize = %this-->baseSizeCtrl.getText();     
    %detailStrength = %this-->detStrengthCtrl.getText();
    %detailDistance = %this-->detDistanceCtrl.getText();   
    %useSideProjection = %this-->sideProjectionCtrl.getValue();   
    %parallaxScale = %this-->parallaxScaleCtrl.getText();
+
+   %macroSize = %this-->macroSizeCtrl.getText();      
+   %macroStrength = %this-->macroStrengthCtrl.getText();
+   %macroDistance = %this-->macroDistanceCtrl.getText();   
    
    // If no properties of this materials have changed,
    // return.
@@ -425,11 +466,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
          %mat.diffuseMap $= %newDiffuse &&
          %mat.normalMap $= %newNormal &&
          %mat.detailMap $= %newDetail &&
+         %mat.macroMap $= %newMacro &&
          %mat.detailSize == %detailSize &&
          %mat.diffuseSize == %diffuseSize &&
          %mat.detailStrength == %detailStrength &&
          %mat.detailDistance == %detailDistance &&         
          %mat.useSideProjection == %useSideProjection &&
+         %mat.macroSize == %macroSize &&
+         %mat.macroStrength == %macroStrength &&
+         %mat.macroDistance == %macroDistance &&         
          %mat.parallaxScale == %parallaxScale )               
       return;
       
@@ -454,10 +499,14 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    %mat.diffuseMap = %newDiffuse;    
    %mat.normalMap = %newNormal;    
    %mat.detailMap = %newDetail;    
+   %mat.macroMap = %newMacro;
    %mat.detailSize = %detailSize;  
    %mat.diffuseSize = %diffuseSize;
    %mat.detailStrength = %detailStrength;    
    %mat.detailDistance = %detailDistance;    
+   %mat.macroSize = %macroSize;  
+   %mat.macroStrength = %macroStrength;    
+   %mat.macroDistance = %macroDistance;    
    %mat.useSideProjection = %useSideProjection;
    %mat.parallaxScale = %parallaxScale;
    
@@ -495,10 +544,14 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
          diffuseMap = %mat.diffuseMap;
          normalMap = %mat.normalMap;
          detailMap = %mat.detailMap;
+         macroMap = %mat.macroMap;
          detailSize = %mat.detailSize;
          diffuseSize = %mat.diffuseSize;
          detailStrength = %mat.detailStrength;
          detailDistance = %mat.detailDistance;
+         macroSize = %mat.macroSize;
+         macroStrength = %mat.macroStrength;
+         macroDistance = %mat.macroDistance;
          useSideProjection = %mat.useSideProjection;
          parallaxScale = %mat.parallaxScale;
       };
@@ -525,10 +578,14 @@ function TerrainMaterialDlg::restoreMaterials( %this )
       %mat.diffuseMap = %obj.diffuseMap;
       %mat.normalMap = %obj.normalMap;
       %mat.detailMap = %obj.detailMap;
+      %mat.macroMap = %obj.macroMap;
       %mat.detailSize = %obj.detailSize;
       %mat.diffuseSize = %obj.diffuseSize;
       %mat.detailStrength = %obj.detailStrength;
       %mat.detailDistance = %obj.detailDistance;
+      %mat.macroSize = %obj.macroSize;
+      %mat.macroStrength = %obj.macroStrength;
+      %mat.macroDistance = %obj.macroDistance;
       %mat.useSideProjection = %obj.useSideProjection;
       %mat.parallaxScale = %obj.parallaxScale;
    }

File diff suppressed because it is too large
+ 410 - 83
Templates/Full PhysX/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui


+ 57 - 0
Templates/Full PhysX/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs

@@ -247,6 +247,29 @@ function TerrainMaterialDlg::changeDetail( %this )
    %ctrl.setBitmap( %file );  
 }
 
+//----------------------------------------------------------------------------
+
+function TerrainMaterialDlg::changeMacro( %this )
+{
+   %ctrl = %this-->macroTexCtrl;
+   %file = %ctrl.bitmap;
+   if( getSubStr( %file, 0 , 6 ) $= "tools/" )
+      %file = "";
+
+   %file = TerrainMaterialDlg._selectTextureFileDialog( %file );  
+   if( %file $= "" )
+   {
+      if( %ctrl.bitmap !$= "" )
+         %file = %ctrl.bitmap;
+      else
+         %file = "tools/materialeditor/gui/unknownImage";
+   }
+   
+   %file = makeRelativePath( %file, getMainDotCsDir() );
+   %ctrl.setBitmap( %file );  
+}
+
+
 //-----------------------------------------------------------------------------
 
 function TerrainMaterialDlg::changeNormal( %this )
@@ -362,6 +385,11 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       }else{
          %this-->detailTexCtrl.setBitmap( %mat.detailMap );
       }
+      if (%mat.macroMap $= ""){
+         %this-->macroTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
+      }else{
+         %this-->macroTexCtrl.setBitmap( %mat.macroMap );
+      }      
       if (%mat.normalMap $= ""){
          %this-->normTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
       }else{
@@ -373,6 +401,10 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       %this-->detDistanceCtrl.setText( %mat.detailDistance );      
       %this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
       %this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
+
+      %this-->macroSizeCtrl.setText( %mat.macroSize );
+      %this-->macroStrengthCtrl.setText( %mat.macroStrength );
+      %this-->macroDistanceCtrl.setText( %mat.macroDistance );      
             
       %this.activateMaterialCtrls( true );      
    }
@@ -411,12 +443,21 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    }else{
       %newDetail = %this-->detailTexCtrl.bitmap;  
    }
+   if (%this-->macroTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){
+      %newMacro = "";
+   }else{
+      %newMacro = %this-->macroTexCtrl.bitmap;  
+   }
    %detailSize = %this-->detSizeCtrl.getText();      
    %diffuseSize = %this-->baseSizeCtrl.getText();     
    %detailStrength = %this-->detStrengthCtrl.getText();
    %detailDistance = %this-->detDistanceCtrl.getText();   
    %useSideProjection = %this-->sideProjectionCtrl.getValue();   
    %parallaxScale = %this-->parallaxScaleCtrl.getText();
+
+   %macroSize = %this-->macroSizeCtrl.getText();      
+   %macroStrength = %this-->macroStrengthCtrl.getText();
+   %macroDistance = %this-->macroDistanceCtrl.getText();   
    
    // If no properties of this materials have changed,
    // return.
@@ -425,11 +466,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
          %mat.diffuseMap $= %newDiffuse &&
          %mat.normalMap $= %newNormal &&
          %mat.detailMap $= %newDetail &&
+         %mat.macroMap $= %newMacro &&
          %mat.detailSize == %detailSize &&
          %mat.diffuseSize == %diffuseSize &&
          %mat.detailStrength == %detailStrength &&
          %mat.detailDistance == %detailDistance &&         
          %mat.useSideProjection == %useSideProjection &&
+         %mat.macroSize == %macroSize &&
+         %mat.macroStrength == %macroStrength &&
+         %mat.macroDistance == %macroDistance &&         
          %mat.parallaxScale == %parallaxScale )               
       return;
       
@@ -454,10 +499,14 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    %mat.diffuseMap = %newDiffuse;    
    %mat.normalMap = %newNormal;    
    %mat.detailMap = %newDetail;    
+   %mat.macroMap = %newMacro;
    %mat.detailSize = %detailSize;  
    %mat.diffuseSize = %diffuseSize;
    %mat.detailStrength = %detailStrength;    
    %mat.detailDistance = %detailDistance;    
+   %mat.macroSize = %macroSize;  
+   %mat.macroStrength = %macroStrength;    
+   %mat.macroDistance = %macroDistance;    
    %mat.useSideProjection = %useSideProjection;
    %mat.parallaxScale = %parallaxScale;
    
@@ -495,10 +544,14 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
          diffuseMap = %mat.diffuseMap;
          normalMap = %mat.normalMap;
          detailMap = %mat.detailMap;
+         macroMap = %mat.macroMap;
          detailSize = %mat.detailSize;
          diffuseSize = %mat.diffuseSize;
          detailStrength = %mat.detailStrength;
          detailDistance = %mat.detailDistance;
+         macroSize = %mat.macroSize;
+         macroStrength = %mat.macroStrength;
+         macroDistance = %mat.macroDistance;
          useSideProjection = %mat.useSideProjection;
          parallaxScale = %mat.parallaxScale;
       };
@@ -525,10 +578,14 @@ function TerrainMaterialDlg::restoreMaterials( %this )
       %mat.diffuseMap = %obj.diffuseMap;
       %mat.normalMap = %obj.normalMap;
       %mat.detailMap = %obj.detailMap;
+      %mat.macroMap = %obj.macroMap;
       %mat.detailSize = %obj.detailSize;
       %mat.diffuseSize = %obj.diffuseSize;
       %mat.detailStrength = %obj.detailStrength;
       %mat.detailDistance = %obj.detailDistance;
+      %mat.macroSize = %obj.macroSize;
+      %mat.macroStrength = %obj.macroStrength;
+      %mat.macroDistance = %obj.macroDistance;
       %mat.useSideProjection = %obj.useSideProjection;
       %mat.parallaxScale = %obj.parallaxScale;
    }

+ 338 - 11
Templates/Full/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui

@@ -6,7 +6,7 @@
    HorizSizing = "right";
    VertSizing = "bottom";
    position = "0 0";
-   Extent = "800 600";
+   Extent = "800 768";
    MinExtent = "8 2";
    canSave = "1";
    Visible = "1";
@@ -20,8 +20,8 @@
       HorizSizing = "center";
       VertSizing = "center";
       position = "221 151";
-      Extent = "394 322";
-      MinExtent = "358 298";
+      Extent = "394 432";
+      MinExtent = "358 432";
       canSave = "1";
       Visible = "1";
       tooltipprofile = "ToolsGuiToolTipProfile";
@@ -106,7 +106,7 @@
          HorizSizing = "left";
          VertSizing = "height";
          position = "202 26";
-         Extent = "185 263";
+         Extent = "185 363";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -132,7 +132,7 @@
             Visible = "1";
             tooltipprofile = "ToolsGuiToolTipProfile";
             hovertime = "1000";
-            bitmap = "tools/gui/images/separator-v";
+            bitmap = "core/art/gui/images/separator-v";
             wrap = "0";
          };
          new GuiTextCtrl() {
@@ -438,7 +438,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "width";
             VertSizing = "bottom";
-            position = "6 206";
+            position = "6 295";
             Extent = "185 50";
             MinExtent = "8 2";
             canSave = "1";
@@ -622,6 +622,333 @@
                passwordMask = "*";
             };
          };
+
+         new GuiBitmapCtrl() {
+            bitmap = "tools/gui/images/separator-v";
+            wrap = "0";
+            position = "6 288";
+            extent = "175 2";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "ToolsGuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiContainer() {
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "6 122";
+            extent = "185 72";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "ToolsGuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiBitmapCtrl() {
+               bitmap = "tools/materialeditor/gui/unknownImage";
+               wrap = "0";
+               position = "1 1";
+               extent = "47 47";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroTexCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiBitmapButtonCtrl() {
+               bitmap = "tools/materialEditor/gui/cubemapBtnBorder";
+               bitmapMode = "Stretched";
+               autoFitExtents = "0";
+               useModifiers = "0";
+               useStates = "1";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "1 1";
+               extent = "48 48";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg.changeMacro();";
+               tooltipProfile = "ToolsGuiDefaultProfile";
+               tooltip = "Change the active Macro Map for this layer.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Macro";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "56 -3";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "EditorTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "None";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "56 17";
+               extent = "116 17";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiButtonCtrl() {
+               text = "Edit";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "116 0";
+               extent = "40 16";
+               minExtent = "8 2";
+               horizSizing = "left";
+               vertSizing = "bottom";
+               profile = "ToolsGuiButtonProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg.changeMacro();";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiBitmapButtonCtrl() {
+               bitmap = "tools/gui/images/delete";
+               bitmapMode = "Stretched";
+               autoFitExtents = "0";
+               useModifiers = "0";
+               useStates = "1";
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "0";
+               position = "159 0";
+               extent = "16 16";
+               minExtent = "8 2";
+               horizSizing = "left";
+               vertSizing = "bottom";
+               profile = "ToolsGuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               command = "TerrainMaterialDlg-->macroTexCtrl.setBitmap(\"tools/materialeditor/gui/unknownImage\");";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Size";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "132 33";
+               extent = "39 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "94 32";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroSizeCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Strength";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "39 54";
+               extent = "46 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "1 53";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroStrengthCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Distance";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "132 54";
+               extent = "45 16";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextEditCtrl() {
+               historySize = "0";
+               tabComplete = "0";
+               sinkAllKeyEvents = "0";
+               password = "0";
+               passwordMask = "*";
+               maxLength = "1024";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "0";
+               anchorBottom = "0";
+               anchorLeft = "0";
+               anchorRight = "0";
+               position = "94 53";
+               extent = "34 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "ToolsGuiTextEditProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "ToolsGuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "macroDistanceCtrl";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         
          new GuiBitmapCtrl() {
             canSaveDynamicFields = "0";
             isContainer = "0";
@@ -644,7 +971,7 @@
             Profile = "ToolsGuiDefaultProfile";
             HorizSizing = "width";
             VertSizing = "bottom";
-            position = "6 122";
+            position = "6 206";
             Extent = "185 72";
             MinExtent = "8 2";
             canSave = "1";
@@ -933,7 +1260,7 @@
          HorizSizing = "width";
          VertSizing = "height";
          position = "6 42";
-         Extent = "189 273";
+         Extent = "189 373";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -947,7 +1274,7 @@
             HorizSizing = "width";
             VertSizing = "height";
             position = "0 0";
-            Extent = "189 274";
+            Extent = "189 374";
             MinExtent = "8 2";
             canSave = "1";
             Visible = "1";
@@ -1006,7 +1333,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "202 294";
+         position = "202 394";
          Extent = "98 22";
          MinExtent = "8 2";
          canSave = "1";
@@ -1025,7 +1352,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "307 294";
+         position = "307 394";
          Extent = "80 22";
          MinExtent = "8 2";
          canSave = "1";

+ 57 - 0
Templates/Full/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs

@@ -247,6 +247,29 @@ function TerrainMaterialDlg::changeDetail( %this )
    %ctrl.setBitmap( %file );  
 }
 
+//----------------------------------------------------------------------------
+
+function TerrainMaterialDlg::changeMacro( %this )
+{
+   %ctrl = %this-->macroTexCtrl;
+   %file = %ctrl.bitmap;
+   if( getSubStr( %file, 0 , 6 ) $= "tools/" )
+      %file = "";
+
+   %file = TerrainMaterialDlg._selectTextureFileDialog( %file );  
+   if( %file $= "" )
+   {
+      if( %ctrl.bitmap !$= "" )
+         %file = %ctrl.bitmap;
+      else
+         %file = "tools/materialeditor/gui/unknownImage";
+   }
+   
+   %file = makeRelativePath( %file, getMainDotCsDir() );
+   %ctrl.setBitmap( %file );  
+}
+
+
 //-----------------------------------------------------------------------------
 
 function TerrainMaterialDlg::changeNormal( %this )
@@ -362,6 +385,11 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       }else{
          %this-->detailTexCtrl.setBitmap( %mat.detailMap );
       }
+      if (%mat.macroMap $= ""){
+         %this-->macroTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
+      }else{
+         %this-->macroTexCtrl.setBitmap( %mat.macroMap );
+      }      
       if (%mat.normalMap $= ""){
          %this-->normTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" );
       }else{
@@ -373,6 +401,10 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
       %this-->detDistanceCtrl.setText( %mat.detailDistance );      
       %this-->sideProjectionCtrl.setValue( %mat.useSideProjection );
       %this-->parallaxScaleCtrl.setText( %mat.parallaxScale );
+
+      %this-->macroSizeCtrl.setText( %mat.macroSize );
+      %this-->macroStrengthCtrl.setText( %mat.macroStrength );
+      %this-->macroDistanceCtrl.setText( %mat.macroDistance );      
             
       %this.activateMaterialCtrls( true );      
    }
@@ -411,12 +443,21 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    }else{
       %newDetail = %this-->detailTexCtrl.bitmap;  
    }
+   if (%this-->macroTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){
+      %newMacro = "";
+   }else{
+      %newMacro = %this-->macroTexCtrl.bitmap;  
+   }
    %detailSize = %this-->detSizeCtrl.getText();      
    %diffuseSize = %this-->baseSizeCtrl.getText();     
    %detailStrength = %this-->detStrengthCtrl.getText();
    %detailDistance = %this-->detDistanceCtrl.getText();   
    %useSideProjection = %this-->sideProjectionCtrl.getValue();   
    %parallaxScale = %this-->parallaxScaleCtrl.getText();
+
+   %macroSize = %this-->macroSizeCtrl.getText();      
+   %macroStrength = %this-->macroStrengthCtrl.getText();
+   %macroDistance = %this-->macroDistanceCtrl.getText();   
    
    // If no properties of this materials have changed,
    // return.
@@ -425,11 +466,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
          %mat.diffuseMap $= %newDiffuse &&
          %mat.normalMap $= %newNormal &&
          %mat.detailMap $= %newDetail &&
+         %mat.macroMap $= %newMacro &&
          %mat.detailSize == %detailSize &&
          %mat.diffuseSize == %diffuseSize &&
          %mat.detailStrength == %detailStrength &&
          %mat.detailDistance == %detailDistance &&         
          %mat.useSideProjection == %useSideProjection &&
+         %mat.macroSize == %macroSize &&
+         %mat.macroStrength == %macroStrength &&
+         %mat.macroDistance == %macroDistance &&         
          %mat.parallaxScale == %parallaxScale )               
       return;
       
@@ -454,10 +499,14 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
    %mat.diffuseMap = %newDiffuse;    
    %mat.normalMap = %newNormal;    
    %mat.detailMap = %newDetail;    
+   %mat.macroMap = %newMacro;
    %mat.detailSize = %detailSize;  
    %mat.diffuseSize = %diffuseSize;
    %mat.detailStrength = %detailStrength;    
    %mat.detailDistance = %detailDistance;    
+   %mat.macroSize = %macroSize;  
+   %mat.macroStrength = %macroStrength;    
+   %mat.macroDistance = %macroDistance;    
    %mat.useSideProjection = %useSideProjection;
    %mat.parallaxScale = %parallaxScale;
    
@@ -495,10 +544,14 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
          diffuseMap = %mat.diffuseMap;
          normalMap = %mat.normalMap;
          detailMap = %mat.detailMap;
+         macroMap = %mat.macroMap;
          detailSize = %mat.detailSize;
          diffuseSize = %mat.diffuseSize;
          detailStrength = %mat.detailStrength;
          detailDistance = %mat.detailDistance;
+         macroSize = %mat.macroSize;
+         macroStrength = %mat.macroStrength;
+         macroDistance = %mat.macroDistance;
          useSideProjection = %mat.useSideProjection;
          parallaxScale = %mat.parallaxScale;
       };
@@ -525,10 +578,14 @@ function TerrainMaterialDlg::restoreMaterials( %this )
       %mat.diffuseMap = %obj.diffuseMap;
       %mat.normalMap = %obj.normalMap;
       %mat.detailMap = %obj.detailMap;
+      %mat.macroMap = %obj.macroMap;
       %mat.detailSize = %obj.detailSize;
       %mat.diffuseSize = %obj.diffuseSize;
       %mat.detailStrength = %obj.detailStrength;
       %mat.detailDistance = %obj.detailDistance;
+      %mat.macroSize = %obj.macroSize;
+      %mat.macroStrength = %obj.macroStrength;
+      %mat.macroDistance = %obj.macroDistance;
       %mat.useSideProjection = %obj.useSideProjection;
       %mat.parallaxScale = %obj.parallaxScale;
    }

Some files were not shown because too many files changed in this diff