Torque3D Documentation / _generateds / scenePolyhedralObject.impl.h

scenePolyhedralObject.impl.h

Engine/source/scene/mixin/scenePolyhedralObject.impl.h

More...

Detailed Description

  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#ifndef _SCENEPOLYHEDRALOBJECT_IMPL_H_
 24#define _SCENEPOLYHEDRALOBJECT_IMPL_H_
 25
 26#include "platform/platform.h"
 27#include "scene/mixin/scenePolyhedralObject.h"
 28
 29#include "console/consoleTypes.h"
 30#include "gfx/gfxDrawUtil.h"
 31#include "gfx/gfxTransformSaver.h"
 32#include "core/stream/bitStream.h"
 33#include "math/mathIO.h"
 34
 35#if 0 // Enable when enabling debug rendering below.
 36#include "scene/sceneRenderState.h"
 37#include "gfx/sim/debugDraw.h"
 38#endif
 39
 40
 41//-----------------------------------------------------------------------------
 42
 43template< typename Base, typename P >
 44void ScenePolyhedralObject< Base, P >::initPersistFields()
 45{
 46   Parent::addGroup( "Internal" );
 47
 48      Parent::addProtectedField( "plane", TypeRealString, NULL,
 49         &_setPlane, &defaultProtectedGetFn,
 50         "For internal use only.",
 51         AbstractClassRep::FIELD_HideInInspectors );
 52      Parent::addProtectedField( "point", TypeRealString, NULL,
 53         &_setPoint, &defaultProtectedGetFn,
 54         "For internal use only.",
 55         AbstractClassRep::FIELD_HideInInspectors );
 56      Parent::addProtectedField( "edge", TypeRealString, NULL,
 57         &_setEdge, &defaultProtectedGetFn,
 58         "For internal use only.",
 59         AbstractClassRep::FIELD_HideInInspectors );
 60
 61   Parent::endGroup( "Internal" );
 62
 63   Parent::initPersistFields();
 64}
 65
 66//-----------------------------------------------------------------------------
 67
 68template< typename Base, typename P >
 69bool ScenePolyhedralObject< Base, P >::onAdd()
 70{
 71   // If no polyhedron has been initialized for the zone, default
 72   // to object box.  Do this before calling the parent's onAdd()
 73   // so that we set the object box correctly.
 74
 75   if( mPolyhedron.getNumPlanes() == 0 )
 76   {
 77      mPolyhedron.buildBox( MatrixF::Identity, this->getObjBox() );
 78      mIsBox = true;
 79   }
 80   else
 81   {
 82      mIsBox = false;
 83
 84      // Compute object-space bounds from polyhedron.
 85      this->mObjBox = mPolyhedron.getBounds();
 86   }
 87   
 88   if( !Parent::onAdd() )
 89      return false;
 90
 91   return true;
 92}
 93
 94//-----------------------------------------------------------------------------
 95
 96template< typename Base, typename P >
 97bool ScenePolyhedralObject< Base, P >::containsPoint( const Point3F& point )
 98{
 99   // If our shape is the OBB, use the default implementation
100   // inherited from SceneObject.
101
102   if( this->mIsBox )
103      return Parent::containsPoint( point );
104
105   // Take the point into our local object space.
106
107   Point3F p = point;
108   this->getWorldTransform().mulP( p );
109   p.convolveInverse( this->getScale() );
110
111   // See if the polyhedron contains the point.
112
113   return mPolyhedron.isContained( p );
114}
115
116//-----------------------------------------------------------------------------
117
118template< typename Base, typename P >
119void ScenePolyhedralObject< Base, P >::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat )
120{
121   if( overrideMat )
122      return;
123
124   if( this->mIsBox )
125      Parent::_renderObject( ri, state, overrideMat );
126   else if( !this->mEditorRenderMaterial )
127   {
128      GFXTransformSaver saver;
129
130      MatrixF mat = this->getRenderTransform();
131      mat.scale( this->getScale() );
132
133      GFX->multWorld( mat );
134
135      GFXStateBlockDesc desc;
136      desc.setZReadWrite( true, false );
137      desc.setBlend( true );
138      desc.setCullMode( GFXCullNone );
139
140      GFX->getDrawUtil()->drawPolyhedron( desc, mPolyhedron, this->_getDefaultEditorSolidColor() );
141
142      // Render black wireframe.
143
144      desc.setFillModeWireframe();
145      GFX->getDrawUtil()->drawPolyhedron( desc, mPolyhedron, this->_getDefaultEditorWireframeColor() );
146   }
147   else
148   {
149      //TODO: render polyhedron with material
150   }
151
152   // Debug rendering.
153
154   #if 0
155   if( state->isDiffusePass() )
156      drawPolyhedronDebugInfo( mPolyhedron, this->getTransform(), this->getScale() );
157   #endif
158}
159
160//-----------------------------------------------------------------------------
161
162template< typename Base, typename P >
163U32 ScenePolyhedralObject< Base, P >::packUpdate( NetConnection* connection, U32 mask, BitStream* stream )
164{
165   U32 retMask = Parent::packUpdate( connection, mask, stream );
166
167   if( stream->writeFlag( !mIsBox && ( mask & PolyMask ) ) )
168   {
169      // Write planes.
170
171      const U32 numPlanes = mPolyhedron.getNumPlanes();
172      const typename PolyhedronType::PlaneType* planes = mPolyhedron.getPlanes();
173
174      stream->writeInt( numPlanes, 8 );
175      for( U32 i = 0; i < numPlanes; ++ i )
176         mathWrite( *stream, planes[ i ] );
177
178      // Write points.
179
180      const U32 numPoints = mPolyhedron.getNumPoints();
181      const typename PolyhedronType::PointType* points = mPolyhedron.getPoints();
182
183      stream->writeInt( numPoints, 8 );
184      for( U32 i = 0; i < numPoints; ++ i )
185         mathWrite( *stream, points[ i ] );
186
187      // Write edges.
188
189      const U32 numEdges = mPolyhedron.getNumEdges();
190      const typename PolyhedronType::EdgeType* edges = mPolyhedron.getEdges();
191
192      stream->writeInt( numEdges, 8 );
193      for( U32 i = 0; i < numEdges; ++ i )
194      {
195         const typename PolyhedronType::EdgeType& edge = edges[ i ];
196
197         stream->writeInt( edge.face[ 0 ], 8 );
198         stream->writeInt( edge.face[ 1 ], 8 );
199         stream->writeInt( edge.vertex[ 0 ], 8 );
200         stream->writeInt( edge.vertex[ 1 ], 8 );
201      }
202   }
203
204   return retMask;
205}
206
207//-----------------------------------------------------------------------------
208
209template< typename Base, typename P >
210void ScenePolyhedralObject< Base, P >::unpackUpdate( NetConnection* connection, BitStream* stream )
211{
212   Parent::unpackUpdate( connection, stream );
213
214   if( stream->readFlag() )  // PolyMask
215   {
216      // Read planes.
217
218      const U32 numPlanes = stream->readInt( 8 );
219      mPolyhedron.mPlaneList.setSize( numPlanes );
220
221      for( U32 i = 0; i < numPlanes; ++ i )
222         mathRead( *stream, &mPolyhedron.mPlaneList[ i ] );
223
224      // Read points.
225
226      const U32 numPoints = stream->readInt( 8 );
227      mPolyhedron.mPointList.setSize( numPoints );
228
229      for( U32 i = 0; i < numPoints; ++ i )
230         mathRead( *stream, &mPolyhedron.mPointList[ i ] );
231
232      // Read edges.
233
234      const U32 numEdges = stream->readInt( 8 );
235      mPolyhedron.mEdgeList.setSize( numEdges );
236
237      for( U32 i = 0; i < numEdges; ++ i )
238      {
239         typename PolyhedronType::EdgeType& edge = mPolyhedron.mEdgeList[ i ];
240
241         edge.face[ 0 ] = stream->readInt( 8 );
242         edge.face[ 1 ] = stream->readInt( 8 );
243         edge.vertex[ 0 ] = stream->readInt( 8 );
244         edge.vertex[ 1 ] = stream->readInt( 8 );
245      }
246   }
247}
248
249//-----------------------------------------------------------------------------
250
251template< typename Base, typename P >
252bool ScenePolyhedralObject< Base, P >::writeField( StringTableEntry name, const char* value )
253{
254   StringTableEntry sPlane = StringTable->insert( "plane" );
255   StringTableEntry sPoint = StringTable->insert( "point" );
256   StringTableEntry sEdge = StringTable->insert( "edge" );
257
258   if( name == sPlane || name == sPoint || name == sEdge )
259      return false;
260
261   return Parent::writeField( name, value );
262}
263
264//-----------------------------------------------------------------------------
265
266template< typename Base, typename P >
267void ScenePolyhedralObject< Base, P >::writeFields( Stream& stream, U32 tabStop )
268{
269   Parent::writeFields( stream, tabStop );
270
271   // If the polyhedron is the same as our object box,
272   // don't bother writing out the planes and points.
273
274   if( mIsBox )
275      return;
276
277   stream.write( 2, "\r\n" );
278
279   // Write all planes.
280   
281   const U32 numPlanes = mPolyhedron.getNumPlanes();
282   for( U32 i = 0; i < numPlanes; ++ i )
283   {
284      const PlaneF& plane = mPolyhedron.getPlanes()[ i ];
285
286      stream.writeTabs( tabStop );
287
288      char buffer[ 1024 ];
289      dSprintf( buffer, sizeof( buffer ), "plane = \"%g %g %g %g\";",
290         plane.x, plane.y, plane.z, plane.d
291      );
292
293      stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
294   }
295
296   // Write all points.
297
298   const U32 numPoints = mPolyhedron.getNumPoints();
299   for( U32 i = 0; i < numPoints; ++ i )
300   {
301      const Point3F& point = mPolyhedron.getPoints()[ i ];
302
303      stream.writeTabs( tabStop );
304
305      char buffer[ 1024 ];
306      dSprintf( buffer, sizeof( buffer ), "point = \"%g %g %g\";",
307         point.x, point.y, point.z
308      );
309
310      stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
311   }
312
313   // Write all edges.
314
315   const U32 numEdges = mPolyhedron.getNumEdges();
316   for( U32 i = 0; i < numEdges; ++ i )
317   {
318      const PolyhedronData::Edge& edge = mPolyhedron.getEdges()[ i ];
319
320      stream.writeTabs( tabStop );
321
322      char buffer[ 1024 ];
323      dSprintf( buffer, sizeof( buffer ), "edge = \"%i %i %i %i\";",
324         edge.face[ 0 ], edge.face[ 1 ],
325         edge.vertex[ 0 ], edge.vertex[ 1 ]
326      );
327
328      stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
329   }
330}
331
332//-----------------------------------------------------------------------------
333
334template< typename Base, typename P >
335bool ScenePolyhedralObject< Base, P >::_setPlane( void* object, const char* index, const char* data )
336{
337   ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
338
339   PlaneF plane;
340
341   dSscanf( data, "%g %g %g %g",
342      &plane.x,
343      &plane.y,
344      &plane.z,
345      &plane.d
346   );
347
348   obj->mPolyhedron.mPlaneList.push_back( plane );
349   obj->setMaskBits( PolyMask );
350   obj->mIsBox = false;
351
352   return false;
353}
354
355//-----------------------------------------------------------------------------
356
357template< typename Base, typename P >
358bool ScenePolyhedralObject< Base, P >::_setPoint( void* object, const char* index, const char* data )
359{
360   ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
361
362   Point3F point;
363
364   dSscanf( data, "%g %g %g %g",
365      &point[ 0 ],
366      &point[ 1 ],
367      &point[ 2 ]
368   );
369
370   obj->mPolyhedron.mPointList.push_back( point );
371   obj->setMaskBits( PolyMask );
372   obj->mIsBox = false;
373
374   return false;
375}
376
377//-----------------------------------------------------------------------------
378
379template< typename Base, typename P >
380bool ScenePolyhedralObject< Base, P >::_setEdge( void* object, const char* index, const char* data )
381{
382   ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
383
384   PolyhedronData::Edge edge;
385
386   dSscanf( data, "%i %i %i %i",
387      &edge.face[ 0 ],
388      &edge.face[ 1 ],
389      &edge.vertex[ 0 ],
390      &edge.vertex[ 1 ]
391   );
392
393   obj->mPolyhedron.mEdgeList.push_back( edge );
394   obj->setMaskBits( PolyMask );
395   obj->mIsBox = false;
396
397   return false;
398}
399
400#endif // _SCENEPOLYHEDRALOBJECT_IMPL_H_
401