scenePolyhedralObject.impl.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SCENEPOLYHEDRALOBJECT_IMPL_H_
  23. #define _SCENEPOLYHEDRALOBJECT_IMPL_H_
  24. #include "platform/platform.h"
  25. #include "scene/mixin/scenePolyhedralObject.h"
  26. #include "console/consoleTypes.h"
  27. #include "gfx/gfxDrawUtil.h"
  28. #include "gfx/gfxTransformSaver.h"
  29. #include "core/stream/bitStream.h"
  30. #include "math/mathIO.h"
  31. #if 0 // Enable when enabling debug rendering below.
  32. #include "scene/sceneRenderState.h"
  33. #include "gfx/sim/debugDraw.h"
  34. #endif
  35. //-----------------------------------------------------------------------------
  36. template< typename Base, typename P >
  37. void ScenePolyhedralObject< Base, P >::initPersistFields()
  38. {
  39. Parent::addGroup( "Internal" );
  40. Parent::addProtectedField( "plane", TypeRealString, 0,
  41. &_setPlane, &defaultProtectedGetFn,
  42. "For internal use only.",
  43. AbstractClassRep::FIELD_HideInInspectors );
  44. Parent::addProtectedField( "point", TypeRealString, 0,
  45. &_setPoint, &defaultProtectedGetFn,
  46. "For internal use only.",
  47. AbstractClassRep::FIELD_HideInInspectors );
  48. Parent::addProtectedField( "edge", TypeRealString, 0,
  49. &_setEdge, &defaultProtectedGetFn,
  50. "For internal use only.",
  51. AbstractClassRep::FIELD_HideInInspectors );
  52. Parent::endGroup( "Internal" );
  53. Parent::initPersistFields();
  54. }
  55. //-----------------------------------------------------------------------------
  56. template< typename Base, typename P >
  57. bool ScenePolyhedralObject< Base, P >::onAdd()
  58. {
  59. // If no polyhedron has been initialized for the zone, default
  60. // to object box. Do this before calling the parent's onAdd()
  61. // so that we set the object box correctly.
  62. if( mPolyhedron.getNumPlanes() == 0 )
  63. {
  64. mPolyhedron.buildBox( MatrixF::Identity, this->getObjBox() );
  65. mIsBox = true;
  66. }
  67. else
  68. {
  69. mIsBox = false;
  70. // Compute object-space bounds from polyhedron.
  71. this->mObjBox = mPolyhedron.getBounds();
  72. }
  73. if( !Parent::onAdd() )
  74. return false;
  75. return true;
  76. }
  77. //-----------------------------------------------------------------------------
  78. template< typename Base, typename P >
  79. bool ScenePolyhedralObject< Base, P >::containsPoint( const Point3F& point )
  80. {
  81. // If our shape is the OBB, use the default implementation
  82. // inherited from SceneObject.
  83. if( this->mIsBox )
  84. return Parent::containsPoint( point );
  85. // Take the point into our local object space.
  86. Point3F p = point;
  87. this->getWorldTransform().mulP( p );
  88. p.convolveInverse( this->getScale() );
  89. // See if the polyhedron contains the point.
  90. return mPolyhedron.isContained( p );
  91. }
  92. //-----------------------------------------------------------------------------
  93. template< typename Base, typename P >
  94. void ScenePolyhedralObject< Base, P >::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat )
  95. {
  96. if( overrideMat )
  97. return;
  98. if( this->mIsBox )
  99. Parent::_renderObject( ri, state, overrideMat );
  100. else if( !this->mEditorRenderMaterial )
  101. {
  102. GFXTransformSaver saver;
  103. MatrixF mat = this->getRenderTransform();
  104. mat.scale( this->getScale() );
  105. GFX->multWorld( mat );
  106. GFXStateBlockDesc desc;
  107. desc.setZReadWrite( true, false );
  108. desc.setBlend( true );
  109. desc.setCullMode( GFXCullNone );
  110. GFX->getDrawUtil()->drawPolyhedron( desc, mPolyhedron, this->_getDefaultEditorSolidColor() );
  111. // Render black wireframe.
  112. desc.setFillModeWireframe();
  113. GFX->getDrawUtil()->drawPolyhedron( desc, mPolyhedron, this->_getDefaultEditorWireframeColor() );
  114. }
  115. else
  116. {
  117. //TODO: render polyhedron with material
  118. }
  119. // Debug rendering.
  120. #if 0
  121. if( state->isDiffusePass() )
  122. DebugDrawer::get()->drawPolyhedronDebugInfo( mPolyhedron, this->getTransform(), this->getScale() );
  123. #endif
  124. }
  125. //-----------------------------------------------------------------------------
  126. template< typename Base, typename P >
  127. U32 ScenePolyhedralObject< Base, P >::packUpdate( NetConnection* connection, U32 mask, BitStream* stream )
  128. {
  129. U32 retMask = Parent::packUpdate( connection, mask, stream );
  130. if( stream->writeFlag( !mIsBox && ( mask & PolyMask ) ) )
  131. {
  132. // Write planes.
  133. const U32 numPlanes = mPolyhedron.getNumPlanes();
  134. const typename PolyhedronType::PlaneType* planes = mPolyhedron.getPlanes();
  135. stream->writeInt( numPlanes, 8 );
  136. for( U32 i = 0; i < numPlanes; ++ i )
  137. mathWrite( *stream, planes[ i ] );
  138. // Write points.
  139. const U32 numPoints = mPolyhedron.getNumPoints();
  140. const typename PolyhedronType::PointType* points = mPolyhedron.getPoints();
  141. stream->writeInt( numPoints, 8 );
  142. for( U32 i = 0; i < numPoints; ++ i )
  143. mathWrite( *stream, points[ i ] );
  144. // Write edges.
  145. const U32 numEdges = mPolyhedron.getNumEdges();
  146. const typename PolyhedronType::EdgeType* edges = mPolyhedron.getEdges();
  147. stream->writeInt( numEdges, 8 );
  148. for( U32 i = 0; i < numEdges; ++ i )
  149. {
  150. const typename PolyhedronType::EdgeType& edge = edges[ i ];
  151. stream->writeInt( edge.face[ 0 ], 8 );
  152. stream->writeInt( edge.face[ 1 ], 8 );
  153. stream->writeInt( edge.vertex[ 0 ], 8 );
  154. stream->writeInt( edge.vertex[ 1 ], 8 );
  155. }
  156. }
  157. return retMask;
  158. }
  159. //-----------------------------------------------------------------------------
  160. template< typename Base, typename P >
  161. void ScenePolyhedralObject< Base, P >::unpackUpdate( NetConnection* connection, BitStream* stream )
  162. {
  163. Parent::unpackUpdate( connection, stream );
  164. if( stream->readFlag() ) // PolyMask
  165. {
  166. // Read planes.
  167. const U32 numPlanes = stream->readInt( 8 );
  168. mPolyhedron.mPlaneList.setSize( numPlanes );
  169. for( U32 i = 0; i < numPlanes; ++ i )
  170. mathRead( *stream, &mPolyhedron.mPlaneList[ i ] );
  171. // Read points.
  172. const U32 numPoints = stream->readInt( 8 );
  173. mPolyhedron.mPointList.setSize( numPoints );
  174. for( U32 i = 0; i < numPoints; ++ i )
  175. mathRead( *stream, &mPolyhedron.mPointList[ i ] );
  176. // Read edges.
  177. const U32 numEdges = stream->readInt( 8 );
  178. mPolyhedron.mEdgeList.setSize( numEdges );
  179. for( U32 i = 0; i < numEdges; ++ i )
  180. {
  181. typename PolyhedronType::EdgeType& edge = mPolyhedron.mEdgeList[ i ];
  182. edge.face[ 0 ] = stream->readInt( 8 );
  183. edge.face[ 1 ] = stream->readInt( 8 );
  184. edge.vertex[ 0 ] = stream->readInt( 8 );
  185. edge.vertex[ 1 ] = stream->readInt( 8 );
  186. }
  187. }
  188. }
  189. //-----------------------------------------------------------------------------
  190. template< typename Base, typename P >
  191. bool ScenePolyhedralObject< Base, P >::writeField( StringTableEntry name, const char* value )
  192. {
  193. StringTableEntry sPlane = StringTable->insert( "plane" );
  194. StringTableEntry sPoint = StringTable->insert( "point" );
  195. StringTableEntry sEdge = StringTable->insert( "edge" );
  196. if( name == sPlane || name == sPoint || name == sEdge )
  197. return false;
  198. return Parent::writeField( name, value );
  199. }
  200. //-----------------------------------------------------------------------------
  201. template< typename Base, typename P >
  202. void ScenePolyhedralObject< Base, P >::writeFields( Stream& stream, U32 tabStop )
  203. {
  204. Parent::writeFields( stream, tabStop );
  205. // If the polyhedron is the same as our object box,
  206. // don't bother writing out the planes and points.
  207. if( mIsBox )
  208. return;
  209. stream.write( 2, "\r\n" );
  210. // Write all planes.
  211. const U32 numPlanes = mPolyhedron.getNumPlanes();
  212. for( U32 i = 0; i < numPlanes; ++ i )
  213. {
  214. const PlaneF& plane = mPolyhedron.getPlanes()[ i ];
  215. stream.writeTabs( tabStop );
  216. char buffer[ 1024 ];
  217. dSprintf( buffer, sizeof( buffer ), "plane = \"%g %g %g %g\";",
  218. plane.x, plane.y, plane.z, plane.d
  219. );
  220. stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
  221. }
  222. // Write all points.
  223. const U32 numPoints = mPolyhedron.getNumPoints();
  224. for( U32 i = 0; i < numPoints; ++ i )
  225. {
  226. const Point3F& point = mPolyhedron.getPoints()[ i ];
  227. stream.writeTabs( tabStop );
  228. char buffer[ 1024 ];
  229. dSprintf( buffer, sizeof( buffer ), "point = \"%g %g %g\";",
  230. point.x, point.y, point.z
  231. );
  232. stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
  233. }
  234. // Write all edges.
  235. const U32 numEdges = mPolyhedron.getNumEdges();
  236. for( U32 i = 0; i < numEdges; ++ i )
  237. {
  238. const PolyhedronData::Edge& edge = mPolyhedron.getEdges()[ i ];
  239. stream.writeTabs( tabStop );
  240. char buffer[ 1024 ];
  241. dSprintf( buffer, sizeof( buffer ), "edge = \"%i %i %i %i\";",
  242. edge.face[ 0 ], edge.face[ 1 ],
  243. edge.vertex[ 0 ], edge.vertex[ 1 ]
  244. );
  245. stream.writeLine( reinterpret_cast< const U8* >( buffer ) );
  246. }
  247. }
  248. //-----------------------------------------------------------------------------
  249. template< typename Base, typename P >
  250. bool ScenePolyhedralObject< Base, P >::_setPlane( void* object, const char* index, const char* data )
  251. {
  252. ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
  253. PlaneF plane;
  254. dSscanf( data, "%g %g %g %g",
  255. &plane.x,
  256. &plane.y,
  257. &plane.z,
  258. &plane.d
  259. );
  260. obj->mPolyhedron.mPlaneList.push_back( plane );
  261. obj->setMaskBits( PolyMask );
  262. obj->mIsBox = false;
  263. return false;
  264. }
  265. //-----------------------------------------------------------------------------
  266. template< typename Base, typename P >
  267. bool ScenePolyhedralObject< Base, P >::_setPoint( void* object, const char* index, const char* data )
  268. {
  269. ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
  270. Point3F point;
  271. dSscanf( data, "%g %g %g %g",
  272. &point[ 0 ],
  273. &point[ 1 ],
  274. &point[ 2 ]
  275. );
  276. obj->mPolyhedron.mPointList.push_back( point );
  277. obj->setMaskBits( PolyMask );
  278. obj->mIsBox = false;
  279. return false;
  280. }
  281. //-----------------------------------------------------------------------------
  282. template< typename Base, typename P >
  283. bool ScenePolyhedralObject< Base, P >::_setEdge( void* object, const char* index, const char* data )
  284. {
  285. ScenePolyhedralObject* obj = reinterpret_cast< ScenePolyhedralObject* >( object );
  286. PolyhedronData::Edge edge;
  287. dSscanf( data, "%i %i %i %i",
  288. &edge.face[ 0 ],
  289. &edge.face[ 1 ],
  290. &edge.vertex[ 0 ],
  291. &edge.vertex[ 1 ]
  292. );
  293. obj->mPolyhedron.mEdgeList.push_back( edge );
  294. obj->setMaskBits( PolyMask );
  295. obj->mIsBox = false;
  296. return false;
  297. }
  298. #endif // _SCENEPOLYHEDRALOBJECT_IMPL_H_