Torque3D Documentation / _generateds / accumulationVolume.cpp

accumulationVolume.cpp

Engine/source/T3D/accumulationVolume.cpp

More...

Public Variables

Public Functions

ConsoleDocClass(AccumulationVolume , "@brief An invisible shape that allow objects within it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have an accumulation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map.\n\n</a>" "<a href="/coding/class/classaccumulationvolume/">AccumulationVolume</a> is used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add additional realism <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scene. It's <a href="/coding/file/x86unixmain_8cpp/#x86unixmain_8cpp_1a217dbf8b442f20279ea00b898af96f52">main</a> use is in outdoor scenes " " where objects could benefit from overlaying environment accumulation textures such as sand, snow , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n\n</a>" "Objects within the volume must have accumulation enabled in their material. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup enviroMisc" )

Detailed Description

Public Variables

GFXTexHandle gLevelAccuMap 

Public Functions

ConsoleDocClass(AccumulationVolume , "@brief An invisible shape that allow objects within it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have an accumulation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map.\n\n</a>" "<a href="/coding/class/classaccumulationvolume/">AccumulationVolume</a> is used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add additional realism <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scene. It's <a href="/coding/file/x86unixmain_8cpp/#x86unixmain_8cpp_1a217dbf8b442f20279ea00b898af96f52">main</a> use is in outdoor scenes " " where objects could benefit from overlaying environment accumulation textures such as sand, snow , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n\n</a>" "Objects within the volume must have accumulation enabled in their material. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup enviroMisc" )

IMPLEMENT_CO_NETOBJECT_V1(AccumulationVolume )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "T3D/accumulationVolume.h"
 26
 27#include "scene/sceneManager.h"
 28#include "scene/sceneRenderState.h"
 29#include "gfx/gfxDevice.h"
 30#include "gfx/gfxDrawUtil.h"
 31#include "gfx/sim/debugDraw.h"
 32#include "util/tempAlloc.h"
 33#include "materials/materialDefinition.h"
 34#include "materials/materialManager.h"
 35#include "materials/materialFeatureTypes.h"
 36#include "materials/matInstance.h"
 37#include "console/consoleTypes.h"
 38#include "core/stream/bitStream.h"
 39#include "gfx/gfxDevice.h"
 40#include "console/console.h"
 41#include "console/engineAPI.h"
 42#include "gfx/gfxTextureHandle.h"
 43#include "scene/sceneContainer.h"
 44
 45#include "math/mPolyhedron.impl.h"
 46
 47Vector< SimObjectPtr<SceneObject> > AccumulationVolume::smAccuObjects;
 48Vector< SimObjectPtr<AccumulationVolume> > AccumulationVolume::smAccuVolumes;
 49
 50GFXTexHandle gLevelAccuMap;
 51
 52//#define DEBUG_DRAW
 53
 54IMPLEMENT_CO_NETOBJECT_V1( AccumulationVolume );
 55
 56ConsoleDocClass( AccumulationVolume,
 57   "@brief An invisible shape that allow objects within it to have an accumulation map.\n\n"
 58
 59   "AccumulationVolume is used to add additional realism to a scene. It's main use is in outdoor scenes "
 60   " where objects could benefit from overlaying environment accumulation textures such as sand, snow, etc.\n\n"
 61
 62   "Objects within the volume must have accumulation enabled in their material. \n\n"
 63
 64   "@ingroup enviroMisc"
 65);
 66
 67//-----------------------------------------------------------------------------
 68
 69AccumulationVolume::AccumulationVolume()
 70   : mTransformDirty( true ),
 71     mSilhouetteExtractor( mPolyhedron )
 72{
 73   VECTOR_SET_ASSOCIATION( mWSPoints );
 74   VECTOR_SET_ASSOCIATION( mVolumeQueryList );
 75
 76   //mObjectFlags.set( VisualOccluderFlag );
 77   
 78   mNetFlags.set( Ghostable | ScopeAlways );
 79   mObjScale.set( 1.f, 1.f, 1.f );
 80   mObjBox.set(
 81      Point3F( -0.5f, -0.5f, -0.5f ),
 82      Point3F( 0.5f, 0.5f, 0.5f )
 83   );
 84
 85   mObjToWorld.identity();
 86   mWorldToObj.identity();
 87
 88   // Accumulation Texture.
 89   mTextureName = "";
 90   mAccuTexture = NULL;
 91
 92   resetWorldBox();
 93}
 94
 95AccumulationVolume::~AccumulationVolume()
 96{
 97   mAccuTexture = NULL;
 98}
 99
100void AccumulationVolume::initPersistFields()
101{
102   addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
103         &_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
104
105   Parent::initPersistFields();
106}
107
108//-----------------------------------------------------------------------------
109
110void AccumulationVolume::consoleInit()
111{
112   // Disable rendering of occlusion volumes by default.
113   getStaticClassRep()->mIsRenderEnabled = false;
114}
115
116//-----------------------------------------------------------------------------
117
118bool AccumulationVolume::onAdd()
119{
120   if( !Parent::onAdd() )
121      return false;
122
123   // Prepare some client side things.
124   if ( isClientObject() )  
125   {
126      smAccuVolumes.push_back(this);
127      refreshVolumes();
128   }
129
130   // Set up the silhouette extractor.
131   mSilhouetteExtractor = SilhouetteExtractorType( mPolyhedron );
132
133   return true;
134}
135
136void AccumulationVolume::onRemove()
137{
138   if ( isClientObject() )  
139   {
140      smAccuVolumes.remove(this);
141      refreshVolumes();
142   }
143   Parent::onRemove();
144}
145
146//-----------------------------------------------------------------------------
147
148void AccumulationVolume::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat )
149{
150   Parent::_renderObject( ri, state, overrideMat );
151
152   #ifdef DEBUG_DRAW
153   if( state->isDiffusePass() )
154      DebugDrawer::get()->drawPolyhedronDebugInfo( mPolyhedron, getTransform(), getScale() );
155   #endif
156}
157
158//-----------------------------------------------------------------------------
159
160void AccumulationVolume::setTransform( const MatrixF& mat )
161{
162   Parent::setTransform( mat );
163   mTransformDirty = true;
164   refreshVolumes();
165}
166
167//-----------------------------------------------------------------------------
168
169void AccumulationVolume::buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F>& outPoints )
170{
171   // Extract the silhouette of the polyhedron.  This works differently
172   // depending on whether we project orthogonally or in perspective.
173
174   TempAlloc< U32> indices( mPolyhedron.getNumPoints() );
175   U32 numPoints;
176
177   if( cameraState.getFrustum().isOrtho() )
178   {
179      // Transform the view direction into object space.
180
181      Point3F osViewDir;
182      getWorldTransform().mulV( cameraState.getViewDirection(), &osViewDir );
183
184      // And extract the silhouette.
185
186      SilhouetteExtractorOrtho< PolyhedronType> extractor( mPolyhedron );
187      numPoints = extractor.extractSilhouette( osViewDir, indices, indices.size );
188   }
189   else
190   {
191      // Create a transform to go from view space to object space.
192
193      MatrixF camView( true );
194      camView.scale( Point3F( 1.0f / getScale().x, 1.0f / getScale().y, 1.0f / getScale().z ) );
195      camView.mul( getRenderWorldTransform() );
196      camView.mul( cameraState.getViewWorldMatrix() );
197
198      // Do a perspective-correct silhouette extraction.
199
200      numPoints = mSilhouetteExtractor.extractSilhouette(
201         camView,
202         indices, indices.size );
203   }
204
205   // If we haven't yet, transform the polyhedron's points
206   // to world space.
207
208   if( mTransformDirty )
209   {
210      const U32 numPolyPoints = mPolyhedron.getNumPoints();
211      const PolyhedronType::PointType* points = getPolyhedron().getPoints();
212
213      mWSPoints.setSize(numPolyPoints);
214      for( U32 i = 0; i < numPolyPoints; ++ i )
215      {
216         Point3F p = points[ i ];
217         p.convolve( getScale() );
218         getTransform().mulP( p, &mWSPoints[ i ] );
219      }
220
221      mTransformDirty = false;
222   }
223
224   // Now store the points.
225
226   outPoints.setSize( numPoints );
227   for( U32 i = 0; i < numPoints; ++ i )
228      outPoints[ i ] = mWSPoints[ indices[ i ] ];
229}
230
231//-----------------------------------------------------------------------------
232
233U32 AccumulationVolume::packUpdate( NetConnection *connection, U32 mask, BitStream *stream )
234{
235   U32 retMask = Parent::packUpdate( connection, mask, stream );
236
237   if (stream->writeFlag(mask & InitialUpdateMask))
238   {
239      stream->write( mTextureName );
240   }
241
242   return retMask;  
243}
244
245void AccumulationVolume::unpackUpdate( NetConnection *connection, BitStream *stream )
246{
247   Parent::unpackUpdate( connection, stream );
248
249   if (stream->readFlag())
250   {
251      stream->read( &mTextureName );
252      setTexture(mTextureName);
253   }
254}
255
256//-----------------------------------------------------------------------------
257
258void AccumulationVolume::inspectPostApply()
259{
260   Parent::inspectPostApply();
261   setMaskBits(U32(-1) );
262}
263
264void AccumulationVolume::setTexture( const String& name )
265{
266   mTextureName = name;
267   if ( isClientObject() && mTextureName.isNotEmpty() )
268   {
269      mAccuTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
270      if ( mAccuTexture.isNull() )
271         Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
272   }
273   refreshVolumes();
274}
275
276//-----------------------------------------------------------------------------
277// Static Functions
278//-----------------------------------------------------------------------------
279bool AccumulationVolume::_setTexture( void *object, const char *index, const char *data )
280{
281   AccumulationVolume* volume = reinterpret_cast< AccumulationVolume* >( object );
282   volume->setTexture( data );
283   return false;
284}
285
286void AccumulationVolume::refreshVolumes()
287{
288   // This function tests each accumulation object to
289   // see if it's within the bounds of an accumulation
290   // volume. If so, it will pass on the accumulation
291   // texture of the volume to the object.
292
293   // This function should only be called when something
294   // global like change of volume or material occurs.
295
296   // Clear old data.
297   for (S32 n = 0; n < smAccuObjects.size(); ++n)
298   {
299      SimObjectPtr<SceneObject> object = smAccuObjects[n];
300      if ( object.isValid() )
301         object->mAccuTex = gLevelAccuMap;
302   }
303
304   // 
305   for (S32 i = 0; i < smAccuVolumes.size(); ++i)
306   {
307      SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
308      if ( volume.isNull() ) continue;
309
310      for (S32 n = 0; n < smAccuObjects.size(); ++n)
311      {
312         SimObjectPtr<SceneObject> object = smAccuObjects[n];
313         if ( object.isNull() ) continue;
314
315         if ( volume->containsPoint(object->getPosition()) )
316            object->mAccuTex = volume->mAccuTexture;
317      }
318   }
319}
320
321// Accumulation Object Management.
322void AccumulationVolume::addObject(SimObjectPtr<SceneObject> object)
323{
324   smAccuObjects.push_back(object);
325   refreshVolumes();
326}
327
328void AccumulationVolume::removeObject(SimObjectPtr<SceneObject> object)
329{
330   smAccuObjects.remove(object);
331   refreshVolumes();
332}
333
334void AccumulationVolume::updateObject(SceneObject* object)
335{
336   // This function is called when an individual object
337   // has been moved. Tests to see if it's in any of the
338   // accumulation volumes.
339
340   // We use ZERO instead of NULL so the accumulation
341   // texture will be updated in renderMeshMgr.
342   object->mAccuTex = gLevelAccuMap;
343
344   for (S32 i = 0; i < smAccuVolumes.size(); ++i)
345   {
346      SimObjectPtr<AccumulationVolume> volume = smAccuVolumes[i];
347      if ( volume.isNull() ) continue;
348
349      if ( volume->containsPoint(object->getPosition()) )
350         object->mAccuTex = volume->mAccuTexture;
351   }
352}
353