Browse Source

Merge branch 'development' into defineconsolemethod

Conflicts:
	Engine/source/materials/materialDefinition.cpp
Daniel Buckmaster 10 years ago
parent
commit
ae284a89ec
100 changed files with 2941 additions and 796 deletions
  1. 349 0
      Engine/source/T3D/accumulationVolume.cpp
  2. 104 0
      Engine/source/T3D/accumulationVolume.h
  3. 8 0
      Engine/source/T3D/fx/particleEmitter.cpp
  4. 1 0
      Engine/source/T3D/fx/particleEmitter.h
  5. 4 2
      Engine/source/T3D/gameBase/gameBase.cpp
  6. 4 0
      Engine/source/T3D/gameBase/gameBase.h
  7. 30 0
      Engine/source/T3D/gameBase/gameConnection.cpp
  8. 5 0
      Engine/source/T3D/gameBase/gameConnection.h
  9. 6 1
      Engine/source/T3D/levelInfo.cpp
  10. 2 1
      Engine/source/T3D/levelInfo.h
  11. 29 4
      Engine/source/T3D/tsStatic.cpp
  12. 10 10
      Engine/source/app/net/serverQuery.cpp
  13. 23 17
      Engine/source/console/compiledEval.cpp
  14. 2 0
      Engine/source/console/consoleInternal.cpp
  15. 2 0
      Engine/source/console/consoleInternal.h
  16. 73 19
      Engine/source/console/simDictionary.cpp
  17. 42 0
      Engine/source/console/simDictionary.h
  18. 7 1
      Engine/source/console/stringStack.cpp
  19. 18 1
      Engine/source/console/stringStack.h
  20. 1 1
      Engine/source/core/ogg/oggVorbisDecoder.cpp
  21. 4 0
      Engine/source/environment/waterObject.cpp
  22. 9 9
      Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h
  23. 7 0
      Engine/source/gfx/gl/gfxGLUtils.h
  24. 74 1
      Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp
  25. 74 1
      Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp
  26. 1 0
      Engine/source/materials/baseMatInstance.h
  27. 8 0
      Engine/source/materials/matInstance.cpp
  28. 1 0
      Engine/source/materials/matInstance.h
  29. 40 0
      Engine/source/materials/materialDefinition.cpp
  30. 10 0
      Engine/source/materials/materialDefinition.h
  31. 8 0
      Engine/source/materials/materialFeatureTypes.cpp
  32. 7 0
      Engine/source/materials/materialFeatureTypes.h
  33. 1 0
      Engine/source/materials/processedCustomMaterial.cpp
  34. 1 0
      Engine/source/materials/processedFFMaterial.cpp
  35. 1 0
      Engine/source/materials/processedMaterial.cpp
  36. 6 0
      Engine/source/materials/processedMaterial.h
  37. 51 0
      Engine/source/materials/processedShaderMaterial.cpp
  38. 5 0
      Engine/source/materials/processedShaderMaterial.h
  39. 1 0
      Engine/source/materials/sceneData.h
  40. 3 0
      Engine/source/platform/platform.h
  41. 2 2
      Engine/source/platform/platformAssert.h
  42. 21 0
      Engine/source/platform/platformCPU.cpp
  43. 2 0
      Engine/source/platformWin32/menus/menuBarWin32.cpp
  44. 1 1
      Engine/source/platformWin32/winTime.cpp
  45. 1 0
      Engine/source/renderInstance/renderBinManager.cpp
  46. 40 1
      Engine/source/renderInstance/renderGlowMgr.cpp
  47. 2 1
      Engine/source/renderInstance/renderGlowMgr.h
  48. 10 0
      Engine/source/renderInstance/renderMeshMgr.cpp
  49. 65 60
      Engine/source/renderInstance/renderParticleMgr.cpp
  50. 3 1
      Engine/source/renderInstance/renderParticleMgr.h
  51. 3 0
      Engine/source/renderInstance/renderPassManager.h
  52. 1 1
      Engine/source/scene/sceneManager.cpp
  53. 4 0
      Engine/source/scene/sceneManager.h
  54. 11 0
      Engine/source/scene/sceneObject.cpp
  55. 10 0
      Engine/source/scene/sceneObject.h
  56. 241 0
      Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp
  57. 185 0
      Engine/source/shaderGen/GLSL/accuFeatureGLSL.h
  58. 6 12
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
  59. 2 0
      Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp
  60. 238 0
      Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp
  61. 185 0
      Engine/source/shaderGen/HLSL/accuFeatureHLSL.h
  62. 3 12
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  63. 2 1
      Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp
  64. 48 224
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  65. 0 9
      Engine/source/terrain/terrCellMaterial.cpp
  66. 0 4
      Engine/source/terrain/terrCellMaterial.h
  67. 1 5
      Engine/source/terrain/terrMaterial.cpp
  68. 0 7
      Engine/source/terrain/terrMaterial.h
  69. 5 2
      Engine/source/ts/tsMesh.cpp
  70. 2 1
      Engine/source/ts/tsRenderState.cpp
  71. 13 1
      Engine/source/ts/tsRenderState.h
  72. 13 1
      Engine/source/ts/tsShapeInstance.cpp
  73. 6 0
      Engine/source/ts/tsShapeInstance.h
  74. 1 0
      Engine/source/util/imposterCapture.cpp
  75. BIN
      Templates/Empty/game/art/terrains/Example/dirt_grass_n.png
  76. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry.jpg
  77. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry_d.png
  78. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry_n.png
  79. BIN
      Templates/Empty/game/art/terrains/Example/grass1_n.png
  80. BIN
      Templates/Empty/game/art/terrains/Example/grass2_n.png
  81. BIN
      Templates/Empty/game/art/terrains/Example/road_n.png
  82. BIN
      Templates/Empty/game/art/terrains/Example/rocks1_n.png
  83. BIN
      Templates/Empty/game/art/terrains/Example/rocktest_n.png
  84. BIN
      Templates/Empty/game/art/terrains/Example/sand_n.png
  85. BIN
      Templates/Empty/game/art/terrains/Example/snowtop_n.png
  86. BIN
      Templates/Empty/game/art/terrains/Example/stone_n.png
  87. 0 225
      Templates/Empty/game/art/terrains/materials.cs
  88. 9 10
      Templates/Empty/game/core/scripts/client/audio.cs
  89. 4 0
      Templates/Empty/game/core/scripts/client/postFx/default.postfxpreset.cs
  90. 185 4
      Templates/Empty/game/core/scripts/client/postFx/postFXManager.gui
  91. 26 1
      Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.cs
  92. 15 0
      Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs
  93. 476 1
      Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui
  94. 21 0
      Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs
  95. 28 1
      Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui
  96. 2 0
      Templates/Empty/game/tools/particleEditor/particleEmitterEditor.ed.cs
  97. 5 51
      Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui
  98. 10 82
      Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui
  99. 1 0
      Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs
  100. 0 7
      Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs

+ 349 - 0
Engine/source/T3D/accumulationVolume.cpp

@@ -0,0 +1,349 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platform.h"
+#include "T3D/accumulationVolume.h"
+
+#include "scene/sceneManager.h"
+#include "scene/sceneRenderState.h"
+#include "gfx/gfxDevice.h"
+#include "gfx/gfxDrawUtil.h"
+#include "gfx/sim/debugDraw.h"
+#include "util/tempAlloc.h"
+#include "materials/materialDefinition.h"
+#include "materials/materialManager.h"
+#include "materials/materialFeatureTypes.h"
+#include "materials/matInstance.h"
+#include "console/consoleTypes.h"
+#include "core/stream/bitStream.h"
+#include "gfx/gfxDevice.h"
+#include "console/console.h"
+#include "console/engineAPI.h"
+#include "gfx/gfxTextureHandle.h"
+#include "scene/sceneContainer.h"
+
+#include "math/mPolyhedron.impl.h"
+
+Vector< SimObjectPtr<SceneObject> > AccumulationVolume::smAccuObjects;
+Vector< SimObjectPtr<AccumulationVolume> > AccumulationVolume::smAccuVolumes;
+
+//#define DEBUG_DRAW
+
+IMPLEMENT_CO_NETOBJECT_V1( AccumulationVolume );
+
+ConsoleDocClass( AccumulationVolume,
+   "@brief An invisible shape that allow objects within it to have an accumulation map.\n\n"
+
+   "AccumulationVolume is used to add additional realism to a scene. It's main use is in outdoor scenes "
+   " where objects could benefit from overlaying environment accumulation textures such as sand, snow, etc.\n\n"
+
+   "Objects within the volume must have accumulation enabled in their material. \n\n"
+
+   "@ingroup enviroMisc"
+);
+
+//-----------------------------------------------------------------------------
+
+AccumulationVolume::AccumulationVolume()
+   : mTransformDirty( true ),
+     mSilhouetteExtractor( mPolyhedron )
+{
+   VECTOR_SET_ASSOCIATION( mWSPoints );
+   VECTOR_SET_ASSOCIATION( mVolumeQueryList );
+
+   //mObjectFlags.set( VisualOccluderFlag );
+   
+   mNetFlags.set( Ghostable | ScopeAlways );
+   mObjScale.set( 1.f, 1.f, 1.f );
+   mObjBox.set(
+      Point3F( -0.5f, -0.5f, -0.5f ),
+      Point3F( 0.5f, 0.5f, 0.5f )
+   );
+
+   mObjToWorld.identity();
+   mWorldToObj.identity();
+
+   // Accumulation Texture.
+   mTextureName = "";
+   mAccuTexture = NULL;
+
+   resetWorldBox();
+}
+
+AccumulationVolume::~AccumulationVolume()
+{
+   mAccuTexture = NULL;
+}
+
+void AccumulationVolume::initPersistFields()
+{
+   addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
+         &_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
+
+   Parent::initPersistFields();
+}
+
+//-----------------------------------------------------------------------------
+
+void AccumulationVolume::consoleInit()
+{
+   // Disable rendering of occlusion volumes by default.
+   getStaticClassRep()->mIsRenderEnabled = false;
+}
+
+//-----------------------------------------------------------------------------
+
+bool AccumulationVolume::onAdd()
+{
+   if( !Parent::onAdd() )
+      return false;
+
+   // Prepare some client side things.
+   if ( isClientObject() )  
+   {
+      smAccuVolumes.push_back(this);
+      refreshVolumes();
+   }
+
+   // Set up the silhouette extractor.
+   mSilhouetteExtractor = SilhouetteExtractorType( mPolyhedron );
+
+   return true;
+}
+
+void AccumulationVolume::onRemove()
+{
+   if ( isClientObject() )  
+   {
+      smAccuVolumes.remove(this);
+      refreshVolumes();
+   }
+   Parent::onRemove();
+}
+
+//-----------------------------------------------------------------------------
+
+void AccumulationVolume::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat )
+{
+   Parent::_renderObject( ri, state, overrideMat );
+
+   #ifdef DEBUG_DRAW
+   if( state->isDiffusePass() )
+      DebugDrawer::get()->drawPolyhedronDebugInfo( mPolyhedron, getTransform(), getScale() );
+   #endif
+}
+
+//-----------------------------------------------------------------------------
+
+void AccumulationVolume::setTransform( const MatrixF& mat )
+{
+   Parent::setTransform( mat );
+   mTransformDirty = true;
+   refreshVolumes();
+}
+
+//-----------------------------------------------------------------------------
+
+void AccumulationVolume::buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F >& outPoints )
+{
+   // Extract the silhouette of the polyhedron.  This works differently
+   // depending on whether we project orthogonally or in perspective.
+
+   TempAlloc< U32 > indices( mPolyhedron.getNumPoints() );
+   U32 numPoints;
+
+   if( cameraState.getFrustum().isOrtho() )
+   {
+      // Transform the view direction into object space.
+
+      Point3F osViewDir;
+      getWorldTransform().mulV( cameraState.getViewDirection(), &osViewDir );
+
+      // And extract the silhouette.
+
+      SilhouetteExtractorOrtho< PolyhedronType > extractor( mPolyhedron );
+      numPoints = extractor.extractSilhouette( osViewDir, indices, indices.size );
+   }
+   else
+   {
+      // Create a transform to go from view space to object space.
+
+      MatrixF camView( true );
+      camView.scale( Point3F( 1.0f / getScale().x, 1.0f / getScale().y, 1.0f / getScale().z ) );
+      camView.mul( getRenderWorldTransform() );
+      camView.mul( cameraState.getViewWorldMatrix() );
+
+      // Do a perspective-correct silhouette extraction.
+
+      numPoints = mSilhouetteExtractor.extractSilhouette(
+         camView,
+         indices, indices.size );
+   }
+
+   // If we haven't yet, transform the polyhedron's points
+   // to world space.
+
+   if( mTransformDirty )
+   {
+      const U32 numPoints = mPolyhedron.getNumPoints();
+      const PolyhedronType::PointType* points = getPolyhedron().getPoints();
+
+      mWSPoints.setSize( numPoints );
+      for( U32 i = 0; i < numPoints; ++ i )
+      {
+         Point3F p = points[ i ];
+         p.convolve( getScale() );
+         getTransform().mulP( p, &mWSPoints[ i ] );
+      }
+
+      mTransformDirty = false;
+   }
+
+   // Now store the points.
+
+   outPoints.setSize( numPoints );
+   for( U32 i = 0; i < numPoints; ++ i )
+      outPoints[ i ] = mWSPoints[ indices[ i ] ];
+}
+
+//-----------------------------------------------------------------------------
+
+U32 AccumulationVolume::packUpdate( NetConnection *connection, U32 mask, BitStream *stream )
+{
+   U32 retMask = Parent::packUpdate( connection, mask, stream );
+
+   if (stream->writeFlag(mask & InitialUpdateMask))
+   {
+      stream->write( mTextureName );
+   }
+
+   return retMask;  
+}
+
+void AccumulationVolume::unpackUpdate( NetConnection *connection, BitStream *stream )
+{
+   Parent::unpackUpdate( connection, stream );
+
+   if (stream->readFlag())
+   {
+      stream->read( &mTextureName );
+      setTexture(mTextureName);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void AccumulationVolume::inspectPostApply()
+{
+   Parent::inspectPostApply();
+   setMaskBits(U32(-1) );
+}
+
+void AccumulationVolume::setTexture( const String& name )
+{
+   mTextureName = name;
+   if ( isClientObject() && mTextureName.isNotEmpty() )
+   {
+      mAccuTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "AccumulationVolume::mAccuTexture");
+      if ( mAccuTexture.isNull() )
+         Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
+   }
+   refreshVolumes();
+}
+
+//-----------------------------------------------------------------------------
+// Static Functions
+//-----------------------------------------------------------------------------
+bool AccumulationVolume::_setTexture( void *object, const char *index, const char *data )
+{
+   AccumulationVolume* volume = reinterpret_cast< AccumulationVolume* >( object );
+   volume->setTexture( data );
+   return false;
+}
+
+void AccumulationVolume::refreshVolumes()
+{
+   // This function tests each accumulation object to
+   // see if it's within the bounds of an accumulation
+   // volume. If so, it will pass on the accumulation
+   // texture of the volume to the object.
+
+   // This function should only be called when something
+   // global like change of volume or material occurs.
+
+   // Clear old data.
+   for (S32 n = 0; n < smAccuObjects.size(); ++n)
+   {
+      SimObjectPtr<SceneObject> object = smAccuObjects[n];
+      if ( object.isValid() )
+         object->mAccuTex = GFXTexHandle::ZERO;
+   }
+
+   // 
+   for (S32 i = 0; i < smAccuVolumes.size(); ++i)
+   {
+      SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
+      if ( volume.isNull() ) continue;
+
+      for (S32 n = 0; n < smAccuObjects.size(); ++n)
+      {
+         SimObjectPtr<SceneObject> object = smAccuObjects[n];
+         if ( object.isNull() ) continue;
+
+         if ( volume->containsPoint(object->getPosition()) )
+            object->mAccuTex = volume->mAccuTexture;
+      }
+   }
+}
+
+// Accumulation Object Management.
+void AccumulationVolume::addObject(SimObjectPtr<SceneObject> object)
+{
+   smAccuObjects.push_back(object);
+   refreshVolumes();
+}
+
+void AccumulationVolume::removeObject(SimObjectPtr<SceneObject> object)
+{
+   smAccuObjects.remove(object);
+   refreshVolumes();
+}
+
+void AccumulationVolume::updateObject(SceneObject* object)
+{
+   // This function is called when an individual object
+   // has been moved. Tests to see if it's in any of the
+   // accumulation volumes.
+
+   // We use ZERO instead of NULL so the accumulation
+   // texture will be updated in renderMeshMgr.
+   object->mAccuTex = GFXTexHandle::ZERO;
+
+   for (S32 i = 0; i < smAccuVolumes.size(); ++i)
+   {
+      SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
+      if ( volume.isNull() ) continue;
+
+      if ( volume->containsPoint(object->getPosition()) )
+         object->mAccuTex = volume->mAccuTexture;
+   }
+}

+ 104 - 0
Engine/source/T3D/accumulationVolume.h

@@ -0,0 +1,104 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _ACCUMULATIONVOLUME_H_
+#define _ACCUMULATIONVOLUME_H_
+
+#ifndef _SCENEPOLYHEDRALSPACE_H_
+#include "scene/scenePolyhedralSpace.h"
+#endif
+
+#ifndef _MSILHOUETTEEXTRACTOR_H_
+#include "math/mSilhouetteExtractor.h"
+#endif
+
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+
+/// A volume in space that blocks visibility.
+class AccumulationVolume : public ScenePolyhedralSpace
+{
+   public:
+
+      typedef ScenePolyhedralSpace Parent;
+
+   protected:
+
+      typedef SilhouetteExtractorPerspective< PolyhedronType > SilhouetteExtractorType;
+
+      /// Whether the volume's transform has changed and we need to recompute
+      /// transform-based data.
+      bool mTransformDirty;
+
+      /// World-space points of the volume's polyhedron.
+      Vector< Point3F > mWSPoints;
+
+      /// Silhouette extractor when using perspective projections.
+      SilhouetteExtractorType mSilhouetteExtractor;
+      
+      mutable Vector< SceneObject* > mVolumeQueryList;
+
+      // Name (path) of the accumulation texture.
+      String mTextureName;
+      
+      // SceneSpace.
+      virtual void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat );
+
+   public:
+
+      GFXTexHandle mAccuTexture;
+
+      AccumulationVolume();
+      ~AccumulationVolume();
+
+      // SimObject.
+      DECLARE_CONOBJECT( AccumulationVolume );
+      DECLARE_DESCRIPTION( "Allows objects in an area to have accumulation effect applied." );
+      DECLARE_CATEGORY( "3D Scene" );
+
+      virtual bool onAdd();
+      virtual void onRemove();
+      void inspectPostApply();
+      void setTexture( const String& name );
+
+      // Static Functions.
+      static void consoleInit();
+      static void initPersistFields();
+      static Vector< SimObjectPtr<SceneObject> > smAccuObjects;
+      static Vector< SimObjectPtr<AccumulationVolume> > smAccuVolumes;
+      static void addObject(SimObjectPtr<SceneObject> object);
+      static void removeObject(SimObjectPtr<SceneObject> object);
+      static void refreshVolumes();
+      static bool _setTexture( void *object, const char *index, const char *data );
+      static void updateObject(SceneObject* object);
+
+      // Network
+      U32 packUpdate( NetConnection *, U32 mask, BitStream *stream );
+      void unpackUpdate( NetConnection *, BitStream *stream );
+
+      // SceneObject.
+      virtual void buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F >& outPoints );
+      virtual void setTransform( const MatrixF& mat );
+};
+
+#endif // !_AccumulationVolume_H_

+ 8 - 0
Engine/source/T3D/fx/particleEmitter.cpp

@@ -145,6 +145,7 @@ ParticleEmitterData::ParticleEmitterData()
    blendStyle = ParticleRenderInst::BlendUndefined;
    sortParticles = false;
    renderReflection = true;
+   glow = false;
    reverseOrder = false;
    textureName = 0;
    textureHandle = 0;
@@ -289,6 +290,9 @@ void ParticleEmitterData::initPersistFields()
       addField( "renderReflection", TYPEID< bool >(), Offset(renderReflection, ParticleEmitterData),
          "Controls whether particles are rendered onto reflective surfaces like water." );
 
+      addField("glow", TYPEID< bool >(), Offset(glow, ParticleEmitterData),
+         "If true, the particles are rendered to the glow buffer as well.");
+
       //@}
 
    endGroup( "ParticleEmitterData" );
@@ -356,6 +360,7 @@ void ParticleEmitterData::packData(BitStream* stream)
    }
    stream->writeFlag(highResOnly);
    stream->writeFlag(renderReflection);
+   stream->writeFlag(glow);
    stream->writeInt( blendStyle, 4 );
 }
 
@@ -418,6 +423,7 @@ void ParticleEmitterData::unpackData(BitStream* stream)
    }
    highResOnly = stream->readFlag();
    renderReflection = stream->readFlag();
+   glow = stream->readFlag();
    blendStyle = stream->readInt( 4 );
 }
 
@@ -909,6 +915,8 @@ void ParticleEmitter::prepRenderImage(SceneRenderState* state)
 
    ri->blendStyle = mDataBlock->blendStyle;
 
+   ri->glow = mDataBlock->glow;
+
    // use first particle's texture unless there is an emitter texture to override it
    if (mDataBlock->textureHandle)
      ri->diffuseTex = &*(mDataBlock->textureHandle);

+ 1 - 0
Engine/source/T3D/fx/particleEmitter.h

@@ -114,6 +114,7 @@ class ParticleEmitterData : public GameBaseData
    GFXTexHandle          textureHandle;      ///< Emitter texture handle from txrName
    bool                  highResOnly;        ///< This particle system should not use the mixed-resolution particle rendering
    bool                  renderReflection;   ///< Enables this emitter to render into reflection passes.
+   bool glow;                                ///< Renders this emitter into the glow buffer.
 
    bool reload();
 };

+ 4 - 2
Engine/source/T3D/gameBase/gameBase.cpp

@@ -388,7 +388,9 @@ F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 u
    // Weight by field of view, objects directly in front
    // will be weighted 1, objects behind will be 0
    F32 dot = mDot(pos,camInfo->orientation);
-   bool inFov = dot > camInfo->cosFov;
+
+   bool inFov = dot > camInfo->cosFov * 1.5f;
+
    F32 wFov = inFov? 1.0f: 0;
 
    // Weight by linear velocity parallel to the viewing plane
@@ -406,7 +408,7 @@ F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 u
 
    // Weight by interest.
    F32 wInterest;
-   if (getTypeMask() & PlayerObjectType)
+   if (getTypeMask() & (PlayerObjectType || VehicleObjectType ))
       wInterest = 0.75f;
    else if (getTypeMask() & ProjectileObjectType)
    {

+ 4 - 0
Engine/source/T3D/gameBase/gameBase.h

@@ -35,6 +35,10 @@
 #ifndef _DYNAMIC_CONSOLETYPES_H_
 #include "console/dynamicTypes.h"
 #endif
+#ifndef __SCENEMANAGER_H__  
+#include "scene/sceneManager.h"    
+#define __SCENEMANAGER_H__  
+#endif
 
 class NetConnection;
 class ProcessList;

+ 30 - 0
Engine/source/T3D/gameBase/gameConnection.cpp

@@ -226,6 +226,8 @@ GameConnection::GameConnection()
    mAddYawToAbsRot = false;
    mAddPitchToAbsRot = false;
 
+   mVisibleGhostDistance = 0.0f;
+
    clearDisplayDevice();
 }
 
@@ -240,6 +242,16 @@ GameConnection::~GameConnection()
 
 //----------------------------------------------------------------------------
 
+void GameConnection::setVisibleGhostDistance(F32 dist)
+{
+   mVisibleGhostDistance = dist;
+}
+
+F32 GameConnection::getVisibleGhostDistance()
+{
+   return mVisibleGhostDistance;
+}
+
 bool GameConnection::canRemoteCreate()
 {
    return true;
@@ -2199,3 +2211,21 @@ DefineEngineMethod( GameConnection, getControlSchemeAbsoluteRotation, bool, (),,
 {
    return object->getControlSchemeAbsoluteRotation();
 }
+
+DefineEngineMethod( GameConnection, setVisibleGhostDistance, void, (F32 dist),,
+   "@brief Sets the distance that objects around it will be ghosted. If set to 0, "
+   "it may be defined by the LevelInfo.\n\n"
+   "@dist - is the max distance\n\n"
+   )
+{
+   object->setVisibleGhostDistance(dist);
+}
+
+DefineEngineMethod( GameConnection, getVisibleGhostDistance, F32, (),,
+   "@brief Gets the distance that objects around the connection will be ghosted.\n\n"
+   
+   "@return S32 of distance.\n\n"
+   )
+{
+   return object->getVisibleGhostDistance();
+}

+ 5 - 0
Engine/source/T3D/gameBase/gameConnection.h

@@ -72,6 +72,8 @@ private:
 
    U32  mMissionCRC;             // crc of the current mission file from the server
 
+   F32 mVisibleGhostDistance;
+
 private:
    U32 mLastControlRequestTime;
    S32 mDataBlockModifiedKey;
@@ -155,6 +157,9 @@ public:
 
    bool canRemoteCreate();
 
+   void setVisibleGhostDistance(F32 dist);
+   F32 getVisibleGhostDistance();
+
 private:
    /// @name Connection State
    /// This data is set with setConnectArgs() and setJoinPassword(), and

+ 6 - 1
Engine/source/T3D/levelInfo.cpp

@@ -35,6 +35,8 @@
 #include "console/engineAPI.h"
 #include "math/mathIO.h"
 
+#include "torqueConfig.h"
+
 
 IMPLEMENT_CO_NETOBJECT_V1(LevelInfo);
 
@@ -77,6 +79,7 @@ static SFXAmbience sDefaultAmbience;
 LevelInfo::LevelInfo()
    :  mNearClip( 0.1f ),
       mVisibleDistance( 1000.0f ),
+      mVisibleGhostDistance ( 0 ),
       mDecalBias( 0.0015f ),
       mCanvasClearColor( 255, 0, 255, 255 ),
       mSoundAmbience( NULL ),
@@ -113,7 +116,8 @@ void LevelInfo::initPersistFields()
    addGroup( "Visibility" );
 
       addField( "nearClip", TypeF32, Offset( mNearClip, LevelInfo ), "Closest distance from the camera's position to render the world." );
-      addField( "visibleDistance", TypeF32, Offset( mVisibleDistance, LevelInfo ), "Furthest distance fromt he camera's position to render the world." );
+      addField( "visibleDistance", TypeF32, Offset( mVisibleDistance, LevelInfo ), "Furthest distance from the camera's position to render the world." );
+      addField( "visibleGhostDistance", TypeF32, Offset( mVisibleGhostDistance, LevelInfo ), "Furthest distance from the camera's position to render players. Defaults to visibleDistance." );
       addField( "decalBias", TypeF32, Offset( mDecalBias, LevelInfo ),
          "NearPlane bias used when rendering Decal and DecalRoad. This should be tuned to the visibleDistance in your level." );
 
@@ -300,6 +304,7 @@ void LevelInfo::_updateSceneGraph()
    
    scene->setNearClip( mNearClip );
    scene->setVisibleDistance( mVisibleDistance );
+   scene->setVisibleGhostDistance( mVisibleGhostDistance );
 
    gDecalBias = mDecalBias;
 

+ 2 - 1
Engine/source/T3D/levelInfo.h

@@ -36,7 +36,6 @@
    #include "sfx/sfxCommon.h"
 #endif
 
-
 class SFXAmbience;
 class SFXSoundscape;
 
@@ -55,6 +54,8 @@ class LevelInfo : public NetObject
 
       F32 mVisibleDistance;
 
+      F32 mVisibleGhostDistance;
+
       F32 mDecalBias;
 
       ColorI mCanvasClearColor;

+ 29 - 4
Engine/source/T3D/tsStatic.cpp

@@ -48,6 +48,7 @@
 #include "materials/materialFeatureData.h"
 #include "materials/materialFeatureTypes.h"
 #include "console/engineAPI.h"
+#include "T3D/accumulationVolume.h"
 
 using namespace Torque;
 
@@ -198,10 +199,10 @@ void TSStatic::initPersistFields()
    endGroup("Collision");
 
    addGroup( "AlphaFade" );  
-      addField( "Alpha Fade Enable",   TypeBool,   Offset(mUseAlphaFade,    TSStatic), "Turn on/off Alpha Fade" );  
-      addField( "Alpha Fade Start",    TypeF32,    Offset(mAlphaFadeStart,  TSStatic), "Distance of start Alpha Fade" );  
-      addField( "Alpha Fade End",      TypeF32,    Offset(mAlphaFadeEnd,    TSStatic), "Distance of end Alpha Fade" );  
-      addField( "Alpha Fade Inverse", TypeBool,    Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance" );  
+      addField( "alphaFadeEnable",   TypeBool,   Offset(mUseAlphaFade,    TSStatic), "Turn on/off Alpha Fade" );  
+      addField( "alphaFadeStart",    TypeF32,    Offset(mAlphaFadeStart,  TSStatic), "Distance of start Alpha Fade" );  
+      addField( "alphaFadeEnd",      TypeF32,    Offset(mAlphaFadeEnd,    TSStatic), "Distance of end Alpha Fade" );  
+      addField( "alphaFadeInverse", TypeBool,    Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance" );  
    endGroup( "AlphaFade" );
 
    addGroup("Debug");
@@ -293,6 +294,13 @@ bool TSStatic::onAdd()
 
    _updateShouldTick();
 
+   // Accumulation
+   if ( isClientObject() && mShapeInstance )
+   {
+      if ( mShapeInstance->hasAccumulation() ) 
+         AccumulationVolume::addObject(this);
+   }
+
    return true;
 }
 
@@ -403,6 +411,13 @@ void TSStatic::onRemove()
 {
    SAFE_DELETE( mPhysicsRep );
 
+   // Accumulation
+   if ( isClientObject() && mShapeInstance )
+   {
+      if ( mShapeInstance->hasAccumulation() ) 
+         AccumulationVolume::removeObject(this);
+   }
+
    mConvexList->nukeList();
 
    removeFromScene();
@@ -562,6 +577,9 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
    rdata.setFadeOverride( 1.0f );
    rdata.setOriginSort( mUseOriginSort );
 
+   // Acculumation
+   rdata.setAccuTex(mAccuTex);
+
    // If we have submesh culling enabled then prepare
    // the object space frustum to pass to the shape.
    Frustum culler;
@@ -649,6 +667,13 @@ void TSStatic::setTransform(const MatrixF & mat)
    if ( mPhysicsRep )
       mPhysicsRep->setTransform( mat );
 
+   // Accumulation
+   if ( isClientObject() && mShapeInstance )
+   {
+      if ( mShapeInstance->hasAccumulation() ) 
+         AccumulationVolume::updateObject(this);
+   }
+
    // Since this is a static it's render transform changes 1
    // to 1 with it's collision transform... no interpolation.
    setRenderTransform(mat);

+ 10 - 10
Engine/source/app/net/serverQuery.cpp

@@ -207,10 +207,6 @@ struct ServerFilter
       Favorites   = 3,
    };
 
-   Type  type;
-   char* gameType;
-   char* missionType;
-
    enum // Query Flags
    {
       OnlineQuery       = 0,        // Authenticated with master
@@ -226,17 +222,21 @@ struct ServerFilter
       CurrentVersion    = BIT(7),
       NotXenon          = BIT(6)
    };
-
+   
+   //Rearranging the fields according to their sizes
+   char* gameType;
+   char* missionType;
    U8    queryFlags;
    U8    minPlayers;
    U8    maxPlayers;
    U8    maxBots;
-   U32   regionMask;
-   U32   maxPing;
    U8    filterFlags;
-   U16   minCPU;
    U8    buddyCount;
+   U16   minCPU;
+   U32   regionMask;
+   U32   maxPing;
    U32*  buddyList;
+   Type  type;
 
    ServerFilter()
    {
@@ -432,7 +432,7 @@ DefineConsoleFunction( queryAllServers
       maxBots,regionMask,maxPing,minCPU,filterFlags,0,&buddyList);
 
    queryLanServers(lanPort, flags, gameType, missionType, minPlayers, maxPlayers, maxBots,
-	   regionMask, maxPing, minCPU, filterFlags);
+      regionMask, maxPing, minCPU, filterFlags);
    dFree(gameType);
    dFree(missionType);
 
@@ -456,7 +456,7 @@ DefineConsoleFunction( queryLanServers
 
    clearServerList();
    queryLanServers(lanPort, flags, gameType, missionType, minPlayers, maxPlayers, maxBots,
-	   regionMask, maxPing, minCPU, filterFlags);
+      regionMask, maxPing, minCPU, filterFlags);
 
 }
 

+ 23 - 17
Engine/source/console/compiledEval.cpp

@@ -470,11 +470,11 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
             dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
                "%s(", thisFunctionName);
          }
-         for (i = 0; i < wantedArgc; i++)
+         for(i = 0; i < wantedArgc; i++)
          {
-             dStrcat(traceBuffer, argv[i + 1]);
-             if (i != wantedArgc - 1)
-                 dStrcat(traceBuffer, ", ");
+            dStrcat(traceBuffer, argv[i+1]);
+            if(i != wantedArgc - 1)
+               dStrcat(traceBuffer, ", ");
          }
          dStrcat(traceBuffer, ")");
          Con::printf("%s", traceBuffer);
@@ -533,9 +533,16 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
       }
    }
 
-   // Reset the console stack frame which at this point will contain 
-   // either nothing or argv[] which we just copied
-   CSTK.resetFrame();
+   bool doResetValueStack = !gEvalState.mResetLocked;
+   gEvalState.mResetLocked = true;
+   
+   if (gEvalState.mShouldReset)
+   {
+      // Ensure all stacks are clean in case anything became unbalanced during the previous execution
+      STR.clearFrames();
+      CSTK.clearFrames();
+      gEvalState.mShouldReset = false;
+   }
 
    // Grab the state of the telenet debugger here once
    // so that the push and pop frames are always balanced.
@@ -1817,7 +1824,7 @@ breakContinue:
                ConsoleValueRef ret;
                if(nsEntry->mFunctionOffset)
                   ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
- 
+
                STR.popFrame();
                // Functions are assumed to return strings, so look ahead to see if we can skip the conversion
                if(code[ip] == OP_STR_TO_UINT)
@@ -1837,7 +1844,7 @@ breakContinue:
                }
                else
                   STR.setStringValue((const char*)ret);
-               
+
                // This will clear everything including returnValue
                CSTK.popFrame();
                STR.clearFunctionOffset();
@@ -2219,15 +2226,7 @@ execFinished:
          Con::printf("%s", traceBuffer);
       }
    }
-   else
-   {
-      delete[] globalStrings;
-      globalStringsMaxLen = 0;
 
-      delete[] globalFloats;
-      globalStrings = NULL;
-      globalFloats = NULL;
-   }
    smCurrentCodeBlock = saveCodeBlock;
    if(saveCodeBlock && saveCodeBlock->name)
    {
@@ -2235,6 +2234,13 @@ execFinished:
       Con::gCurrentRoot = saveCodeBlock->modPath;
    }
 
+   // Mark the reset flag for the next run if we've finished execution
+   if (doResetValueStack)
+   {
+      gEvalState.mShouldReset = true;
+      gEvalState.mResetLocked = false;
+   }
+
    decRefCount();
 
 #ifdef TORQUE_DEBUG

+ 2 - 0
Engine/source/console/consoleInternal.cpp

@@ -796,6 +796,8 @@ ExprEvalState::ExprEvalState()
    currentVariable = NULL;
    mStackDepth = 0;
    stack.reserve( 64 );
+   mShouldReset = false;
+   mResetLocked = false;
 }
 
 ExprEvalState::~ExprEvalState()

+ 2 - 0
Engine/source/console/consoleInternal.h

@@ -468,6 +468,8 @@ public:
    bool traceOn;
 
    U32 mStackDepth;
+   bool mShouldReset; ///< Designates if the value stack should be reset
+   bool mResetLocked; ///< mShouldReset will be set at the end
 
    ExprEvalState();
    ~ExprEvalState();

+ 73 - 19
Engine/source/console/simDictionary.cpp

@@ -29,19 +29,23 @@ extern U32 HashPointer(StringTableEntry e);
 
 SimNameDictionary::SimNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    hashTable = NULL;
+#endif
    mutex = Mutex::createMutex();
 }
 
 SimNameDictionary::~SimNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    delete[] hashTable;
+#endif
    Mutex::destroyMutex(mutex);
 }
 
 void SimNameDictionary::insert(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    SimObject* checkForDup = find(obj->objectName);
@@ -50,7 +54,7 @@ void SimNameDictionary::insert(SimObject* obj)
       Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName);
 
    Mutex::lockMutex(mutex);
-   
+#ifndef USE_NEW_SIMDICTIONARY
    if(!hashTable)
    {
       hashTable = new SimObject *[DefaultTableSize];
@@ -95,12 +99,15 @@ void SimNameDictionary::insert(SimObject* obj)
       hashTable = newHashTable;
       hashTableSize = newHashTableSize;
    }
-   
+#else
+   root[obj->objectName] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
 SimObject* SimNameDictionary::find(StringTableEntry name)
 {
+#ifndef USE_NEW_SIMDICTIONARY
    // NULL is a valid lookup - it will always return NULL
    if(!hashTable)
       return NULL;
@@ -121,15 +128,22 @@ SimObject* SimNameDictionary::find(StringTableEntry name)
 
    Mutex::unlockMutex(mutex);
    return NULL;
+#else
+  Mutex::lockMutex(mutex);
+  StringDictDef::iterator it = root.find(name);
+  SimObject* f = (it == root.end() ? NULL : it->second);
+  Mutex::unlockMutex(mutex);
+  return f;
+#endif
 }
 
 void SimNameDictionary::remove(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
    while(*walk)
    {
@@ -144,7 +158,11 @@ void SimNameDictionary::remove(SimObject* obj)
       }
       walk = &((*walk)->nextNameObject);
    }
-
+#else
+   const char* name = obj->objectName;
+   if (root.find(name) != root.end())
+      root.erase(name);
+#endif
    Mutex::unlockMutex(mutex);
 }	
 
@@ -152,28 +170,31 @@ void SimNameDictionary::remove(SimObject* obj)
 
 SimManagerNameDictionary::SimManagerNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    hashTable = new SimObject *[DefaultTableSize];
    hashTableSize = DefaultTableSize;
    hashEntryCount = 0;
    
    dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
-
+#endif
    mutex = Mutex::createMutex();
 }
 
 SimManagerNameDictionary::~SimManagerNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    delete[] hashTable;
+#endif
    Mutex::destroyMutex(mutex);
 }
 
 void SimManagerNameDictionary::insert(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = HashPointer(obj->objectName) % hashTableSize;
    obj->nextManagerNameObject = hashTable[idx];
    hashTable[idx] = obj;
@@ -209,7 +230,9 @@ void SimManagerNameDictionary::insert(SimObject* obj)
       hashTable = newHashTable;
       hashTableSize = newHashTableSize;
    }
-   
+#else
+   root[obj->objectName] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
@@ -219,6 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
 
    Mutex::lockMutex(mutex);
 
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = HashPointer(name) % hashTableSize;
    SimObject *walk = hashTable[idx];
    while(walk)
@@ -230,16 +254,23 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
       }
       walk = walk->nextManagerNameObject;
    }
-
    Mutex::unlockMutex(mutex);
+
    return NULL;
+#else
+   StringDictDef::iterator it = root.find(name);
+   SimObject* f = (it == root.end() ? NULL : it->second);
+   Mutex::unlockMutex(mutex);
+   return f;
+#endif
 }
 
 void SimManagerNameDictionary::remove(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
+#ifndef USE_NEW_SIMDICTIONARY
    Mutex::lockMutex(mutex);
 
    SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
@@ -256,7 +287,11 @@ void SimManagerNameDictionary::remove(SimObject* obj)
       }
       walk = &((*walk)->nextManagerNameObject);
    }
-
+#else
+   StringTableEntry name = obj->objectName;
+   if (root.find(name) != root.end())
+      root.erase(name);
+#endif
    Mutex::unlockMutex(mutex);
 }	
 
@@ -265,7 +300,9 @@ void SimManagerNameDictionary::remove(SimObject* obj)
 
 SimIdDictionary::SimIdDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
+#endif
    mutex = Mutex::createMutex();
 }
 
@@ -274,22 +311,29 @@ SimIdDictionary::~SimIdDictionary()
    Mutex::destroyMutex(mutex);
 }
 
+
+
 void SimIdDictionary::insert(SimObject* obj)
 {
-   Mutex::lockMutex(mutex);
+   if (!obj)
+      return;
 
+   Mutex::lockMutex(mutex);
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = obj->getId() & TableBitMask;
    obj->nextIdObject = table[idx];
    AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
    table[idx] = obj;
-
+#else
+   root[obj->getId()] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
 SimObject* SimIdDictionary::find(S32 id)
 {
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = id & TableBitMask;
    SimObject *walk = table[idx];
    while(walk)
@@ -301,22 +345,32 @@ SimObject* SimIdDictionary::find(S32 id)
       }
       walk = walk->nextIdObject;
    }
-
    Mutex::unlockMutex(mutex);
 
    return NULL;
+#else
+   SimObjectIdDictDef::iterator it = root.find(id);
+   SimObject* f = (it == root.end() ? NULL : it->second);
+   Mutex::unlockMutex(mutex);
+   return f;
+#endif
 }
 
 void SimIdDictionary::remove(SimObject* obj)
 {
-   Mutex::lockMutex(mutex);
+   if (!obj)
+      return;
 
+   Mutex::lockMutex(mutex);
+#ifndef USE_NEW_SIMDICTIONARY
    SimObject **walk = &table[obj->getId() & TableBitMask];
    while(*walk && *walk != obj)
       walk = &((*walk)->nextIdObject);
    if(*walk)
       *walk = obj->nextIdObject;
-
+#else
+   root.erase(obj->getId());
+#endif
    Mutex::unlockMutex(mutex);
 }
 

+ 42 - 0
Engine/source/console/simDictionary.h

@@ -33,8 +33,38 @@
 #include "platform/threads/mutex.h"
 #endif
 
+#include "torqueConfig.h"
+
 class SimObject;
 
+#ifdef USE_NEW_SIMDICTIONARY
+#include <string>
+#include <unordered_map>
+
+#ifndef _SIM_H_
+#include "console/sim.h"
+#endif
+
+struct StringTableEntryHash
+{
+   inline size_t operator()(StringTableEntry val) const
+   {
+      return (size_t)val;
+   }
+};
+
+struct StringTableEntryEq
+{
+   inline bool operator()(StringTableEntry s1, StringTableEntry s2) const
+   {
+      return s1 == s2;
+   }
+};
+
+typedef std::unordered_map<StringTableEntry, SimObject*, StringTableEntryHash, StringTableEntryEq> StringDictDef;	
+typedef std::unordered_map<SimObjectId, SimObject*> SimObjectIdDictDef;
+#endif
+
 //----------------------------------------------------------------------------
 /// Map of names to SimObjects
 ///
@@ -42,6 +72,7 @@ class SimObject;
 /// for fast removal of an object given object*
 class SimNameDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 29
@@ -50,6 +81,9 @@ class SimNameDictionary
    SimObject **hashTable;  // hash the pointers of the names...
    S32 hashTableSize;
    S32 hashEntryCount;
+#else
+   StringDictDef root;
+#endif
 
    void *mutex;
 
@@ -64,6 +98,7 @@ public:
 
 class SimManagerNameDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 29
@@ -72,6 +107,9 @@ class SimManagerNameDictionary
    SimObject **hashTable;  // hash the pointers of the names...
    S32 hashTableSize;
    S32 hashEntryCount;
+#else
+   StringDictDef root;
+#endif
 
    void *mutex;
 
@@ -91,12 +129,16 @@ public:
 /// for fast removal of an object given object*
 class SimIdDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 4096,
       TableBitMask = 4095
    };
    SimObject *table[DefaultTableSize];
+#else
+   SimObjectIdDictDef root;
+#endif
 
    void *mutex;
 

+ 7 - 1
Engine/source/console/stringStack.cpp

@@ -162,7 +162,7 @@ ConsoleValue* ConsoleValueStack::pop()
 
 void ConsoleValueStack::pushFrame()
 {
-   //Con::printf("CSTK pushFrame");
+   //Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos);
    mStackFrames[mFrame++] = mStackPos;
 }
 
@@ -181,6 +181,12 @@ void ConsoleValueStack::resetFrame()
    //Con::printf("CSTK resetFrame to %i", mStackPos);
 }
 
+void ConsoleValueStack::clearFrames()
+{
+   mStackPos = 0;
+   mFrame = 0;
+}
+
 void ConsoleValueStack::popFrame()
 {
    //Con::printf("CSTK popFrame");

+ 18 - 1
Engine/source/console/stringStack.h

@@ -74,6 +74,7 @@ struct StringStack
          mBuffer = (char *) dRealloc(mBuffer, mBufferSize);
       }
    }
+
    void validateArgBufferSize(U32 size)
    {
       if(size > mArgBufferSize)
@@ -82,6 +83,7 @@ struct StringStack
          mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize);
       }
    }
+
    StringStack()
    {
       mBufferSize = 0;
@@ -95,6 +97,8 @@ struct StringStack
       mFunctionOffset = 0;
       validateBufferSize(8192);
       validateArgBufferSize(2048);
+      dMemset(mBuffer, '\0', mBufferSize);
+      dMemset(mArgBuffer, '\0', mArgBufferSize);
    }
    ~StringStack()
    {
@@ -141,6 +145,7 @@ struct StringStack
    /// Clear the function offset.
    void clearFunctionOffset()
    {
+      //Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset);
       mFunctionOffset = 0;
    }
 
@@ -262,9 +267,9 @@ struct StringStack
       return ret;
    }
 
-   
    void pushFrame()
    {
+      //Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
       mFrameOffsets[mNumFrames++] = mStartStackSize;
       mStartOffsets[mStartStackSize++] = mStart;
       mStart += ReturnBufferSpace;
@@ -273,11 +278,22 @@ struct StringStack
 
    void popFrame()
    {
+      //Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
       mStartStackSize = mFrameOffsets[--mNumFrames];
       mStart = mStartOffsets[mStartStackSize];
       mLen = 0;
    }
 
+   void clearFrames()
+   {
+      //Con::printf("StringStack clearFrames");
+      mNumFrames = 0;
+      mStart = 0;
+      mLen = 0;
+      mStartStackSize = 0;
+      mFunctionOffset = 0;
+   }
+
    /// Get the arguments for a function call from the stack.
    void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
 };
@@ -309,6 +325,7 @@ public:
    void popFrame();
 
    void resetFrame();
+   void clearFrames();
 
    void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);
 

+ 1 - 1
Engine/source/core/ogg/oggVorbisDecoder.cpp

@@ -174,7 +174,7 @@ U32 OggVorbisDecoder::read( RawData** buffer, U32 num )
             S32 val = S32( pcmData[ c ][ n ] * 32767.f );
             if( val > 32767 )
                val = 32767;
-            else if( val < -34768 )
+            else if( val < -32768 )
                val = -32768;
                
             *samplePtr = val;

+ 4 - 0
Engine/source/environment/waterObject.cpp

@@ -891,6 +891,10 @@ void WaterObject::onRemove()
    {
       mPlaneReflector.unregisterReflector();
       cleanupMaterials();
+
+      PostEffect *underWaterEffect = getUnderwaterEffect( );
+      if( underWaterEffect )
+         underWaterEffect->disable( );
    }
 
    Parent::onRemove();

+ 9 - 9
Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h

@@ -143,7 +143,7 @@ public:
    {
       glGenBuffers(1, &mBufferName);
 
-      PRESERVE_VERTEX_BUFFER();
+      PRESERVE_BUFFER( mBinding );
       glBindBuffer(mBinding, mBufferName);
      
       const U32 cSizeInMB = 10;
@@ -195,11 +195,11 @@ public:
       }
       else if( GFXGL->glUseMap() )
       {
-         PRESERVE_VERTEX_BUFFER();
-         glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
+         PRESERVE_BUFFER( mBinding );
+         glBindBuffer(mBinding, mBufferName);
 
          const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
-         outPtr = glMapBufferRange(GL_ARRAY_BUFFER, outOffset, size, access);
+         outPtr = glMapBufferRange(mBinding, outOffset, size, access);
       }
       else
       {
@@ -224,15 +224,15 @@ public:
       }
       else if( GFXGL->glUseMap() )
       {
-         PRESERVE_VERTEX_BUFFER();
-         glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
+         PRESERVE_BUFFER( mBinding );
+         glBindBuffer(mBinding, mBufferName);
 
-         glUnmapBuffer(GL_ARRAY_BUFFER);
+         glUnmapBuffer(mBinding);
       }
       else
       {
-         PRESERVE_VERTEX_BUFFER();
-         glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
+         PRESERVE_BUFFER( mBinding );
+         glBindBuffer(mBinding, mBufferName);
 
          glBufferSubData( mBinding, _getBufferData.mOffset, _getBufferData.mSize, mFrameAllocator.getlockedPtr() );
 

+ 7 - 0
Engine/source/gfx/gl/gfxGLUtils.h

@@ -182,6 +182,13 @@ GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ARRAY_BUFFER, GL_ARR
 #define PRESERVE_INDEX_BUFFER() \
 GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ELEMENT_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindBuffer)
 
+#define _GET_BUFFER_BINDING( BINDING ) \
+BINDING == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING : ( BINDING == GL_ELEMENT_ARRAY_BUFFER ?  GL_ELEMENT_ARRAY_BUFFER_BINDING : 0 )
+
+/// Helper macro to preserve the current element array binding.
+#define PRESERVE_BUFFER( BINDING ) \
+GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (BINDING, _GET_BUFFER_BINDING(BINDING), (GFXGLPreserveInteger::BindFn)glBindBuffer)
+
 /// ASSERT: Never call glActiveTexture for a "bind to modify" or in a PRESERVER_TEXTURE MACRO scope.
 
 /// Helper macro to preserve the current 1D texture binding.

+ 74 - 1
Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp

@@ -330,6 +330,58 @@ void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
       output = meta;
       return;
    }
+
+   else if (fd.features[MFT_AccuMap])
+   {
+      Var *bumpSample = (Var *)LangElement::find("bumpSample");
+      if (bumpSample == NULL)
+      {
+         MultiLine *meta = new MultiLine;
+
+         Var *texCoord = getInTexCoord("texCoord", "vec2", true, componentList);
+
+         Var *bumpMap = getNormalMapTex();
+
+         bumpSample = new Var;
+         bumpSample->setType("vec4");
+         bumpSample->setName("bumpSample");
+         LangElement *bumpSampleDecl = new DecOp(bumpSample);
+
+         meta->addStatement(new GenOp("   @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord));
+
+         if (fd.features.hasFeature(MFT_DetailNormalMap))
+         {
+            Var *bumpMap = (Var*)LangElement::find("detailBumpMap");
+            if (!bumpMap) {
+               bumpMap = new Var;
+               bumpMap->setType("sampler2D");
+               bumpMap->setName("detailBumpMap");
+               bumpMap->uniform = true;
+               bumpMap->sampler = true;
+               bumpMap->constNum = Var::getTexUnitNum();
+            }
+
+            texCoord = getInTexCoord("detCoord", "vec2", true, componentList);
+            LangElement *texOp = new GenOp("tex2D(@, @)", bumpMap, texCoord);
+
+            Var *detailBump = new Var;
+            detailBump->setName("detailBump");
+            detailBump->setType("vec4");
+            meta->addStatement(expandNormalMap(texOp, new DecOp(detailBump), detailBump, fd));
+
+            Var *detailBumpScale = new Var;
+            detailBumpScale->setType("float");
+            detailBumpScale->setName("detailBumpStrength");
+            detailBumpScale->uniform = true;
+            detailBumpScale->constSortPos = cspPass;
+            meta->addStatement(new GenOp("   @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale));
+         }
+
+         output = meta;
+
+         return;
+      }
+   }
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
                fd.features[MFT_ForwardShading] || 
                !fd.features[MFT_RTLighting] )
@@ -398,7 +450,20 @@ void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
       return;
    }
 
-   if (  !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
+   if (!fd.features[MFT_PrePassConditioner] && fd.features[MFT_AccuMap])
+   {
+      passData.mTexType[texIndex] = Material::Bump;
+      passData.mSamplerNames[texIndex] = "bumpMap";
+      passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_NormalMap);
+
+      if (fd.features.hasFeature(MFT_DetailNormalMap))
+      {
+         passData.mTexType[texIndex] = Material::DetailBump;
+         passData.mSamplerNames[texIndex] = "detailBumpMap";
+         passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_DetailNormalMap);
+      }
+   }
+   else if (!fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
          ( fd.features[MFT_PrePassConditioner] ||
            fd.features[MFT_PixSpecular] ) )
    {
@@ -481,6 +546,14 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
    AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
       "DeferredPixelSpecularGLSL::processPix - Something hosed the deferred features!" );
 
+   if (fd.features[MFT_AccuMap]) {
+      // change specularity where the accu texture is applied
+      Var *accuPlc = (Var*)LangElement::find("plc");
+      Var *accuSpecular = (Var*)LangElement::find("accuSpecular");
+      if (accuPlc != NULL && accuSpecular != NULL)
+         //d_specular = clamp(lerp( d_specular, accuSpecular * d_specular, plc.a), 0, 1)
+         meta->addStatement(new GenOp("   @ = clamp( lerp( @, @ * @, @.a), 0, 1);\r\n", d_specular, d_specular, accuSpecular, d_specular, accuPlc));
+   }
    // (a^m)^n = a^(m*n)
    meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
       specDecl, d_specular, specPow, specStrength ) );

+ 74 - 1
Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp

@@ -330,6 +330,57 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
       output = meta;
       return;
    }
+   else if (fd.features[MFT_AccuMap]) 
+   {
+      Var *bumpSample = (Var *)LangElement::find( "bumpSample" );
+      if( bumpSample == NULL )
+      {
+         MultiLine *meta = new MultiLine;
+
+         Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
+
+         Var *bumpMap = getNormalMapTex();
+
+         bumpSample = new Var;
+         bumpSample->setType( "float4" );
+         bumpSample->setName( "bumpSample" );
+         LangElement *bumpSampleDecl = new DecOp( bumpSample );
+
+         meta->addStatement( new GenOp( "   @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord ) );
+
+         if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
+         {
+            Var *bumpMap = (Var*)LangElement::find( "detailBumpMap" );
+            if ( !bumpMap ) {
+               bumpMap = new Var;
+               bumpMap->setType( "sampler2D" );
+               bumpMap->setName( "detailBumpMap" );
+               bumpMap->uniform = true;
+               bumpMap->sampler = true;
+               bumpMap->constNum = Var::getTexUnitNum();
+            }
+
+            texCoord = getInTexCoord( "detCoord", "float2", true, componentList );
+            LangElement *texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
+
+            Var *detailBump = new Var;
+            detailBump->setName( "detailBump" );
+            detailBump->setType( "float4" );
+            meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
+
+            Var *detailBumpScale = new Var;
+            detailBumpScale->setType( "float" );
+            detailBumpScale->setName( "detailBumpStrength" );
+            detailBumpScale->uniform = true;
+            detailBumpScale->constSortPos = cspPass;
+            meta->addStatement( new GenOp( "   @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale ) );
+         }
+
+         output = meta;
+
+         return;
+      }
+   } 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
                fd.features[MFT_ForwardShading] || 
                !fd.features[MFT_RTLighting] )
@@ -398,7 +449,20 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
       return;
    }
 
-   if (  !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
+   if (  !fd.features[MFT_PrePassConditioner] && fd.features[MFT_AccuMap] )
+   {
+      passData.mTexType[ texIndex ] = Material::Bump;
+      passData.mSamplerNames[ texIndex ] = "bumpMap";
+      passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
+
+      if (  fd.features.hasFeature( MFT_DetailNormalMap ) )
+      {
+         passData.mTexType[ texIndex ] = Material::DetailBump;
+         passData.mSamplerNames[texIndex] = "detailBumpMap";
+         passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
+      }
+   }
+   else if (  !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
          ( fd.features[MFT_PrePassConditioner] ||
            fd.features[MFT_PixSpecular] ) )
    {
@@ -481,6 +545,15 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
    AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
       "DeferredPixelSpecularHLSL::processPix - Something hosed the deferred features!" );
 
+   if (fd.features[ MFT_AccuMap ]) {
+      // change specularity where the accu texture is applied
+      Var *accuPlc = (Var*) LangElement::find( "plc" );
+      Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
+      if(accuPlc != NULL && accuSpecular != NULL)
+         //d_specular = clamp(lerp( d_specular, accuSpecular * d_specular, plc.a), 0, 1)
+         meta->addStatement( new GenOp( "   @ = clamp( lerp( @, @ * @, @.a), 0, 1);\r\n", d_specular, d_specular, accuSpecular, d_specular, accuPlc ) );
+   }
+	  
    // (a^m)^n = a^(m*n)
    meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
       specDecl, d_specular, specPow, specStrength ) );

+ 1 - 0
Engine/source/materials/baseMatInstance.h

@@ -185,6 +185,7 @@ public:
 
    // BTRTODO: This stuff below should probably not be in BaseMatInstance
    virtual bool hasGlow() = 0;
+   virtual bool hasAccumulation() = 0;
    
    virtual U32 getCurPass() = 0;
 

+ 8 - 0
Engine/source/materials/matInstance.cpp

@@ -497,6 +497,14 @@ bool MatInstance::hasGlow()
       return false;
 }
 
+bool MatInstance::hasAccumulation() 
+{ 
+   if( mProcessedMaterial )
+      return mProcessedMaterial->hasAccumulation(); 
+   else
+      return false;
+}
+
 const FeatureSet& MatInstance::getFeatures() const 
 {
    return mProcessedMaterial->getFeatures(); 

+ 1 - 0
Engine/source/materials/matInstance.h

@@ -75,6 +75,7 @@ public:
    virtual SimObject* getUserObject() const { return mUserObject; }
    virtual Material *getMaterial() { return mMaterial; }
    virtual bool hasGlow();
+   virtual bool hasAccumulation();
    virtual U32 getCurPass() { return getMax( mCurPass, 0 ); }
    virtual U32 getCurStageNum();
    virtual RenderPassData *getPass(U32 pass);   

+ 40 - 0
Engine/source/materials/materialDefinition.cpp

@@ -35,6 +35,7 @@
 #include "sfx/sfxTrack.h"
 #include "sfx/sfxTypes.h"
 #include "core/util/safeDelete.h"
+#include "T3D/accumulationVolume.h"
 
 
 IMPLEMENT_CONOBJECT( Material );
@@ -120,6 +121,13 @@ Material::Material()
       mSpecularStrength[i] = 1.0f;
       mPixelSpecular[i] = false;
 
+      mAccuEnabled[i]   = false;
+      mAccuScale[i]     = 1.0f;
+      mAccuDirection[i] = 1.0f;
+      mAccuStrength[i]  = 0.6f;
+      mAccuCoverage[i]  = 0.9f;
+      mAccuSpecular[i]  = 16.0f;
+	  
       mParallaxScale[i] = 0.0f;
 
       mVertLit[i] = false;
@@ -251,6 +259,24 @@ void Material::initPersistFields()
          "normal map texture.  Note that if pixel specular is enabled the DXTnm format will not "
          "work with your normal map, unless you are also using a specular map." );
 
+      addProtectedField( "accuEnabled", TYPEID< bool >(), Offset( mAccuEnabled, Material ),
+            &_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture." );
+
+      addField("accuScale",      TypeF32, Offset(mAccuScale, Material), MAX_STAGES,
+         "The scale that is applied to the accu map texture. You can use this to fit the texture to smaller or larger objects.");
+		 
+      addField("accuDirection",  TypeF32, Offset(mAccuDirection, Material), MAX_STAGES,
+         "The direction of the accumulation. Chose whether you want the accu map to go from top to bottom (ie. snow) or upwards (ie. mold).");
+		 
+      addField("accuStrength",   TypeF32, Offset(mAccuStrength, Material), MAX_STAGES,
+         "The strength of the accu map. This changes the transparency of the accu map texture. Make it subtle or add more contrast.");
+		 
+      addField("accuCoverage",   TypeF32, Offset(mAccuCoverage, Material), MAX_STAGES,
+         "The coverage ratio of the accu map texture. Use this to make the entire shape pick up some of the accu map texture or none at all.");
+		 
+      addField("accuSpecular",   TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
+         "Changes specularity to this value where the accumulated material is present.");
+
       addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
          "The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
          "If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
@@ -670,4 +696,18 @@ DefineConsoleMethod( Material, setAutoGenerated, void, (bool isAutoGenerated), ,
               "setAutoGenerated(bool isAutoGenerated): Set whether or not the Material is autogenerated." )
 {
    object->setAutoGenerated(isAutoGenerated);
+}
+
+// Accumulation
+bool Material::_setAccuEnabled( void *object, const char *index, const char *data )
+{
+   Material* mat = reinterpret_cast< Material* >( object );
+
+   if ( index )
+   {
+      U32 i = dAtoui(index);
+      mat->mAccuEnabled[i] = dAtob(data);
+      AccumulationVolume::refreshVolumes();
+   }
+   return true;
 }

+ 10 - 0
Engine/source/materials/materialDefinition.h

@@ -88,6 +88,7 @@ public:
       DynamicLightMask,
       NormalizeCube,
       TexTarget,
+      AccuMap,
    };
 
    enum BlendOp
@@ -198,6 +199,12 @@ public:
    // Data
    //-----------------------------------------------------------------------
    FileName mDiffuseMapFilename[MAX_STAGES];
+   bool     mAccuEnabled[MAX_STAGES];
+   F32      mAccuScale[MAX_STAGES];
+   F32      mAccuDirection[MAX_STAGES];
+   F32      mAccuStrength[MAX_STAGES];
+   F32      mAccuCoverage[MAX_STAGES];
+   F32      mAccuSpecular[MAX_STAGES];
    FileName mOverlayMapFilename[MAX_STAGES];
    FileName mLightMapFilename[MAX_STAGES];
    FileName mToneMapFilename[MAX_STAGES];
@@ -371,6 +378,9 @@ public:
    //
    static void initPersistFields();
 
+   // Accumulation
+   static bool _setAccuEnabled( void *object, const char *index, const char *data );
+
    DECLARE_CONOBJECT(Material);
 protected:
 

+ 8 - 0
Engine/source/materials/materialFeatureTypes.cpp

@@ -32,6 +32,12 @@ ImplementFeatureType( MFT_TexAnim, MFG_PreTexture, 1.0f, true );
 ImplementFeatureType( MFT_Parallax, MFG_PreTexture, 2.0f, true );
 ImplementFeatureType( MFT_DiffuseVertColor, MFG_PreTexture, 3.0f, true );
 
+ImplementFeatureType( MFT_AccuScale, MFG_PreTexture, 4.0f, true );
+ImplementFeatureType( MFT_AccuDirection, MFG_PreTexture, 4.0f, true );
+ImplementFeatureType( MFT_AccuStrength, MFG_PreTexture, 4.0f, true );
+ImplementFeatureType( MFT_AccuCoverage, MFG_PreTexture, 4.0f, true );
+ImplementFeatureType( MFT_AccuSpecular, MFG_PreTexture, 4.0f, true );
+
 ImplementFeatureType( MFT_DiffuseMap, MFG_Texture, 2.0f, true );
 ImplementFeatureType( MFT_OverlayMap, MFG_Texture, 3.0f, true );
 ImplementFeatureType( MFT_DetailMap, MFG_Texture, 4.0f, true );
@@ -41,6 +47,8 @@ ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true );
 ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true );
 ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true );
 
+ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true );
+
 ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
 ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true );
 ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );

+ 7 - 0
Engine/source/materials/materialFeatureTypes.h

@@ -95,6 +95,13 @@ DeclareFeatureType( MFT_DetailMap );
 DeclareFeatureType( MFT_DiffuseColor );
 DeclareFeatureType( MFT_DetailNormalMap );
 
+DeclareFeatureType( MFT_AccuMap );
+DeclareFeatureType( MFT_AccuScale );
+DeclareFeatureType( MFT_AccuDirection );
+DeclareFeatureType( MFT_AccuStrength );
+DeclareFeatureType( MFT_AccuCoverage );
+DeclareFeatureType( MFT_AccuSpecular );
+
 /// This feature enables vertex coloring for the diffuse channel.
 DeclareFeatureType( MFT_DiffuseVertColor );
 

+ 1 - 0
Engine/source/materials/processedCustomMaterial.cpp

@@ -49,6 +49,7 @@ ProcessedCustomMaterial::ProcessedCustomMaterial(Material &mat)
    mCustomMaterial = static_cast<CustomMaterial*>(mMaterial);
    mHasSetStageData = false;
    mHasGlow = false;
+   mHasAccumulation = false;
    mMaxStages = 0;
    mMaxTex = 0;
 }

+ 1 - 0
Engine/source/materials/processedFFMaterial.cpp

@@ -67,6 +67,7 @@ void ProcessedFFMaterial::_construct()
 {   
    mHasSetStageData = false;
    mHasGlow = false;
+   mHasAccumulation = false;
    mIsLightingMaterial = false;
    mDefaultHandle = new FFMaterialParameterHandle();
    mDefaultParameters = new MaterialParameters();

+ 1 - 0
Engine/source/materials/processedMaterial.cpp

@@ -93,6 +93,7 @@ ProcessedMaterial::ProcessedMaterial()
    mCurrentParams( NULL ),
    mHasSetStageData( false ),
    mHasGlow( false ),   
+   mHasAccumulation( false ),   
    mMaxStages( 0 ),
    mVertexFormat( NULL ),
    mUserObject( NULL )

+ 6 - 0
Engine/source/materials/processedMaterial.h

@@ -197,6 +197,9 @@ public:
    /// Returns true if any pass glows
    bool hasGlow() const { return mHasGlow; }
 
+   /// Returns true if any pass accumulates
+   bool hasAccumulation() const { return mHasAccumulation; }
+
    /// Gets the stage number for a pass
    U32 getStageFromPass(U32 pass) const
    {
@@ -244,6 +247,9 @@ protected:
    /// If we glow
    bool mHasGlow;
 
+   /// If we have accumulation.
+   bool mHasAccumulation;
+
    /// Number of stages (not to be confused with number of passes)
    U32 mMaxStages;
 

+ 51 - 0
Engine/source/materials/processedShaderMaterial.cpp

@@ -55,6 +55,11 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/
    mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
    mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower);
    mSpecularStrengthSC = shader->getShaderConstHandle(ShaderGenVars::specularStrength);
+   mAccuScaleSC = shader->getShaderConstHandle("$accuScale");
+   mAccuDirectionSC = shader->getShaderConstHandle("$accuDirection");
+   mAccuStrengthSC = shader->getShaderConstHandle("$accuStrength");
+   mAccuCoverageSC = shader->getShaderConstHandle("$accuCoverage");
+   mAccuSpecularSC = shader->getShaderConstHandle("$accuSpecular");
    mParallaxInfoSC = shader->getShaderConstHandle("$parallaxInfo");
    mFogDataSC = shader->getShaderConstHandle(ShaderGenVars::fogData);
    mFogColorSC = shader->getShaderConstHandle(ShaderGenVars::fogColor);
@@ -423,6 +428,34 @@ void ProcessedShaderMaterial::_determineFeatures(  U32 stageNum,
          fd.features.addFeature( MFT_GlossMap );
    }
 
+   if ( mMaterial->mAccuEnabled[stageNum] )
+   {
+      fd.features.addFeature( MFT_AccuMap );
+      mHasAccumulation = true;
+   }
+
+   // we need both diffuse and normal maps + sm3 to have an accu map
+   if(   fd.features[ MFT_AccuMap ] && 
+       ( !fd.features[ MFT_DiffuseMap ] || 
+         !fd.features[ MFT_NormalMap ] ||
+         GFX->getPixelShaderVersion() < 3.0f ) ) {
+      AssertWarn(false, "SAHARA: Using an Accu Map requires SM 3.0 and a normal map.");
+      fd.features.removeFeature( MFT_AccuMap );
+      mHasAccumulation = false;
+   }
+
+   // if we still have the AccuMap feature, we add all accu constant features
+   if ( fd.features[ MFT_AccuMap ] ) {
+      // add the dependencies of the accu map
+      fd.features.addFeature( MFT_AccuScale );
+      fd.features.addFeature( MFT_AccuDirection );
+      fd.features.addFeature( MFT_AccuStrength );
+      fd.features.addFeature( MFT_AccuCoverage );
+      fd.features.addFeature( MFT_AccuSpecular );
+      // now remove some features that are not compatible with this
+      fd.features.removeFeature( MFT_UseInstancing );
+   }
+
    // Without a base texture use the diffuse color
    // feature to ensure some sort of output.
    if (!fd.features[MFT_DiffuseMap])
@@ -809,6 +842,13 @@ void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const S
          case Material::BackBuff:
             GFX->setTexture( i, sgData.backBuffTex );
             break;
+
+         case Material::AccuMap:
+            if ( sgData.accuTex )
+               GFX->setTexture( i, sgData.accuTex );
+            else
+               GFX->setTexture( i, GFXTexHandle::ZERO );
+            break;
             
          case Material::TexTarget:
             {
@@ -1137,6 +1177,17 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons
          0.0f, 0.0f ); // TODO: Wrap mode flags?
       shaderConsts->setSafe(handles->mBumpAtlasTileSC, atlasTileParams);
    }
+   
+   if( handles->mAccuScaleSC->isValid() )
+      shaderConsts->set( handles->mAccuScaleSC, mMaterial->mAccuScale[stageNum] );
+   if( handles->mAccuDirectionSC->isValid() )
+      shaderConsts->set( handles->mAccuDirectionSC, mMaterial->mAccuDirection[stageNum] );
+   if( handles->mAccuStrengthSC->isValid() )
+      shaderConsts->set( handles->mAccuStrengthSC, mMaterial->mAccuStrength[stageNum] );
+   if( handles->mAccuCoverageSC->isValid() )
+      shaderConsts->set( handles->mAccuCoverageSC, mMaterial->mAccuCoverage[stageNum] );
+   if( handles->mAccuSpecularSC->isValid() )
+      shaderConsts->set( handles->mAccuSpecularSC, mMaterial->mAccuSpecular[stageNum] );
 }
 
 bool ProcessedShaderMaterial::_hasCubemap(U32 pass)

+ 5 - 0
Engine/source/materials/processedShaderMaterial.h

@@ -48,6 +48,11 @@ public:
    GFXShaderConstHandle* mSpecularPowerSC;
    GFXShaderConstHandle* mSpecularStrengthSC;
    GFXShaderConstHandle* mParallaxInfoSC;
+   GFXShaderConstHandle* mAccuScaleSC;
+   GFXShaderConstHandle* mAccuDirectionSC;
+   GFXShaderConstHandle* mAccuStrengthSC;
+   GFXShaderConstHandle* mAccuCoverageSC;
+   GFXShaderConstHandle* mAccuSpecularSC;
    GFXShaderConstHandle* mFogDataSC;
    GFXShaderConstHandle* mFogColorSC;   
    GFXShaderConstHandle* mDetailScaleSC;

+ 1 - 0
Engine/source/materials/sceneData.h

@@ -64,6 +64,7 @@ struct SceneData
    GFXTextureObject *backBuffTex;
    GFXTextureObject *reflectTex;
    GFXTextureObject *miscTex;
+   GFXTextureObject *accuTex;
    
    /// The current lights to use in rendering
    /// in order of the light importance.

+ 3 - 0
Engine/source/platform/platform.h

@@ -74,6 +74,9 @@ enum ProcessorType
    CPU_AMD_K6_2,
    CPU_AMD_K6_3,
    CPU_AMD_Athlon,
+   CPU_AMD_Phenom,
+   CPU_AMD_PhenomII,
+   CPU_AMD_Bulldozer,
    CPU_AMD_Unknown,
    CPU_Cyrix_6x86,
    CPU_Cyrix_MediaGX,

+ 2 - 2
Engine/source/platform/platformAssert.h

@@ -92,8 +92,8 @@ public:
       exit conditions.
     */
    #define AssertFatal(x, y)         \
-         { if (((bool)(x))==(bool)0) \
-            { if ( ::PlatformAssert::processAssert(::PlatformAssert::Fatal, __FILE__, __LINE__,  y) ) { ::Platform::debugBreak(); } } }
+      { if (((bool)(x))==false) \
+         { if ( ::PlatformAssert::processAssert(::PlatformAssert::Fatal, __FILE__, __LINE__,  y) ) { ::Platform::debugBreak(); } } } 
 
 #else
    #define AssertFatal(x, y)   { TORQUE_UNUSED(x); TORQUE_UNUSED(y); }

+ 21 - 0
Engine/source/platform/platformCPU.cpp

@@ -178,6 +178,9 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
          pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0;
          pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0;
          pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0;
+       // Phenom and PhenomII support SSE3, SSE4a
+       pInfo.properties |= ( properties2 & BIT_SSE3 ) ? CPU_PROP_SSE3 : 0;
+         pInfo.properties |= ( properties2 & BIT_SSE4_1 ) ? CPU_PROP_SSE4_1 : 0;
          // switch on processor family code
          switch ((processor >> 8) & 0xf)
          {
@@ -223,6 +226,24 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
                pInfo.name = StringTable->insert("AMD Athlon");
                break;
 
+               // Phenom Family
+         case 15:
+               pInfo.type = CPU_AMD_Phenom;
+               pInfo.name = StringTable->insert("AMD Phenom");
+               break;
+
+            // Phenom II Family
+         case 16:
+               pInfo.type = CPU_AMD_PhenomII;
+               pInfo.name = StringTable->insert("AMD Phenom II");
+               break;
+
+            // Bulldozer Family
+         case 17:
+               pInfo.type = CPU_AMD_Bulldozer;
+               pInfo.name = StringTable->insert("AMD Bulldozer");
+               break;
+
             default:
                pInfo.type = CPU_AMD_Unknown;
                pInfo.name = StringTable->insert("AMD (unknown)");

+ 2 - 0
Engine/source/platformWin32/menus/menuBarWin32.cpp

@@ -133,6 +133,7 @@ void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos)
    }
 
    HWND hWindow = pWindow->getHWND();
+   SetMenu(hWindow, hWindowMenu);
    DrawMenuBar(hWindow);
 
 }
@@ -165,6 +166,7 @@ void MenuBar::removeFromCanvas()
    }
 
    HWND hWindow = pWindow->getHWND();
+   SetMenu(hWindow, NULL);
    DrawMenuBar(hWindow);
 
    mCanvas = NULL;

+ 1 - 1
Engine/source/platformWin32/winTime.cpp

@@ -139,7 +139,7 @@ void Platform::fileToLocalTime(const FileTime & ft, LocalTime * lt)
          lt->sec = time->wSecond;
          lt->min = time->wMinute;
          lt->hour = time->wHour;
-         lt->month = time->wMonth;
+         lt->month = time->wMonth - 1;
          lt->monthday = time->wDay;
          lt->weekday = time->wDayOfWeek;
          lt->year = (time->wYear < 1900) ? 1900 : (time->wYear - 1900);

+ 1 - 0
Engine/source/renderInstance/renderBinManager.cpp

@@ -164,6 +164,7 @@ void RenderBinManager::setupSGData( MeshRenderInst *ri, SceneData &data )
    data.cubemap      = ri->cubemap;
    data.miscTex      = ri->miscTex;
    data.reflectTex   = ri->reflectTex;
+   data.accuTex      = ri->accuTex;
    data.lightmap     = ri->lightmap;
    data.visibility   = ri->visibility;
    data.materialHint = ri->materialHint;

+ 40 - 1
Engine/source/renderInstance/renderGlowMgr.cpp

@@ -22,6 +22,7 @@
 
 #include "platform/platform.h"
 #include "renderInstance/renderGlowMgr.h"
+#include "renderInstance/renderParticleMgr.h"
 
 #include "scene/sceneManager.h"
 #include "scene/sceneRenderState.h"
@@ -89,6 +90,9 @@ RenderGlowMgr::RenderGlowMgr()
 {
    notifyType( RenderPassManager::RIT_Decal );
    notifyType( RenderPassManager::RIT_Translucent );
+   notifyType( RenderPassManager::RIT_Particle );
+
+   mParticleRenderMgr = NULL;
 
    mNamedTarget.registerWithName( "glowbuffer" );
    mTargetSizeType = WindowSize;
@@ -122,6 +126,14 @@ void RenderGlowMgr::addElement( RenderInst *inst )
    // manner so we can skip glow in a non-diffuse render pass.
    //if ( !mParentManager->getSceneManager()->getSceneState()->isDiffusePass() )
       //return RenderBinManager::arSkipped;
+   ParticleRenderInst *particleInst = NULL;
+   if(inst->type == RenderPassManager::RIT_Particle)
+      particleInst = static_cast<ParticleRenderInst*>(inst);
+   if(particleInst && particleInst->glow)
+   {
+      internalAddElement(inst);
+      return;
+   }
 
    // Skip it if we don't have a glowing material.
    BaseMatInstance *matInst = getMaterial( inst );
@@ -171,7 +183,31 @@ void RenderGlowMgr::render( SceneRenderState *state )
 
    for( U32 j=0; j<binSize; )
    {
-      MeshRenderInst *ri = static_cast<MeshRenderInst*>(mElementList[j].inst);
+      RenderInst *_ri = mElementList[j].inst;
+      if(_ri->type == RenderPassManager::RIT_Particle)
+      {
+         // Find the particle render manager (if we don't have it)
+         if(mParticleRenderMgr == NULL)
+         {
+            RenderPassManager *rpm = state->getRenderPass();
+            for( U32 i = 0; i < rpm->getManagerCount(); i++ )
+            {
+               RenderBinManager *bin = rpm->getManager(i);
+               if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles )
+               {
+                  mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin);
+                  break;
+               }
+            }
+         }
+
+         ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(_ri);
+         mParticleRenderMgr->renderParticle(ri, state);
+         j++;
+         continue;
+      }
+
+      MeshRenderInst *ri = static_cast<MeshRenderInst*>(_ri);
 
       setupSGData( ri, sgData );
 
@@ -191,6 +227,9 @@ void RenderGlowMgr::render( SceneRenderState *state )
          U32 a;
          for( a=j; a<binSize; a++ )
          {
+            if (mElementList[a].inst->type == RenderPassManager::RIT_Particle)
+               break;
+
             MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);
 
             if ( newPassNeeded( ri, passRI ) )

+ 2 - 1
Engine/source/renderInstance/renderGlowMgr.h

@@ -26,6 +26,7 @@
 #ifndef _TEXTARGETBIN_MGR_H_
 #include "renderInstance/renderTexTargetBinManager.h"
 #endif
+#include <renderInstance/renderParticleMgr.h>
 
 
 class PostEffect;
@@ -82,7 +83,7 @@ protected:
    };
 
    SimObjectPtr<PostEffect> mGlowEffect;
-
+   RenderParticleMgr *mParticleRenderMgr;
 };
 
 

+ 10 - 0
Engine/source/renderInstance/renderMeshMgr.cpp

@@ -115,6 +115,7 @@ void RenderMeshMgr::render(SceneRenderState * state)
    GFXCubemap *lastCubemap = NULL;
    GFXTextureObject *lastReflectTex = NULL;
    GFXTextureObject *lastMiscTex = NULL;
+   GFXTextureObject *lastAccuTex = NULL;
 
    SceneData sgData;
    sgData.init( state );
@@ -225,6 +226,15 @@ void RenderMeshMgr::render(SceneRenderState * state)
                dirty = true;
             }
 
+            // Update accumulation texture if it changed.
+            // Note: accumulation texture can be NULL, and must be updated.
+            if ( passRI->accuTex != lastAccuTex )
+            {
+               sgData.accuTex = passRI->accuTex;
+               lastAccuTex = lastAccuTex;
+               dirty = true;
+            }
+
             if ( dirty )
                mat->setTextureStages( state, sgData );
 

+ 65 - 60
Engine/source/renderInstance/renderParticleMgr.cpp

@@ -399,64 +399,7 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
          mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mModelViewProjSC, *ri->modelViewProj );
       }
 
-      // We want to turn everything into variation on a pre-multiplied alpha blend
-      F32 alphaFactor = 0.0f, alphaScale = 1.0f;
-      switch(ri->blendStyle)
-      {
-         // SrcAlpha, InvSrcAlpha
-      case ParticleRenderInst::BlendNormal:
-         alphaFactor = 1.0f;
-         break;
-
-         // SrcAlpha, One
-      case ParticleRenderInst::BlendAdditive:
-         alphaFactor = 1.0f;
-         alphaScale = 0.0f;
-         break;
-
-         // SrcColor, One
-      case ParticleRenderInst::BlendGreyscale:
-         alphaFactor = -1.0f;
-         alphaScale = 0.0f;
-         break;
-      }
-
-      mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaFactorSC, alphaFactor );
-      mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaScaleSC, alphaScale );
-
-      mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mFSModelViewProjSC, *ri->modelViewProj  );
-      mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mOneOverFarSC, 1.0f / state->getFarPlane() );     
-
-      if ( mParticleShaderConsts.mOneOverSoftnessSC->isValid() )
-      {
-         F32 oneOverSoftness = 1.0f;
-         if ( ri->softnessDistance > 0.0f )
-            oneOverSoftness = 1.0f / ( ri->softnessDistance / state->getFarPlane() );
-         mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mOneOverSoftnessSC, oneOverSoftness );
-      }
-
-      GFX->setShader( mParticleShader );
-      GFX->setShaderConstBuffer( mParticleShaderConsts.mShaderConsts );
-
-      GFX->setTexture( mParticleShaderConsts.mSamplerDiffuse->getSamplerRegister(), ri->diffuseTex );
-
-      // Set up the prepass texture.
-      if ( mParticleShaderConsts.mPrePassTargetParamsSC->isValid() )
-      {
-         GFXTextureObject *texObject = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
-         GFX->setTexture( mParticleShaderConsts.mSamplerPrePassTex->getSamplerRegister(), texObject );
-
-         Point4F rtParams( 0.0f, 0.0f, 1.0f, 1.0f );
-         if ( texObject )
-            ScreenSpace::RenderTargetParameters(texObject->getSize(), mPrepassTarget->getViewport(), rtParams);
-
-         mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mPrePassTargetParamsSC, rtParams );
-      }
-
-      GFX->setPrimitiveBuffer( *ri->primBuff );
-      GFX->setVertexBuffer( *ri->vertBuff );
-
-      GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 );
+      renderParticle(ri, state);
    }
    else if(ri->systemState == PSS_AwaitingCompositeDraw)
    {
@@ -494,9 +437,9 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
       }
       else
       {
-         AssertWarn(false, "No edge texture target defined, if you want to use mixed particle"
+         AssertFatal(false, "No edge texture target defined, if you want to use mixed particle"
             "rendering, then make sure that the EdgeDetectPostEffect is enabled.");
-         ri->systemState == PSS_AwaitingHighResDraw;
+         ri->systemState = PSS_AwaitingHighResDraw;
          return;
       }
 
@@ -530,6 +473,68 @@ void RenderParticleMgr::renderInstance(ParticleRenderInst *ri, SceneRenderState
    }
 }
 
+void RenderParticleMgr::renderParticle(ParticleRenderInst* ri, SceneRenderState* state)
+{
+   // We want to turn everything into variation on a pre-multiplied alpha blend
+   F32 alphaFactor = 0.0f, alphaScale = 1.0f;
+   switch(ri->blendStyle)
+   {
+      // SrcAlpha, InvSrcAlpha
+   case ParticleRenderInst::BlendNormal:
+      alphaFactor = 1.0f;
+      break;
+
+      // SrcAlpha, One
+   case ParticleRenderInst::BlendAdditive:
+      alphaFactor = 1.0f;
+      alphaScale = 0.0f;
+      break;
+
+      // SrcColor, One
+   case ParticleRenderInst::BlendGreyscale:
+      alphaFactor = -1.0f;
+      alphaScale = 0.0f;
+      break;
+   }
+
+   mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaFactorSC, alphaFactor );
+   mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mAlphaScaleSC, alphaScale );
+
+   mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mFSModelViewProjSC, *ri->modelViewProj  );
+   mParticleShaderConsts.mShaderConsts->setSafe( mParticleShaderConsts.mOneOverFarSC, 1.0f / state->getFarPlane() );     
+
+   if ( mParticleShaderConsts.mOneOverSoftnessSC->isValid() )
+   {
+      F32 oneOverSoftness = 1.0f;
+      if ( ri->softnessDistance > 0.0f )
+         oneOverSoftness = 1.0f / ( ri->softnessDistance / state->getFarPlane() );
+      mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mOneOverSoftnessSC, oneOverSoftness );
+   }
+
+   GFX->setShader( mParticleShader );
+   GFX->setShaderConstBuffer( mParticleShaderConsts.mShaderConsts );
+
+      GFX->setTexture( mParticleShaderConsts.mSamplerDiffuse->getSamplerRegister(), ri->diffuseTex );
+
+   // Set up the prepass texture.
+   if ( mParticleShaderConsts.mPrePassTargetParamsSC->isValid() )
+   {
+      GFXTextureObject *texObject = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
+         GFX->setTexture( mParticleShaderConsts.mSamplerPrePassTex->getSamplerRegister(), texObject );
+
+      Point4F rtParams( 0.0f, 0.0f, 1.0f, 1.0f );
+      if ( texObject )
+         ScreenSpace::RenderTargetParameters(texObject->getSize(), mPrepassTarget->getViewport(), rtParams);
+
+      mParticleShaderConsts.mShaderConsts->set( mParticleShaderConsts.mPrePassTargetParamsSC, rtParams );
+   }
+
+   GFX->setPrimitiveBuffer( *ri->primBuff );
+   GFX->setVertexBuffer( *ri->vertBuff );
+
+   GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, ri->count * 4, 0, ri->count * 2 );
+}
+
 bool RenderParticleMgr::_initShader()
 {
    ShaderData *shaderData = NULL;

+ 3 - 1
Engine/source/renderInstance/renderParticleMgr.h

@@ -77,7 +77,9 @@ protected:
    // Not only a helper method, but a method for the RenderTranslucentMgr to
    // request a particle system draw
    void renderInstance(ParticleRenderInst *ri, SceneRenderState *state);
-
+public:
+   void renderParticle(ParticleRenderInst *ri, SceneRenderState *state);
+protected:
    bool mOffscreenRenderEnabled;
 
    /// The prepass render target used for the

+ 3 - 0
Engine/source/renderInstance/renderPassManager.h

@@ -366,6 +366,7 @@ struct MeshRenderInst : public RenderInst
    GFXTextureObject *backBuffTex;
    GFXTextureObject *reflectTex;
    GFXTextureObject *miscTex;
+   GFXTextureObject *accuTex;
    GFXCubemap   *cubemap;
 
    void clear();
@@ -392,6 +393,8 @@ struct ParticleRenderInst : public RenderInst
    /// The total particle count to render.
    S32 count;
 
+   bool glow;
+
    /// The combined model, camera, and projection transform.
    const MatrixF *modelViewProj;       
         

+ 1 - 1
Engine/source/scene/sceneManager.cpp

@@ -40,7 +40,6 @@
 // For player object bounds workaround.
 #include "T3D/player.h"
 
-
 extern bool gEditingMission;
 
 
@@ -113,6 +112,7 @@ SceneManager::SceneManager( bool isClient )
      mDisplayTargetResolution( 0, 0 ),
      mDefaultRenderPass( NULL ),
      mVisibleDistance( 500.f ),
+     mVisibleGhostDistance( 0 ),
      mNearClip( 0.1f ),
      mAmbientLightColor( ColorF( 0.1f, 0.1f, 0.1f, 1.0f ) ),
      mZoneManager( NULL )

+ 4 - 0
Engine/source/scene/sceneManager.h

@@ -141,6 +141,7 @@ class SceneManager
 
       F32 mVisibleDistance;
 
+      F32 mVisibleGhostDistance;
       F32 mNearClip;
 
       FogData mFogData;
@@ -317,6 +318,9 @@ class SceneManager
       /// Returns the default visible distance for the scene.
       F32 getVisibleDistance() { return mVisibleDistance; }
 
+      void setVisibleGhostDistance( F32 dist ) { mVisibleGhostDistance = dist; }
+      F32  getVisibleGhostDistance() { return mVisibleGhostDistance;}
+
       /// Used by LevelInfo to set the default near clip plane 
       /// for rendering the scene.
       ///

+ 11 - 0
Engine/source/scene/sceneObject.cpp

@@ -42,6 +42,8 @@
 #include "math/mathIO.h"
 #include "math/mTransform.h"
 #include "T3D/gameBase/gameProcess.h"
+#include "T3D/gameBase/gameConnection.h"
+#include "T3D/accumulationVolume.h"
 
 IMPLEMENT_CONOBJECT(SceneObject);
 
@@ -140,6 +142,8 @@ SceneObject::SceneObject()
 
    mObjectFlags.set( RenderEnabledFlag | SelectionEnabledFlag );
    mIsScopeAlways = false;
+
+   mAccuTex = NULL;
 }
 
 //-----------------------------------------------------------------------------
@@ -151,6 +155,7 @@ SceneObject::~SceneObject()
    AssertFatal( !mSceneObjectLinks,
       "SceneObject::~SceneObject() - object is still linked to SceneTrackers" );
 
+   mAccuTex = NULL;
    unlink();
 }
 
@@ -664,6 +669,12 @@ static void scopeCallback( SceneObject* obj, void* conPtr )
 
 void SceneObject::onCameraScopeQuery( NetConnection* connection, CameraScopeQuery* query )
 {
+   SceneManager* sceneManager = getSceneManager();
+   GameConnection* conn  = dynamic_cast<GameConnection*> (connection);
+   if (conn && (query->visibleDistance = conn->getVisibleGhostDistance()) == 0.0f)
+      if ((query->visibleDistance = sceneManager->getVisibleGhostDistance()) == 0.0f)
+         query->visibleDistance = sceneManager->getVisibleDistance();
+
    // Object itself is in scope.
 
    if( this->isScopeable() )

+ 10 - 0
Engine/source/scene/sceneObject.h

@@ -51,6 +51,10 @@
 #include "scene/sceneContainer.h"
 #endif
 
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+
 
 class SceneManager;
 class SceneRenderState;
@@ -765,8 +769,14 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       static bool _setFieldRotation( void *object, const char *index, const char *data );
       static bool _setFieldScale( void *object, const char *index, const char *data );
       static bool _setMountPID( void* object, const char* index, const char* data );
+      static bool _setAccuEnabled( void *object, const char *index, const char *data );
 
       /// @}
+
+   // Accumulation Texture
+   // Note: This was placed in SceneObject to both ShapeBase and TSStatic could support it.
+   public:
+      GFXTextureObject* mAccuTex;
 };
 
 #endif  // _SCENEOBJECT_H_

+ 241 - 0
Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp

@@ -0,0 +1,241 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "shaderGen/GLSL/accuFeatureGLSL.h"
+#include "shaderGen/shaderFeature.h"
+#include "shaderGen/shaderOp.h"
+#include "shaderGen/featureMgr.h"
+#include "materials/materialFeatureTypes.h"
+#include "gfx/gfxDevice.h"
+#include "materials/processedMaterial.h"
+
+//****************************************************************************
+// Accu Texture
+//****************************************************************************
+void AccuTexFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
+                                    const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+   getOutTexCoord(   "texCoord", 
+                     "vec2", 
+                     true, 
+                     false, 
+                     meta, 
+                     componentList );
+   
+   getOutObjToTangentSpace( componentList, meta, fd );
+   addOutAccuVec( componentList, meta );
+
+   output = meta;
+}
+
+void AccuTexFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
+                                    const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+
+   output = meta;
+
+   // OUT.col
+   Var *color = (Var*) LangElement::find( "col" );
+   if (!color)
+   {
+      output = new GenOp("   //NULL COLOR!");
+      return;
+   }
+
+   // accu map
+   Var *accuMap = new Var;
+   accuMap->setType( "sampler2D" );
+   accuMap->setName( "accuMap" );
+   accuMap->uniform = true;
+   accuMap->sampler = true;
+   accuMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+   // accuColor var
+   Var *accuColor = new Var;
+   accuColor->setType( "vec4" );
+   accuColor->setName( "accuColor" );
+   LangElement *colorAccuDecl = new DecOp( accuColor );
+
+   // plc (placement)
+   Var *accuPlc = new Var;
+   accuPlc->setType( "vec4" );
+   accuPlc->setName( "plc" );
+   LangElement *plcAccu = new DecOp( accuPlc );
+
+   // accu constants
+   Var *accuScale = (Var*)LangElement::find( "accuScale" );
+   if ( !accuScale ) {
+      accuScale = new Var;
+      accuScale->setType( "float" );
+      accuScale->setName( "accuScale" );
+      accuScale->uniform = true;
+      accuScale->sampler = false;
+      accuScale->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
+   if ( !accuDirection ) {
+      accuDirection = new Var;
+      accuDirection->setType( "float" );
+      accuDirection->setName( "accuDirection" );
+      accuDirection->uniform = true;
+      accuDirection->sampler = false;
+      accuDirection->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
+   if ( !accuStrength ) {
+      accuStrength = new Var;
+      accuStrength->setType( "float" );
+      accuStrength->setName( "accuStrength" );
+      accuStrength->uniform = true;
+      accuStrength->sampler = false;
+      accuStrength->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
+   if ( !accuCoverage ) {
+      accuCoverage = new Var;
+      accuCoverage->setType( "float" );
+      accuCoverage->setName( "accuCoverage" );
+      accuCoverage->uniform = true;
+      accuCoverage->sampler = false;
+      accuCoverage->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
+   if ( !accuSpecular ) {
+      accuSpecular = new Var;
+      accuSpecular->setType( "float" );
+      accuSpecular->setName( "accuSpecular" );
+      accuSpecular->uniform = true;
+      accuSpecular->sampler = false;
+      accuSpecular->constSortPos = cspPotentialPrimitive;
+   }
+
+   Var *inTex = getInTexCoord( "texCoord", "vec2", true, componentList );
+   Var *accuVec = getInTexCoord( "accuVec", "vec3", true, componentList );
+   Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
+   if( bumpNorm == NULL ) {
+      bumpNorm = (Var *)LangElement::find( "bumpNormal" );
+      if (!bumpNorm)
+      {
+         output = new GenOp("   //NULL bumpNormal!");
+         return;
+      }
+   }
+
+   // get the accu pixel color
+   meta->addStatement( new GenOp( "   @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) );
+
+   // scale up normals
+   meta->addStatement( new GenOp( "   @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
+
+   // assign direction
+   meta->addStatement( new GenOp( "   @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
+
+   // saturate based on strength
+   meta->addStatement( new GenOp( "   @ = saturate( float4(dot( float3(@), @.xyz * pow(@, 5) ) ));\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
+
+   // add coverage
+   meta->addStatement( new GenOp( "   @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
+
+   // clamp to a sensible value
+   meta->addStatement( new GenOp( "   @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
+
+   // light
+   Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
+   if(lightColor != NULL)
+      meta->addStatement( new GenOp( "   @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
+
+   // lerp with current pixel - use the accu alpha as well
+   meta->addStatement( new GenOp( "   @ = mix( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
+
+   // the result should always be opaque
+   meta->addStatement( new GenOp( "   @.a = 1.0;\r\n", color ) );
+}
+
+void AccuTexFeatGLSL::setTexData(Material::StageData &stageDat,
+                                    const MaterialFeatureData &fd,
+                                    RenderPassData &passData,
+                                    U32 &texIndex )
+{
+   //GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
+   //if ( tex )
+   //{
+   passData.mSamplerNames[texIndex] = "accuMap";
+   passData.mTexType[ texIndex++ ] = Material::AccuMap;
+      //passData.mTexSlot[ texIndex++ ].texObject = tex;
+   //}
+}
+
+
+void AccuTexFeatGLSL::getAccuVec(MultiLine *meta, LangElement *accuVec)
+{
+   // Get the transform to world space.
+   Var *objTrans = (Var*)LangElement::find( "objTrans" );
+   if ( !objTrans )
+   {
+      objTrans = new Var;
+      objTrans->setType( "float4x4" );
+      objTrans->setName( "objTrans" );
+      objTrans->uniform = true;
+      objTrans->constSortPos = cspPrimitive;      
+   }
+
+   // accu obj trans
+   Var *aobjTrans = new Var;
+   aobjTrans->setType( "float4x4" );
+   aobjTrans->setName( "accuObjTrans" );
+   LangElement *accuObjTransDecl = new DecOp( aobjTrans );
+
+   Var *outObjToTangentSpace = (Var*)LangElement::find( "objToTangentSpace" );
+
+   Var *tav = new Var;
+   tav->setType( "float4" );
+   tav->setName( "tAccuVec" );
+   LangElement *tavDecl = new DecOp( tav );
+
+   meta->addStatement( new GenOp( "   @ = float4(0,0,1,0);\r\n", tavDecl ) );
+   meta->addStatement( new GenOp( "   @ = transpose(@);\r\n", accuObjTransDecl, objTrans ) );
+   meta->addStatement( new GenOp( "   @ = tMul(@, @);\r\n", tav, aobjTrans, tav ) );
+   meta->addStatement( new GenOp( "   @.xyz = tMul(@, @.xyz);\r\n", tav, outObjToTangentSpace, tav ) );
+   meta->addStatement( new GenOp( "   @.y *= -1;\r\n", tav ) );
+   meta->addStatement( new GenOp( "   @ = @.xyz;\r\n", accuVec, tav ) );
+}
+
+Var* AccuTexFeatGLSL::addOutAccuVec(Vector<ShaderComponent*> &componentList, MultiLine *meta)
+{
+   Var *outAccuVec = (Var*)LangElement::find( "accuVec" );
+   if ( !outAccuVec )
+   {
+      // Setup the connector.
+      ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+      outAccuVec = connectComp->getElement( RT_TEXCOORD );
+      outAccuVec->setName( "accuVec" );
+      outAccuVec->setStructName( "OUT" );
+      outAccuVec->setType( "float3" );
+      outAccuVec->mapsToSampler = false;
+
+      getAccuVec( meta, outAccuVec );
+   }
+
+   return outAccuVec;
+}

+ 185 - 0
Engine/source/shaderGen/GLSL/accuFeatureGLSL.h

@@ -0,0 +1,185 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _ACCUFEATUREGLSL_H_
+#define _ACCUFEATUREGLSL_H_
+
+#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
+#include "shaderGen/GLSL/shaderFeatureGLSL.h"
+#endif
+#ifndef _LANG_ELEMENT_H_
+#include "shaderGen/langElement.h"
+#endif
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+#ifndef _FEATUREMGR_H_
+#include "shaderGen/featureMgr.h"
+#endif
+#ifndef _MATERIALFEATURETYPES_H_
+#include "materials/materialFeatureTypes.h"
+#endif
+#ifndef _MATERIALFEATUREDATA_H_
+#include "materials/materialFeatureData.h"
+#endif
+
+/// Accu texture
+class AccuTexFeatGLSL : public ShaderFeatureGLSL
+{
+public:
+
+   //****************************************************************************
+   // Accu Texture
+   //****************************************************************************
+   virtual void processVert(  Vector<ShaderComponent*> &componentList, 
+                              const MaterialFeatureData &fd );
+
+   virtual void processPix(   Vector<ShaderComponent*> &componentList, 
+                              const MaterialFeatureData &fd );
+
+   void getAccuVec( MultiLine *meta, LangElement *accuVec );
+
+   Var* addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta );
+
+   virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
+
+   virtual Resources getResources( const MaterialFeatureData &fd )
+   {
+      Resources res; 
+      res.numTex = 1;
+      res.numTexReg = 1;
+      return res;
+   }
+
+   virtual void setTexData(   Material::StageData &stageDat,
+                              const MaterialFeatureData &fd,
+                              RenderPassData &passData,
+                              U32 &texIndex );
+
+   virtual String getName()
+   {
+      return "Accu Texture";
+   }
+};
+
+class AccuScaleFeature : public ShaderFeatureGLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuScale = (Var *)( LangElement::find("accuScale") );
+      if( accuScale == NULL )
+      {
+         accuScale = new Var;
+         accuScale->setType( "float" );
+         accuScale->setName( "accuScale" );
+         accuScale->constSortPos = cspPotentialPrimitive;
+         accuScale->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Scale"; }
+};
+
+class AccuDirectionFeature : public ShaderFeatureGLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuDirection = (Var *)( LangElement::find("accuDirection") );
+      if( accuDirection == NULL )
+      {
+         accuDirection = new Var;
+         accuDirection->setType( "float" );
+         accuDirection->setName( "accuDirection" );
+         accuDirection->constSortPos = cspPotentialPrimitive;
+         accuDirection->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Direction"; }
+};
+
+class AccuStrengthFeature : public ShaderFeatureGLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuStrength = (Var *)( LangElement::find("accuStrength") );
+      if( accuStrength == NULL )
+      {
+         accuStrength = new Var;
+         accuStrength->setType( "float" );
+         accuStrength->setName( "accuStrength" );
+         accuStrength->constSortPos = cspPotentialPrimitive;
+         accuStrength->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Strength"; }
+};
+
+class AccuCoverageFeature : public ShaderFeatureGLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuCoverage = (Var *)( LangElement::find("accuCoverage") );
+      if( accuCoverage == NULL )
+      {
+         accuCoverage = new Var;
+         accuCoverage->setType( "float" );
+         accuCoverage->setName( "accuCoverage" );
+         accuCoverage->constSortPos = cspPotentialPrimitive;
+         accuCoverage->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Coverage"; }
+};
+
+
+class AccuSpecularFeature : public ShaderFeatureGLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuSpecular = (Var *)( LangElement::find("accuSpecular") );
+      if( accuSpecular == NULL )
+      {
+         accuSpecular = new Var;
+         accuSpecular->setType( "float" );
+         accuSpecular->setName( "accuSpecular" );
+         accuSpecular->constSortPos = cspPotentialPrimitive;
+         accuSpecular->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Specular"; }
+};
+
+#endif

+ 6 - 12
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp

@@ -1682,7 +1682,7 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
     cubeVertPos->setType( "vec3" );
    LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
 
-    meta->addStatement( new GenOp( "   @ = tMul(mat3( @ ), @).xyz;\r\n",
+   meta->addStatement( new GenOp( "   @ = tMul( @, float4(@,1)).xyz;\r\n",
                        cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
 
    // cube normal
@@ -1694,6 +1694,9 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
     meta->addStatement( new GenOp( "   @ = ( tMul( (@),  vec4(@, 0) ) ).xyz;\r\n",
                        cubeNormDecl, cubeTrans, inNormal ) );
 
+    meta->addStatement( new GenOp( "   @ = bool(length(@)) ? normalize(@) : @;\r\n",
+                        cubeNormal, cubeNormal, cubeNormal, cubeNormal ) );
+
     // grab the eye position
     Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
     if ( !eyePos )
@@ -1703,23 +1706,14 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
         eyePos->constSortPos = cspPass;
     }
 
-    // cube position
-    Var * cubePos = new Var;
-    cubePos->setName( "cubePos" );
-    cubePos->setType( "vec3" );
-    LangElement *cubePosDecl = new DecOp( cubePos );
-
-    meta->addStatement( new GenOp( "   @ = vec3( @[3][0], @[3][1], @[3][2] );\r\n",
-                        cubePosDecl, cubeTrans, cubeTrans, cubeTrans ) );
-
    // eye to vert
    Var * eyeToVert = new Var;
    eyeToVert->setName( "eyeToVert" );
     eyeToVert->setType( "vec3" );
    LangElement *e2vDecl = new DecOp( eyeToVert );
 
-    meta->addStatement( new GenOp( "   @ = @ - ( @ - @ );\r\n", 
-                        e2vDecl, cubeVertPos, eyePos, cubePos ) );
+    meta->addStatement( new GenOp( "   @ = @ - @;\r\n", 
+                        e2vDecl, cubeVertPos, eyePos ) );
 
    // grab connector texcoord register
    ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

+ 2 - 0
Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp

@@ -32,6 +32,7 @@
 #include "shaderGen/GLSL/paraboloidGLSL.h"
 #include "materials/materialFeatureTypes.h"
 #include "core/module.h"
+#include "shaderGen/GLSL/accuFeatureGLSL.h"
 
 
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@@ -62,6 +63,7 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
    FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
    FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
+   FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatGLSL );
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL );

+ 238 - 0
Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp

@@ -0,0 +1,238 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "shaderGen/HLSL/accuFeatureHLSL.h"
+#include "shaderGen/shaderFeature.h"
+#include "shaderGen/shaderOp.h"
+#include "shaderGen/featureMgr.h"
+#include "materials/materialFeatureTypes.h"
+#include "gfx/gfxDevice.h"
+#include "materials/processedMaterial.h"
+
+//****************************************************************************
+// Accu Texture
+//****************************************************************************
+void AccuTexFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
+                                    const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+   getOutTexCoord(   "texCoord", 
+                     "float2", 
+                     true, 
+                     false, 
+                     meta, 
+                     componentList );
+   
+   getOutObjToTangentSpace( componentList, meta, fd );
+   addOutAccuVec( componentList, meta );
+
+   output = meta;
+}
+
+void AccuTexFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
+                                    const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+
+   output = meta;
+
+   // OUT.col
+   Var *color = (Var*) LangElement::find( "col" );
+   if (!color)
+   {
+      output = new GenOp("   //NULL COLOR!");
+      return;
+   }
+
+   // accu map
+   Var *accuMap = new Var;
+   accuMap->setType( "sampler2D" );
+   accuMap->setName( "accuMap" );
+   accuMap->uniform = true;
+   accuMap->sampler = true;
+   accuMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+   // accuColor var
+   Var *accuColor = new Var;
+   accuColor->setType( "float4" );
+   accuColor->setName( "accuColor" );
+   LangElement *colorAccuDecl = new DecOp( accuColor );
+
+   // plc (placement)
+   Var *accuPlc = new Var;
+   accuPlc->setType( "float4" );
+   accuPlc->setName( "plc" );
+   LangElement *plcAccu = new DecOp( accuPlc );
+
+   // accu constants
+   Var *accuScale = (Var*)LangElement::find( "accuScale" );
+   if ( !accuScale ) {
+      accuScale = new Var;
+      accuScale->setType( "float" );
+      accuScale->setName( "accuScale" );
+      accuScale->uniform = true;
+      accuScale->sampler = false;
+      accuScale->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuDirection = (Var*)LangElement::find( "accuDirection" );
+   if ( !accuDirection ) {
+      accuDirection = new Var;
+      accuDirection->setType( "float" );
+      accuDirection->setName( "accuDirection" );
+      accuDirection->uniform = true;
+      accuDirection->sampler = false;
+      accuDirection->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuStrength = (Var*)LangElement::find( "accuStrength" );
+   if ( !accuStrength ) {
+      accuStrength = new Var;
+      accuStrength->setType( "float" );
+      accuStrength->setName( "accuStrength" );
+      accuStrength->uniform = true;
+      accuStrength->sampler = false;
+      accuStrength->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" );
+   if ( !accuCoverage ) {
+      accuCoverage = new Var;
+      accuCoverage->setType( "float" );
+      accuCoverage->setName( "accuCoverage" );
+      accuCoverage->uniform = true;
+      accuCoverage->sampler = false;
+      accuCoverage->constSortPos = cspPotentialPrimitive;
+   }
+   Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" );
+   if ( !accuSpecular ) {
+      accuSpecular = new Var;
+      accuSpecular->setType( "float" );
+      accuSpecular->setName( "accuSpecular" );
+      accuSpecular->uniform = true;
+      accuSpecular->sampler = false;
+      accuSpecular->constSortPos = cspPotentialPrimitive;
+   }
+
+   Var *inTex = getInTexCoord( "texCoord", "float2", true, componentList );
+   Var *accuVec = getInTexCoord( "accuVec", "float3", true, componentList );
+   Var *bumpNorm = (Var *)LangElement::find( "bumpSample" );
+   if( bumpNorm == NULL ) {
+      bumpNorm = (Var *)LangElement::find( "bumpNormal" );
+      if (!bumpNorm)
+        return;
+   }
+
+   // get the accu pixel color
+   meta->addStatement( new GenOp( "   @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) );
+
+   // scale up normals
+   meta->addStatement( new GenOp( "   @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) );
+
+   // assign direction
+   meta->addStatement( new GenOp( "   @.z *= @*2.0;\r\n", accuVec, accuDirection ) );
+
+   // saturate based on strength
+   meta->addStatement( new GenOp( "   @ = saturate( dot( @, @.xyz * pow(@, 5) ) );\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) );
+
+   // add coverage
+   meta->addStatement( new GenOp( "   @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) );
+
+   // clamp to a sensible value
+   meta->addStatement( new GenOp( "   @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) );
+
+   // light
+   Var *lightColor = (Var*) LangElement::find( "d_lightcolor" );
+   if(lightColor != NULL)
+      meta->addStatement( new GenOp( "   @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) );
+
+   // lerp with current pixel - use the accu alpha as well
+   meta->addStatement( new GenOp( "   @ = lerp( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) );
+
+   // the result should always be opaque
+   meta->addStatement( new GenOp( "   @.a = 1.0;\r\n", color ) );
+
+}
+
+void AccuTexFeatHLSL::setTexData(   Material::StageData &stageDat,
+                                    const MaterialFeatureData &fd,
+                                    RenderPassData &passData,
+                                    U32 &texIndex )
+{
+   //GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap );
+   //if ( tex )
+   //{
+   passData.mSamplerNames[ texIndex ] = "AccuMap";
+   passData.mTexType[ texIndex++ ] = Material::AccuMap;
+   //}
+}
+
+
+void AccuTexFeatHLSL::getAccuVec( MultiLine *meta, LangElement *accuVec )
+{
+   // Get the transform to world space.
+   Var *objTrans = (Var*)LangElement::find( "objTrans" );
+   if ( !objTrans )
+   {
+      objTrans = new Var;
+      objTrans->setType( "float4x4" );
+      objTrans->setName( "objTrans" );
+      objTrans->uniform = true;
+      objTrans->constSortPos = cspPrimitive;      
+   }
+
+   // accu obj trans
+   Var *aobjTrans = new Var;
+   aobjTrans->setType( "float4x4" );
+   aobjTrans->setName( "accuObjTrans" );
+   LangElement *accuObjTransDecl = new DecOp( aobjTrans );
+
+   Var *outObjToTangentSpace = (Var*)LangElement::find( "objToTangentSpace" );
+
+   Var *tav = new Var;
+   tav->setType( "float4" );
+   tav->setName( "tAccuVec" );
+   LangElement *tavDecl = new DecOp( tav );
+
+   meta->addStatement( new GenOp( "   @ = float4(0,0,1,0);\r\n", tavDecl ) );
+   meta->addStatement( new GenOp( "   @ = transpose(@);\r\n", accuObjTransDecl, objTrans ) );
+   meta->addStatement( new GenOp( "   @ = mul(@, @);\r\n", tav, aobjTrans, tav ) );
+   meta->addStatement( new GenOp( "   @.xyz = mul(@, @.xyz);\r\n", tav, outObjToTangentSpace, tav ) );
+   meta->addStatement( new GenOp( "   @.y *= -1;\r\n", tav ) );
+   meta->addStatement( new GenOp( "   @ = @.xyz;\r\n", accuVec, tav ) );
+}
+
+Var* AccuTexFeatHLSL::addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta )
+{
+   Var *outAccuVec = (Var*)LangElement::find( "accuVec" );
+   if ( !outAccuVec )
+   {
+      // Setup the connector.
+      ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+      outAccuVec = connectComp->getElement( RT_TEXCOORD );
+      outAccuVec->setName( "accuVec" );
+      outAccuVec->setStructName( "OUT" );
+      outAccuVec->setType( "float3" );
+      outAccuVec->mapsToSampler = false;
+
+      getAccuVec( meta, outAccuVec );
+   }
+
+   return outAccuVec;
+}

+ 185 - 0
Engine/source/shaderGen/HLSL/accuFeatureHLSL.h

@@ -0,0 +1,185 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _ACCUFEATUREHLSL_H_
+#define _ACCUFEATUREHLSL_H_
+
+#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
+#include "shaderGen/HLSL/shaderFeatureHLSL.h"
+#endif
+#ifndef _LANG_ELEMENT_H_
+#include "shaderGen/langElement.h"
+#endif
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+#ifndef _FEATUREMGR_H_
+#include "shaderGen/featureMgr.h"
+#endif
+#ifndef _MATERIALFEATURETYPES_H_
+#include "materials/materialFeatureTypes.h"
+#endif
+#ifndef _MATERIALFEATUREDATA_H_
+#include "materials/materialFeatureData.h"
+#endif
+
+/// Accu texture
+class AccuTexFeatHLSL : public ShaderFeatureHLSL
+{
+public:
+
+   //****************************************************************************
+   // Accu Texture
+   //****************************************************************************
+   virtual void processVert(  Vector<ShaderComponent*> &componentList, 
+                              const MaterialFeatureData &fd );
+
+   virtual void processPix(   Vector<ShaderComponent*> &componentList, 
+                              const MaterialFeatureData &fd );
+
+   void getAccuVec( MultiLine *meta, LangElement *accuVec );
+
+   Var* addOutAccuVec( Vector<ShaderComponent*> &componentList, MultiLine *meta );
+
+   virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
+
+   virtual Resources getResources( const MaterialFeatureData &fd )
+   {
+      Resources res; 
+      res.numTex = 1;
+      res.numTexReg = 1;
+      return res;
+   }
+
+   virtual void setTexData(   Material::StageData &stageDat,
+                              const MaterialFeatureData &fd,
+                              RenderPassData &passData,
+                              U32 &texIndex );
+
+   virtual String getName()
+   {
+      return "Accu Texture";
+   }
+};
+
+class AccuScaleFeature : public ShaderFeatureHLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuScale = (Var *)( LangElement::find("accuScale") );
+      if( accuScale == NULL )
+      {
+         accuScale = new Var;
+         accuScale->setType( "float" );
+         accuScale->setName( "accuScale" );
+         accuScale->constSortPos = cspPotentialPrimitive;
+         accuScale->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Scale"; }
+};
+
+class AccuDirectionFeature : public ShaderFeatureHLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuDirection = (Var *)( LangElement::find("accuDirection") );
+      if( accuDirection == NULL )
+      {
+         accuDirection = new Var;
+         accuDirection->setType( "float" );
+         accuDirection->setName( "accuDirection" );
+         accuDirection->constSortPos = cspPotentialPrimitive;
+         accuDirection->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Direction"; }
+};
+
+class AccuStrengthFeature : public ShaderFeatureHLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuStrength = (Var *)( LangElement::find("accuStrength") );
+      if( accuStrength == NULL )
+      {
+         accuStrength = new Var;
+         accuStrength->setType( "float" );
+         accuStrength->setName( "accuStrength" );
+         accuStrength->constSortPos = cspPotentialPrimitive;
+         accuStrength->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Strength"; }
+};
+
+class AccuCoverageFeature : public ShaderFeatureHLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuCoverage = (Var *)( LangElement::find("accuCoverage") );
+      if( accuCoverage == NULL )
+      {
+         accuCoverage = new Var;
+         accuCoverage->setType( "float" );
+         accuCoverage->setName( "accuCoverage" );
+         accuCoverage->constSortPos = cspPotentialPrimitive;
+         accuCoverage->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Coverage"; }
+};
+
+
+class AccuSpecularFeature : public ShaderFeatureHLSL
+{
+public:
+   virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+   {
+      // Find the constant value
+      Var *accuSpecular = (Var *)( LangElement::find("accuSpecular") );
+      if( accuSpecular == NULL )
+      {
+         accuSpecular = new Var;
+         accuSpecular->setType( "float" );
+         accuSpecular->setName( "accuSpecular" );
+         accuSpecular->constSortPos = cspPotentialPrimitive;
+         accuSpecular->uniform = true;
+      }
+   }
+
+   virtual String getName() { return "Accu Specular"; }
+};
+
+#endif

+ 3 - 12
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -1681,7 +1681,7 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
     cubeVertPos->setType( "float3" );
     LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
 
-    meta->addStatement( new GenOp( "   @ = mul((float3x3)@, @).xyz;\r\n", 
+    meta->addStatement( new GenOp( "   @ = mul(@, float4(@,1)).xyz;\r\n", 
                         cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
 
     // cube normal
@@ -1702,23 +1702,14 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
         eyePos->constSortPos = cspPass;
     }
 
-    // cube position
-    Var * cubePos = new Var;
-    cubePos->setName( "cubePos" );
-    cubePos->setType( "float3" );
-    LangElement *cubePosDecl = new DecOp( cubePos );
-
-    meta->addStatement( new GenOp( "   @ = float3( @[0][3], @[1][3], @[2][3] );\r\n", 
-                        cubePosDecl, cubeTrans, cubeTrans, cubeTrans ) );
-
     // eye to vert
     Var * eyeToVert = new Var;
     eyeToVert->setName( "eyeToVert" );
     eyeToVert->setType( "float3" );
     LangElement *e2vDecl = new DecOp( eyeToVert );
 
-    meta->addStatement( new GenOp( "   @ = @ - ( @ - @ );\r\n", 
-                        e2vDecl, cubeVertPos, eyePos, cubePos ) );
+    meta->addStatement( new GenOp( "   @ = @ - @;\r\n", 
+                        e2vDecl, cubeVertPos, eyePos ) );
 
     // grab connector texcoord register
     ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );

+ 2 - 1
Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp

@@ -32,7 +32,7 @@
 #include "shaderGen/HLSL/paraboloidHLSL.h"
 #include "materials/materialFeatureTypes.h"
 #include "core/module.h"
-
+#include "shaderGen/HLSL/accuFeatureHLSL.h"
 
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
 
@@ -66,6 +66,7 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
    FEATUREMGR->registerFeature( MFT_Fog, new FogFeatHLSL );
    FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapHLSL );
+   FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatHLSL );
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
    FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) );

+ 48 - 224
Engine/source/terrain/glsl/terrFeatureGLSL.cpp

@@ -379,9 +379,6 @@ 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
@@ -450,95 +447,6 @@ 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");
-       outColor->setStructName("OUT");
-	   meta->addStatement(new GenOp("   @;\r\n", outColor));
-   }
-
-   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 )
@@ -550,96 +458,7 @@ 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
+   meta->addStatement( new GenOp( "   @ += @;\r\n", blendTotal, detailBlend ) );
 
    // If we had a parallax feature... then factor in the parallax
    // amount so that it fades out with the layer blending.
@@ -676,36 +495,58 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       return;
    }
 
-   // used as texture unit num here
+   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
 
    // 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 ) );
 
-   // 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("      @ += @ * @;\r\n", outColor, detailColor, detailBlend));
+   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("         @ = (@.a * @ + @ * @) / (@ + @);\r\n", currentAlpha, bumpNorm, b1, currentAlpha, b2, b1, b2));
-   }
+   meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
+                                    outColor, outColor, baseColor, detailColor, detailBlend ) );
 
    meta->addStatement( new GenOp( "   }\r\n" ) );
 
@@ -971,9 +812,13 @@ 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("      @ += @ * @;\r\n", outColor, detailColor, detailBlend));
+   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;
@@ -1075,36 +920,15 @@ void TerrainNormalMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
 
    // create bump normal
-   // 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);
-   }
+   Var *bumpNorm = new Var;
+   bumpNorm->setName( "bumpNormal" );
+   bumpNorm->setType( "vec4" );
 
+   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 ) );
 

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

@@ -574,10 +574,6 @@ 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() )
       {
@@ -715,11 +711,6 @@ 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();

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

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

+ 1 - 5
Engine/source/terrain/terrMaterial.cpp

@@ -65,8 +65,7 @@ TerrainMaterial::TerrainMaterial()
       mMacroSize( 200.0f ),
       mMacroStrength( 0.7f ),
       mMacroDistance( 500.0f ),
-	  mParallaxScale(0.0f),
-	  mBlendDepth(0.4f)
+      mParallaxScale( 0.0f )
 {
 }
 
@@ -98,9 +97,6 @@ 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!

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

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

+ 5 - 2
Engine/source/ts/tsMesh.cpp

@@ -165,6 +165,9 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
    MeshRenderInst *coreRI = renderPass->allocInst<MeshRenderInst>();
    coreRI->type = RenderPassManager::RIT_Mesh;
 
+   // Pass accumulation texture along.
+   coreRI->accuTex = rdata.getAccuTex();
+
    const MatrixF &objToWorld = GFX->getWorldMatrix();
 
    // Sort by the center point or the bounds.
@@ -2428,7 +2431,7 @@ void TSMesh::_createVBIB( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb
             pInfo.startIndex = draw.start;
             // Use the first index to determine which 16-bit address space we are operating in
             pInfo.startVertex = indices[draw.start] & 0xFFFF0000;
-            pInfo.minIndex = pInfo.startVertex;
+            pInfo.minIndex = 0; // minIndex are zero based index relative to startVertex. See @GFXDevice
             pInfo.numVertices = getMin((U32)0x10000, mNumVerts - pInfo.startVertex);
             break;
 
@@ -2439,7 +2442,7 @@ void TSMesh::_createVBIB( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb
             pInfo.startIndex = draw.start;
             // Use the first index to determine which 16-bit address space we are operating in
             pInfo.startVertex = indices[draw.start] & 0xFFFF0000;
-            pInfo.minIndex = pInfo.startVertex;
+            pInfo.minIndex = 0; // minIndex are zero based index relative to startVertex. See @GFXDevice
             pInfo.numVertices = getMin((U32)0x10000, mNumVerts - pInfo.startVertex);
             break;
 

+ 2 - 1
Engine/source/ts/tsRenderState.cpp

@@ -33,7 +33,8 @@ TSRenderState::TSRenderState()
       mMaterialHint( NULL ),
       mCuller( NULL ),
       mLightQuery( NULL ),
-      mUseOriginSort( false )
+      mUseOriginSort( false ),
+      mAccuTex( NULL )
 {
 }
 

+ 13 - 1
Engine/source/ts/tsRenderState.h

@@ -27,7 +27,9 @@
 #include "math/mMatrix.h"
 #endif
 
-
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
 
 class SceneRenderState;
 class GFXCubemap;
@@ -103,8 +105,14 @@ protected:
    /// are forward lit and need lights.
    LightQuery *mLightQuery;
 
+   // The accumulation texture provided by an accumulation
+   // volume. This is passed down per-object.
+   GFXTextureObject* mAccuTex;
+
 public:
 
+   
+
    TSRenderState();
    TSRenderState( const TSRenderState &state );
 
@@ -147,6 +155,10 @@ public:
    void setLightQuery( LightQuery *query ) { mLightQuery = query; }
    LightQuery* getLightQuery() const { return mLightQuery; }
 
+   ///@see mAccuTex
+   void setAccuTex( GFXTextureObject* query ) { mAccuTex = query; }
+   GFXTextureObject* getAccuTex() const { return mAccuTex; }
+
    /// @}
 };
 

+ 13 - 1
Engine/source/ts/tsShapeInstance.cpp

@@ -39,7 +39,6 @@
 #include "gfx/gfxDrawUtil.h"
 #include "core/module.h"
 
-
 MODULE_BEGIN( TSShapeInstance )
 
    MODULE_INIT
@@ -783,3 +782,16 @@ void TSShapeInstance::prepCollision()
    }
 }
 
+// Returns true is the shape contains any materials with accumulation enabled.
+bool TSShapeInstance::hasAccumulation()
+{
+   bool result = false;
+   for ( U32 i = 0; i < mMaterialList->size(); ++i )
+   {
+      BaseMatInstance* mat = mMaterialList->getMaterialInst(i);
+      if ( mat->hasAccumulation() )
+         result = true;
+   }
+   return result;
+}
+

+ 6 - 0
Engine/source/ts/tsShapeInstance.h

@@ -671,6 +671,12 @@ protected:
    void *mData; ///< available for use by app...initialized to 0
 
    void prepCollision();
+
+//-------------------------------------------------------------------------------------
+// accumulation
+//-------------------------------------------------------------------------------------
+
+   bool hasAccumulation();
 };
 
 

+ 1 - 0
Engine/source/util/imposterCapture.cpp

@@ -121,6 +121,7 @@ void ImposterCaptureMaterialHook::init( BaseMatInstance *inMat )
    features.addFeature( MFT_IsDXTnm );
    features.addFeature( MFT_NormalMap );
    features.addFeature( MFT_NormalsOut );
+   features.addFeature( MFT_AccuMap );
    mNormalsMatInst = MATMGR->createMatInstance( matName );
    mNormalsMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures );
    mNormalsMatInst->init( features, inMat->getVertexFormat() );

BIN
Templates/Empty/game/art/terrains/Example/dirt_grass_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry.jpg


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry_d.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass2_n.png


BIN
Templates/Empty/game/art/terrains/Example/road_n.png


BIN
Templates/Empty/game/art/terrains/Example/rocks1_n.png


BIN
Templates/Empty/game/art/terrains/Example/rocktest_n.png


BIN
Templates/Empty/game/art/terrains/Example/sand_n.png


BIN
Templates/Empty/game/art/terrains/Example/snowtop_n.png


BIN
Templates/Empty/game/art/terrains/Example/stone_n.png


+ 0 - 225
Templates/Empty/game/art/terrains/materials.cs

@@ -20,228 +20,3 @@
 // 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";
-};

+ 9 - 10
Templates/Empty/game/core/scripts/client/audio.cs

@@ -239,27 +239,26 @@ function sfxCompareProvider( %providerA, %providerB )
       case "FMOD":
          return 1;
          
+      case "XAudio":
+         if( %providerB !$= "FMOD" )
+            return 1;
+         else
+            return -1;
+            
       // Prefer OpenAL over anything but FMOD.
       case "OpenAL":
-         if( %providerB $= "FMOD" )
+         if( %providerB $= "FMOD" && %providerB !$= "XAudio")
             return -1;
          else
             return 1;
             
-      // As long as the XAudio SFX provider still has issues,
-      // choose stable DSound over it.
+      // DSound is just about deprecated, so make that one the last fallback
       case "DirectSound":
-         if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
+         if( %providerB $= "FMOD" || %providerB $= "OpenAL" && %providerB !$= "XAudio")
             return -1;
          else
             return 0;
             
-      case "XAudio":
-         if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "DirectSound" )
-            return 1;
-         else
-            return -1;
-         
       default:
          return -1;
    }

+ 4 - 0
Templates/Empty/game/core/scripts/client/postFx/default.postfxpreset.cs

@@ -46,6 +46,10 @@ $PostFXManager::Settings::HDR::keyValue = "0.18";
 $PostFXManager::Settings::HDR::minLuminace = "0.001";
 $PostFXManager::Settings::HDR::whiteCutoff = "1";
 $PostFXManager::Settings::LightRays::brightScalar = "0.75";
+$PostFXManager::Settings::LightRays::decay = "1.0";
+$PostFXManager::Settings::LightRays::density = "0.94";
+$PostFXManager::Settings::LightRays::numSamples = "40";
+$PostFXManager::Settings::LightRays::weight = "5.65";
 $PostFXManager::Settings::SSAO::blurDepthTol = "0.001";
 $PostFXManager::Settings::SSAO::blurNormalTol = "0.95";
 $PostFXManager::Settings::SSAO::lDepthMax = "2";

+ 185 - 4
Templates/Empty/game/core/scripts/client/postFx/postFXManager.gui

@@ -1689,12 +1689,12 @@
             canSave = "1";
             canSaveDynamicFields = "0";
 
-            new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) {
+           new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) {
                range = "0 5";
                ticks = "1000";
                snap = "0";
                value = "0.75";
-               position = "96 96";
+               position = "96 46";
                extent = "264 17";
                minExtent = "8 2";
                horizSizing = "right";
@@ -1707,7 +1707,7 @@
                isContainer = "0";
                canSave = "1";
                canSaveDynamicFields = "0";
-            };
+            };			
             new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) {
                text = "Brightness";
                maxLength = "1024";
@@ -1717,7 +1717,7 @@
                anchorBottom = "0";
                anchorLeft = "1";
                anchorRight = "0";
-               position = "26 98";
+               position = "26 48";
                extent = "87 15";
                minExtent = "8 2";
                horizSizing = "right";
@@ -1732,6 +1732,187 @@
                canSave = "1";
                canSaveDynamicFields = "0";
             };
+			
+		    new GuiSliderCtrl(ppOptionsLightRaysSampleScalar) {
+               range = "20 512";
+               ticks = "512";
+               snap = "0";
+               value = "40";
+               position = "96 75";
+               extent = "264 17";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiTextCtrl(ppOptionsLightRaysSampleScalarLabel) {
+               text = "Samples";
+               maxLength = "512";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "26 76";
+               extent = "87 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               tooltip = "Controls the number of samples for the shader.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiSliderCtrl(ppOptionsLightRaysDensityScalar) {
+               range = "0.01 1";
+               ticks = "1000";
+               snap = "0";
+               value = "0.94";
+               position = "96 105";
+               extent = "264 17";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiTextCtrl(ppOptionsLightRaysDensityScalarLabel) {
+               text = "Density";
+               maxLength = "1000";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "26 106";
+               extent = "87 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               tooltip = "Controls the density of the rays.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiSliderCtrl(ppOptionsLightRaysWeightScalar) {
+               range = "0.1 10";
+               ticks = "1000";
+               snap = "0";
+               value = "5.65";
+               position = "96 135";
+               extent = "264 17";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiTextCtrl(ppOptionsLightRaysWeightScalarLabel) {
+               text = "Weight";
+               maxLength = "1000";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "26 136";
+               extent = "87 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               tooltip = "Controls the weight of the rays.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			
+			new GuiSliderCtrl(ppOptionsLightRaysDecayScalar) {
+               range = "0.01 1";
+               ticks = "1000";
+               snap = "0";
+               value = "1.0";
+               position = "96 165";
+               extent = "264 17";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+			
+			new GuiTextCtrl(ppOptionsLightRaysDecayScalarLabel) {
+               text = "Decay";
+               maxLength = "1000";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "26 166";
+               extent = "87 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               tooltip = "Controls the decay of the rays.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
             new GuiCheckBoxCtrl(ppOptionsEnableLightRays) {
                useInactiveState = "0";
                text = "Enable";

+ 26 - 1
Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.cs

@@ -301,12 +301,37 @@ function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this)
 }
 
 
-//Light rays Slider Controls
+//Light rays Brightness Slider Controls
 function ppOptionsLightRaysBrightScalar::onMouseDragged(%this)
 {
    $LightRayPostFX::brightScalar = %this.value;
    %this.ToolTip = "Value : " @ %this.value;
 }
+//Light rays Number of Samples Slider Control
+function ppOptionsLightRaysSampleScalar::onMouseDragged(%this)
+{
+   $LightRayPostFX::numSamples = %this.value;
+   %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Density Slider Control
+function ppOptionsLightRaysDensityScalar::onMouseDragged(%this)
+{
+   $LightRayPostFX::density = %this.value;
+   %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Weight Slider Control
+function ppOptionsLightRaysWeightScalar::onMouseDragged(%this)
+{
+   $LightRayPostFX::weight = %this.value;
+   %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Decay Slider Control
+function ppOptionsLightRaysDecayScalar::onMouseDragged(%this)
+{
+   $LightRayPostFX::decay = %this.value;
+   %this.ToolTip = "Value : " @ %this.value;
+}
+
 
 function ppOptionsUpdateDOFSettings()
 {

+ 15 - 0
Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs

@@ -186,6 +186,11 @@ function PostFXManager::settingsRefreshLightrays(%this)
    ppOptionsEnableLightRays.setValue($PostFXManager::PostFX::EnableLightRays);   
     
    ppOptionsLightRaysBrightScalar.setValue($LightRayPostFX::brightScalar);
+   
+   ppOptionsLightRaysSampleScalar.setValue($LightRayPostFX::numSamples);
+   ppOptionsLightRaysDensityScalar.setValue($LightRayPostFX::density);
+   ppOptionsLightRaysWeightScalar.setValue($LightRayPostFX::weight);
+   ppOptionsLightRaysDecayScalar.setValue($LightRayPostFX::decay);
 }
 
 function PostFXManager::settingsRefreshDOF(%this)
@@ -280,6 +285,11 @@ function PostFXManager::settingsApplyFromPreset(%this)
    //Light rays settings
    $LightRayPostFX::brightScalar       = $PostFXManager::Settings::LightRays::brightScalar;
    
+   $LightRayPostFX::numSamples         = $PostFXManager::Settings::LightRays::numSamples;
+   $LightRayPostFX::density            = $PostFXManager::Settings::LightRays::density;
+   $LightRayPostFX::weight             = $PostFXManager::Settings::LightRays::weight;
+   $LightRayPostFX::decay              = $PostFXManager::Settings::LightRays::decay;
+   
    //DOF settings   
    $DOFPostFx::EnableAutoFocus         = $PostFXManager::Settings::DOF::EnableAutoFocus;
    $DOFPostFx::BlurMin                 = $PostFXManager::Settings::DOF::BlurMin;
@@ -357,6 +367,11 @@ function PostFXManager::settingsApplyLightRays(%this)
 {   
    $PostFXManager::Settings::LightRays::brightScalar        = $LightRayPostFX::brightScalar;
    
+   $PostFXManager::Settings::LightRays::numSamples          = $LightRayPostFX::numSamples;
+   $PostFXManager::Settings::LightRays::density             = $LightRayPostFX::density;
+   $PostFXManager::Settings::LightRays::weight              = $LightRayPostFX::weight;
+   $PostFXManager::Settings::LightRays::decay               = $LightRayPostFX::decay;
+   
    postVerbose("% - PostFX Manager - Settings Saved - Light Rays");   
    
 }

+ 476 - 1
Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

@@ -654,7 +654,6 @@
                            bitmap = "tools/gui/images/delete";
                         };
                      };
-                  
                   };
                };
                new GuiRolloutCtrl(advancedTextureMapsRollout) {
@@ -1483,6 +1482,482 @@
                      };
                   };
                };
+               new GuiRolloutCtrl() {
+                  class = "BehaviorQuickEditRollout";
+                  superclass = LBQuickEditRollout;
+                  Profile = "GuiRolloutProfile";
+                  HorizSizing = "width";
+                  VertSizing = "bottom";
+                  Position = "0 0";
+                  Extent = "195 0";
+                  Caption = "Accumulation Properties";
+                  Margin = "-1 0 0 0";
+                  DragSizable = false;
+                  container = true;
+                  parentRollout = %this.rollout;
+                  object = %behavior;
+                  
+                  new GuiStackControl() {
+                     StackingType = "Vertical";
+                     HorizStacking = "Left to Right";
+                     VertStacking = "Top to Bottom";
+                     Padding = "0";
+                     canSaveDynamicFields = "0";
+                     Enabled = "1";
+                     isContainer = "1";
+                     Profile = "GuiDefaultProfile";
+                     HorizSizing = "width";
+                     VertSizing = "bottom";
+                     Position = "1 3";
+                     Extent = "195 16";
+                     MinExtent = "16 16";
+                     canSave = "1";
+                     isDecoy = "0";
+                     Visible = "1";
+                     tooltipprofile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     
+                     new GuiContainer(){ // enable/disable
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiCheckBoxCtrl() {
+                           canSaveDynamicFields = "0";
+                           internalName = "accuCheckbox";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "ToolsGuiCheckBoxProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 7";
+                           Extent = "57 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           Command = "MaterialEditorGui.updateAccuCheckbox($ThisControl.getValue());";
+                           tooltipprofile = "ToolsGuiDefaultProfile";
+                           ToolTip = "Enables the use of Pixel Specular for this layer.";
+                           hovertime = "1000";
+                           text = "Enable";
+                           groupNum = "-1";
+                           buttonType = "ToggleButton";
+                           useMouseEvents = "0";
+                           useInactiveState = "0";
+                        };  
+                     };
+                  
+                     new GuiContainer(){ // scale
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiTextCtrl() {
+                           canSaveDynamicFields = "0";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "GuiTextRightProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 3";
+                           Extent = "54 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           hovertime = "1000";
+                           Margin = "0 0 0 0";
+                           Padding = "0 0 0 0";
+                           AnchorTop = "1";
+                           AnchorBottom = "0";
+                           AnchorLeft = "1";
+                           AnchorRight = "0";
+                           text = "Scale";
+                           maxLength = "1024";
+                        };
+
+								new GuiControl() {
+                           class = "AggregateControl";
+                           position = "70 3";
+                           Extent = "96 20";
+                           
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuScaleSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 2";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "GuiDefaultProfile";
+                              ToolTip = "Sets the scale of the accu map.";
+                              hovertime = "1000";
+                              range = "0.03125 32";
+                              ticks = "0";
+                              value = "1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuScaleTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "1";
+                              maxLength = "3";
+                           };
+                        };
+                     };
+
+                     new GuiContainer(){ // direction
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiTextCtrl() {
+                           canSaveDynamicFields = "0";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "GuiTextRightProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 3";
+                           Extent = "54 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           hovertime = "1000";
+                           Margin = "0 0 0 0";
+                           Padding = "0 0 0 0";
+                           AnchorTop = "1";
+                           AnchorBottom = "0";
+                           AnchorLeft = "1";
+                           AnchorRight = "0";
+                           text = "Direction";
+                           maxLength = "1024";
+                        };
+
+								new GuiControl() {
+                           class = "AggregateControl";
+                           position = "70 3";
+                           Extent = "96 20";
+                           
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuDirectionSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 2";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "GuiDefaultProfile";
+                              ToolTip = "Sets the direction of the accu map.";
+                              hovertime = "1000";
+                              range = "-1 1";
+                              ticks = "0";
+                              value = "-1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuDirectionTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "-1";
+                              maxLength = "3";
+                           };
+                        };
+                     };
+                     new GuiContainer(){ // strength
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiTextCtrl() {
+                           canSaveDynamicFields = "0";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "GuiTextRightProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 3";
+                           Extent = "54 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           hovertime = "1000";
+                           Margin = "0 0 0 0";
+                           Padding = "0 0 0 0";
+                           AnchorTop = "1";
+                           AnchorBottom = "0";
+                           AnchorLeft = "1";
+                           AnchorRight = "0";
+                           text = "Strength";
+                           maxLength = "1024";
+                        };
+
+								new GuiControl() {
+                           class = "AggregateControl";
+                           position = "70 3";
+                           Extent = "96 20";
+                           
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuStrengthSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 2";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "GuiDefaultProfile";
+                              ToolTip = "Sets the strength of the accu map.";
+                              hovertime = "1000";
+                              range = "0 1";
+                              ticks = "0";
+                              value = "0.6";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuStrengthTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "0.6";
+                              maxLength = "3";
+                           };
+                        };
+                     };
+                     new GuiContainer(){ // coverage
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiTextCtrl() {
+                           canSaveDynamicFields = "0";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "GuiTextRightProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 3";
+                           Extent = "54 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           hovertime = "1000";
+                           Margin = "0 0 0 0";
+                           Padding = "0 0 0 0";
+                           AnchorTop = "1";
+                           AnchorBottom = "0";
+                           AnchorLeft = "1";
+                           AnchorRight = "0";
+                           text = "Coverage";
+                           maxLength = "1024";
+                        };
+
+								new GuiControl() {
+                           class = "AggregateControl";
+                           position = "70 3";
+                           Extent = "96 20";
+                           
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuCoverageSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 2";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "GuiDefaultProfile";
+                              ToolTip = "Sets the coverage of the accu map.";
+                              hovertime = "1000";
+                              range = "0 2";
+                              ticks = "0";
+                              value = "1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuCoverageTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "1";
+                              maxLength = "3";
+                           };
+                        };
+                     };
+                     new GuiContainer(){ // specular
+                        profile="GuiTransparentProfile";
+                        isContainer = "1";
+                        position = "0 0";
+                        Extent = "195 24";
+                        HorizSizing = "width";
+                        
+                        new GuiTextCtrl() {
+                           canSaveDynamicFields = "0";
+                           Enabled = "1";
+                           isContainer = "0";
+                           Profile = "GuiTextRightProfile";
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "8 3";
+                           Extent = "54 16";
+                           MinExtent = "8 2";
+                           canSave = "1";
+                           Visible = "1";
+                           hovertime = "1000";
+                           Margin = "0 0 0 0";
+                           Padding = "0 0 0 0";
+                           AnchorTop = "1";
+                           AnchorBottom = "0";
+                           AnchorLeft = "1";
+                           AnchorRight = "0";
+                           text = "Specular scale";
+                           maxLength = "1024";
+                        };
+
+								new GuiControl() {
+                           class = "AggregateControl";
+                           position = "70 3";
+                           Extent = "96 20";
+                           
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuSpecularSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 2";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "GuiDefaultProfile";
+                              ToolTip = "Sets the specular scale over the accu map.";
+                              hovertime = "1000";
+                              range = "0 2";
+                              ticks = "0";
+                              value = "1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "accuSpecularTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "GuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "1";
+                              maxLength = "3";
+                           };
+                        };
+                     };
+
+                  };
+               };
                new GuiRolloutCtrl() {
                   class = "BehaviorQuickEditRollout";
                   superclass = LBQuickEditRollout;

+ 21 - 0
Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs

@@ -886,6 +886,17 @@ function MaterialEditorGui::guiSync( %this, %material )
       MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] );
    }
    
+   MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]);
+   MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]);
+   MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]);
+   MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]);
+   MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]);
+   MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]);
+   MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]);
+   MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]);
+   MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]);
+   MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]);
+   
    MaterialEditorPropertiesWindow-->detailScaleTextEdit.setText( getWord((%material).detailScale[%layer], 0) );
    MaterialEditorPropertiesWindow-->detailNormalStrengthTextEdit.setText( getWord((%material).detailNormalMapStrength[%layer], 0) );
    
@@ -966,6 +977,9 @@ function MaterialEditorGui::guiSync( %this, %material )
    MaterialEditorPropertiesWindow-->SequenceSliderFPS.setValue( (%material).sequenceFramePerSec[%layer] );
    MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames );
    
+   // Accumulation
+   MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]);   
+   
    %this.preventUndo = false;
 }
 
@@ -2249,3 +2263,10 @@ function MaterialEditorMapThumbnail::onRightClick( %this )
    
    %popup.showPopup( Canvas );
 }
+
+// Accumulation
+function MaterialEditorGui::updateAccuCheckbox(%this, %value)
+{
+   MaterialEditorGui.updateActiveMaterial("accuEnabled[" @ MaterialEditorGui.currentLayer @ "]", %value);   
+   MaterialEditorGui.guiSync( materialEd_previewMaterial );
+}

+ 28 - 1
Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui

@@ -442,7 +442,7 @@ $PE_guielement_ext_colorpicker = "18 18";
                            text = "";
                         };
                      };
-                     
+                        
                      new GuiControl(){ // Spacer ----------------------------
                         isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
                         new GuiBitmapCtrl(){
@@ -543,6 +543,33 @@ $PE_guielement_ext_colorpicker = "18 18";
                            altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );";
                         };
                      };
+                     
+                     new GuiControl(){ // Particle glow
+                        isContainer = "1";
+                        HorizSizing = "width";
+                        VertSizing = "bottom";
+                        Position = $PE_guielement_pos_single_container ;
+                        Extent = $PE_guielement_ext_single_container ;
+                        
+                        new GuiTextCtrl() {
+                           Profile = "ToolsGuiTextProfile";
+                           HorizSizing = "width";
+                           VertSizing = "bottom";
+                           position = $PE_guielement_pos_name;
+                           Extent = $PE_guielement_ext_checkbox_name;
+                           text = "Glow";
+                        };
+                        new GuiCheckBoxCtrl() {
+                           internalName = "PEE_glow";
+                           Profile = "ToolsGuiCheckBoxProfile";
+                           HorizSizing = "left";
+                           VertSizing = "bottom";
+                           position = $PE_guielement_pos_checkbox;
+                           Extent = $PE_guielement_ext_checkbox;
+                           Command = "PE_EmitterEditor.updateEmitter( \"glow\", $ThisControl.getValue());";
+                           text = "";
+                        };
+                     };
                   };// end stack
                }; // end "basic" rollout
                new GuiRolloutCtrl() {

+ 2 - 0
Templates/Empty/game/tools/particleEditor/particleEmitterEditor.ed.cs

@@ -100,6 +100,8 @@ function PE_EmitterEditor::guiSync( %this )
    PE_EmitterEditor-->PEE_reverseOrder.setValue( %data.reverseOrder );
    PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes );
    PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors );
+   
+   PE_EmitterEditor-->PEE_glow.setValue( %data.glow );
 
    // Sync up particle selectors.
    

+ 5 - 51
Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui

@@ -210,7 +210,7 @@
       new GuiBitmapCtrl() {
          Enabled = "1";
          Profile = "ToolsGuiDefaultProfile";
-         position = "250 3";
+         position = "270 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 = "242 5";
+         Position = "262 5";
          Extent = "256 50";
          MinExtent = "8 2";
          canSave = "1";
@@ -370,7 +370,7 @@
       new GuiBitmapCtrl() {
          Enabled = "1";
          Profile = "ToolsGuiDefaultProfile";
-         position = "495 3";
+         position = "525 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 = "510 5";
+         position = "540 5";
          Extent = "120 50";
          MinExtent = "8 2";
          canSave = "1";
@@ -454,53 +454,6 @@
             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 ---
@@ -681,3 +634,4 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) {
       value = "0";
    };
 };
+

+ 10 - 82
Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui

@@ -20,8 +20,8 @@
       HorizSizing = "center";
       VertSizing = "center";
       position = "221 151";
-      Extent = "394 452";
-      MinExtent = "358 452";
+      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 383";
+         Extent = "185 363";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -439,7 +439,7 @@
             HorizSizing = "width";
             VertSizing = "bottom";
             position = "6 295";
-            Extent = "185 80";
+            Extent = "185 50";
             MinExtent = "8 2";
             canSave = "1";
             Visible = "1";
@@ -621,78 +621,6 @@
                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() {
@@ -1332,7 +1260,7 @@
          HorizSizing = "width";
          VertSizing = "height";
          position = "6 42";
-         Extent = "189 393";
+         Extent = "189 373";
          MinExtent = "8 2";
          canSave = "1";
          Visible = "1";
@@ -1346,7 +1274,7 @@
             HorizSizing = "width";
             VertSizing = "height";
             position = "0 0";
-            Extent = "189 394";
+            Extent = "189 374";
             MinExtent = "8 2";
             canSave = "1";
             Visible = "1";
@@ -1405,7 +1333,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "202 414";
+         position = "202 394";
          Extent = "98 22";
          MinExtent = "8 2";
          canSave = "1";
@@ -1424,7 +1352,7 @@
          Profile = "ToolsGuiButtonProfile";
          HorizSizing = "left";
          VertSizing = "top";
-         position = "307 414";
+         position = "307 394";
          Extent = "80 22";
          MinExtent = "8 2";
          canSave = "1";
@@ -1444,7 +1372,7 @@
          HorizSizing = "left";
          VertSizing = "height";
          position = "199 23";
-         Extent = "190 287";
+         Extent = "190 267";
          isContainer = true;
          Visible = false;
          bitmap = "tools/gui/images/inactive-overlay";
@@ -1461,4 +1389,4 @@
       };
    };
 };
-//--- OBJECT WRITE END ---
+//--- OBJECT WRITE END ---

+ 1 - 0
Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs

@@ -83,6 +83,7 @@ function EWCreatorWindow::init( %this )
       %this.registerMissionObject( "SpawnSphere",  "Observer Spawn Sphere", "ObserverDropPoint" );
       %this.registerMissionObject( "SFXSpace",      "Sound Space" );
       %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" );
+      %this.registerMissionObject( "AccumulationVolume", "Accumulation Volume" );
       %this.registerMissionObject("NavMesh", "Navigation mesh");
       %this.registerMissionObject("NavPath", "Path");
       

+ 0 - 7
Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs

@@ -222,8 +222,6 @@ function EPainter::setup( %this, %matIndex )
    ETerrainEditor.setAction( ETerrainEditor.currentAction );
    EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc);
    ETerrainEditor.renderVertexSelection = true;
-   
-   EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend);
 }
 
 function onNeedRelight()
@@ -259,11 +257,6 @@ 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();

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