convexShape.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  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. #include "platform/platform.h"
  23. #include "T3D/convexShape.h"
  24. #include "math/mathIO.h"
  25. #include "math/mathUtils.h"
  26. #include "scene/sceneRenderState.h"
  27. #include "console/consoleTypes.h"
  28. #include "core/stream/bitStream.h"
  29. #include "materials/materialManager.h"
  30. #include "lighting/lightQuery.h"
  31. #include "renderInstance/renderPassManager.h"
  32. #include "gfx/gfxTransformSaver.h"
  33. #include "gfx/primBuilder.h"
  34. #include "gfx/gfxDrawUtil.h"
  35. #include "core/bitVector.h"
  36. #include "materials/materialFeatureTypes.h"
  37. #include "materials/baseMatInstance.h"
  38. #include "collision/optimizedPolyList.h"
  39. #include "T3D/physics/physicsPlugin.h"
  40. #include "T3D/physics/physicsBody.h"
  41. #include "T3D/physics/physicsCollision.h"
  42. #include "console/engineAPI.h"
  43. #include "core/strings/stringUnit.h"
  44. IMPLEMENT_CO_NETOBJECT_V1( ConvexShape );
  45. ConsoleDocClass( ConvexShape,
  46. "@brief A renderable, collidable convex shape defined by a collection of surface planes.\n\n"
  47. "%ConvexShape is intended to be used as a temporary asset for quickly "
  48. "blocking out a scene or filling in approximate shapes to be later replaced "
  49. "with final assets. This is most easily done by using the WorldEditor's "
  50. "Sketch Tool.\n\n"
  51. "@ingroup enviroMisc"
  52. );
  53. Point3F ConvexShapeCollisionConvex::support( const VectorF &vec ) const
  54. {
  55. const Vector< Point3F > &pointList = pShape->mGeometry.points;
  56. if ( pointList.empty() )
  57. return pShape->getObjBox().getCenter();
  58. // This doesn't deal with the case that the farthest plane along vec is also
  59. // perpendicular to it, but in that case maybe it doesn't matter which point we return
  60. // anyway.
  61. F32 bestDot = mDot( pointList[0], vec );
  62. const Point3F *bestP = &pointList[0];
  63. for ( S32 i = 1; i < pointList.size(); i++ )
  64. {
  65. F32 newD = mDot( pointList[i], vec );
  66. if ( newD > bestDot )
  67. {
  68. bestDot = newD;
  69. bestP = &pointList[i];
  70. }
  71. }
  72. return *bestP;
  73. }
  74. void ConvexShapeCollisionConvex::getFeatures( const MatrixF &mat, const VectorF &n, ConvexFeature *cf )
  75. {
  76. if ( pShape->mGeometry.points.empty() )
  77. {
  78. cf->material = 0;
  79. cf->mObject = NULL;
  80. return;
  81. }
  82. cf->material = 0;
  83. cf->mObject = mObject;
  84. // Simple implementation... Add all Points, Edges and Faces.
  85. // Points...
  86. S32 firstVert = cf->mVertexList.size();
  87. const Vector< Point3F > &pointList = pShape->mGeometry.points;
  88. const U32 pointListCount = pointList.size();
  89. cf->mVertexList.increment( pointListCount );
  90. for ( S32 i = 0; i < pointListCount; i++ )
  91. mat.mulP( pointList[i], &(cf->mVertexList[ firstVert + i ]) );
  92. // Edges and Triangles for each face...
  93. const Vector< ConvexShape::Face > &faceList = pShape->mGeometry.faces;
  94. for ( S32 i = 0; i < faceList.size(); i++ )
  95. {
  96. // Add this Face's Edges.
  97. const Vector< ConvexShape::Edge > &edgeList = faceList[i].edges;
  98. const U32 edgeCount = edgeList.size();
  99. const S32 firstEdge = cf->mEdgeList.size();
  100. cf->mEdgeList.increment( edgeCount );
  101. for ( S32 j = 0; j < edgeCount; j++ )
  102. {
  103. cf->mEdgeList[ firstEdge + j ].vertex[0] = faceList[i].points[ edgeList[j].p0 ];
  104. cf->mEdgeList[ firstEdge + j ].vertex[1] = faceList[i].points[ edgeList[j].p1 ];
  105. }
  106. // Add this face's Triangles.
  107. // Note that ConvexFeature calls triangles 'faces' but a ConvexShape 'Face' is not
  108. // necessarily a single triangle.
  109. const Vector< ConvexShape::Triangle > &triangleList = faceList[i].triangles;
  110. const U32 triangleCount = triangleList.size();
  111. S32 firstTriangle = cf->mFaceList.size();
  112. cf->mFaceList.increment( triangleCount );
  113. for ( S32 j = 0; j < triangleCount; j++ )
  114. {
  115. ConvexFeature::Face &cft = cf->mFaceList[ firstTriangle + j ];
  116. cft.normal = faceList[i].normal;
  117. cft.vertex[0] = triangleList[j].p0;
  118. cft.vertex[1] = triangleList[j].p1;
  119. cft.vertex[2] = triangleList[j].p2;
  120. }
  121. }
  122. }
  123. void ConvexShapeCollisionConvex::getPolyList( AbstractPolyList* list )
  124. {
  125. SphereF sphere( Point3F::Zero, 0.0f );
  126. pShape->buildPolyList( PLC_Collision, list, Box3F::Invalid, sphere );
  127. }
  128. GFXImplementVertexFormat( ConvexVert )
  129. {
  130. addElement( "POSITION", GFXDeclType_Float3 );
  131. addElement( "COLOR", GFXDeclType_Color );
  132. addElement( "NORMAL", GFXDeclType_Float3 );
  133. addElement( "TANGENT", GFXDeclType_Float3 );
  134. addElement( "TEXCOORD", GFXDeclType_Float2, 0 );
  135. };
  136. static const U32 sgConvexFaceColorCount = 16;
  137. static const ColorI sgConvexFaceColors[ sgConvexFaceColorCount ] =
  138. {
  139. ColorI( 239, 131, 201 ),
  140. ColorI( 124, 255, 69 ),
  141. ColorI( 255, 65, 77 ),
  142. ColorI( 33, 118, 235 ),
  143. ColorI( 114, 227, 110 ),
  144. ColorI( 197, 50, 237 ),
  145. ColorI( 236, 255, 255 ),
  146. ColorI( 139, 225, 192 ),
  147. ColorI( 215, 9, 65 ),
  148. ColorI( 249, 114, 93 ),
  149. ColorI( 255, 255, 90 ),
  150. ColorI( 93, 104, 97 ),
  151. ColorI( 255, 214, 192 ),
  152. ColorI( 122, 44, 198 ),
  153. ColorI( 137, 141, 194 ),
  154. ColorI( 164, 114, 43 )
  155. };
  156. bool ConvexShape::smRenderEdges = false;
  157. bool ConvexShape::protectedSetSurface( void *object, const char *index, const char *data )
  158. {
  159. ConvexShape *shape = static_cast< ConvexShape* >( object );
  160. QuatF quat;
  161. Point3F pos;
  162. //MatrixF mat;
  163. U32 matID;
  164. Point2F offset;
  165. Point2F scale;
  166. F32 rot = 0;
  167. bool horz = true, vert = true;
  168. /*
  169. dSscanf( data, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
  170. &mat[0], &mat[1], &mat[2], &mat[3],
  171. &mat[4], &mat[5], &mat[6], &mat[7],
  172. &mat[8], &mat[9], &mat[10], &mat[11],
  173. &mat[12], &mat[13], &mat[14], &mat[15] );
  174. */
  175. String t = data;
  176. dSscanf( data, "%g %g %g %g %g %g %g %i %g %g %g %g %f", &quat.x, &quat.y, &quat.z, &quat.w, &pos.x, &pos.y, &pos.z,
  177. &matID, &offset.x, &offset.y, &scale.x, &scale.y, &rot);
  178. MatrixF surface;
  179. quat.setMatrix( &surface );
  180. surface.setPosition( pos );
  181. shape->mSurfaces.push_back( surface );
  182. surfaceUV surfUV;
  183. if (StringUnit::getUnitCount(data, " ") > 7)
  184. {
  185. surfUV.matID = matID;
  186. surfUV.offset = offset;
  187. surfUV.scale = scale;
  188. surfUV.zRot = rot;
  189. surfUV.horzFlip = horz;
  190. surfUV.vertFlip = vert;
  191. }
  192. else
  193. {
  194. surfUV.matID = 0;
  195. surfUV.offset = Point2F(0,0);
  196. surfUV.scale = Point2F(1, 1);
  197. surfUV.zRot = 0;
  198. surfUV.horzFlip = false;
  199. surfUV.vertFlip = false;
  200. }
  201. shape->mSurfaceUVs.push_back(surfUV);
  202. return false;
  203. }
  204. bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, const char *data)
  205. {
  206. ConvexShape *shape = static_cast< ConvexShape* >(object);
  207. surfaceMaterial surface;
  208. surface._setMaterial(StringTable->insert(data));
  209. shape->mSurfaceTextures.push_back(surface);
  210. return false;
  211. }
  212. ConvexShape::ConvexShape()
  213. :
  214. mMaterialInst( NULL ),
  215. //mVertCount( 0 ),
  216. //mPrimCount( 0 ),
  217. mPhysicsRep( NULL ),
  218. mNormalLength( 0.3f )
  219. {
  220. mNetFlags.set( Ghostable | ScopeAlways );
  221. mTypeMask |= StaticObjectType |
  222. StaticShapeObjectType;
  223. mConvexList = new Convex;
  224. mSurfaceBuffers.clear();
  225. mSurfaceUVs.clear();
  226. mSurfaceTextures.clear();
  227. INIT_ASSET(Material);
  228. }
  229. ConvexShape::~ConvexShape()
  230. {
  231. if ( mMaterialInst )
  232. SAFE_DELETE( mMaterialInst );
  233. for(U32 i=0; i<mSurfaceTextures.size(); i++)
  234. {
  235. if (mSurfaceTextures[i].materialInst)
  236. SAFE_DELETE(mSurfaceTextures[i].materialInst);
  237. }
  238. delete mConvexList;
  239. mConvexList = NULL;
  240. }
  241. void ConvexShape::initPersistFields()
  242. {
  243. docsURL;
  244. addGroup( "Rendering" );
  245. INITPERSISTFIELD_MATERIALASSET(Material, ConvexShape, "Default material used to render the ConvexShape surface.");
  246. endGroup( "Rendering" );
  247. addGroup( "Internal" );
  248. addProtectedField( "surface", TypeRealString, 0, &protectedSetSurface, &defaultProtectedGetFn,
  249. "Do not modify, for internal use.", AbstractClassRep::FIELD_HideInInspectors );
  250. addProtectedField( "surfaceTexture", TypeRealString, 0, &protectedSetSurfaceTexture, &defaultProtectedGetFn,
  251. "Do not modify, for internal use.", AbstractClassRep::FIELD_HideInInspectors );
  252. endGroup( "Internal" );
  253. Parent::initPersistFields();
  254. }
  255. void ConvexShape::inspectPostApply()
  256. {
  257. Parent::inspectPostApply();
  258. _updateGeometry( true );
  259. setMaskBits( UpdateMask );
  260. }
  261. bool ConvexShape::onAdd()
  262. {
  263. if ( !Parent::onAdd() )
  264. return false;
  265. //mObjBox.set( -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f );
  266. //resetWorldBox();
  267. // Face Order:
  268. // Top, Bottom, Front, Back, Left, Right
  269. // X Axis
  270. static const Point3F cubeTangents[6] =
  271. {
  272. Point3F( 1, 0, 0 ),
  273. Point3F(-1, 0, 0 ),
  274. Point3F( 1, 0, 0 ),
  275. Point3F(-1, 0, 0 ),
  276. Point3F( 0, 1, 0 ),
  277. Point3F( 0, -1, 0 )
  278. };
  279. // Y Axis
  280. static const Point3F cubeBinormals[6] =
  281. {
  282. Point3F( 0, 1, 0 ),
  283. Point3F( 0, 1, 0 ),
  284. Point3F( 0, 0, -1 ),
  285. Point3F( 0, 0, -1 ),
  286. Point3F( 0, 0, -1 ),
  287. Point3F( 0, 0, -1 )
  288. };
  289. // Z Axis
  290. static const Point3F cubeNormals[6] =
  291. {
  292. Point3F( 0, 0, 1),
  293. Point3F( 0, 0, -1),
  294. Point3F( 0, 1, 0),
  295. Point3F( 0, -1, 0),
  296. Point3F(-1, 0, 0),
  297. Point3F( 1, 0, 0),
  298. };
  299. if ( mSurfaces.empty() )
  300. {
  301. for ( S32 i = 0; i < 6; i++ )
  302. {
  303. mSurfaces.increment();
  304. MatrixF &surf = mSurfaces.last();
  305. surf.identity();
  306. surf.setColumn( 0, cubeTangents[i] );
  307. surf.setColumn( 1, cubeBinormals[i] );
  308. surf.setColumn( 2, cubeNormals[i] );
  309. surf.setPosition( cubeNormals[i] * 0.5f );
  310. mSurfaceUVs.increment();
  311. mSurfaceUVs[i].offset = Point2F(0, 0);
  312. mSurfaceUVs[i].scale = Point2F(1, 1);
  313. mSurfaceUVs[i].zRot = 0;
  314. mSurfaceUVs[i].horzFlip = false;
  315. mSurfaceUVs[i].vertFlip = false;
  316. mSurfaceUVs[i].matID = 0;
  317. }
  318. }
  319. if ( isClientObject() )
  320. _updateMaterial();
  321. _updateGeometry( true );
  322. addToScene();
  323. PlaneF p = PlaneF(Point3F(0, 0, 0), Point3F(0, 0, 1));
  324. Point3F a = Point3F(0, 0, 1);
  325. Point3F b = Point3F(1, 0, -1);
  326. Point3F c = Point3F(-1, 0, -1);
  327. Vector<Point3F> points;
  328. points.push_back(a);
  329. points.push_back(b);
  330. points.push_back(c);
  331. Point3F vertices[64];
  332. p.clipPolygon(points.address(), points.size(), vertices);
  333. return true;
  334. }
  335. void ConvexShape::onRemove()
  336. {
  337. removeFromScene();
  338. mConvexList->nukeList();
  339. SAFE_DELETE( mPhysicsRep );
  340. Parent::onRemove();
  341. }
  342. void ConvexShape::writeFields( Stream &stream, U32 tabStop )
  343. {
  344. Parent::writeFields( stream, tabStop );
  345. // Now write all planes.
  346. stream.write(2, "\r\n");
  347. S32 count = mSurfaces.size();
  348. if ( count > smMaxSurfaces )
  349. {
  350. Con::errorf( "ConvexShape has too many surfaces to save! Truncated value %d to maximum value of %d", count, smMaxSurfaces );
  351. count = smMaxSurfaces;
  352. }
  353. for (U32 i = 0; i < mSurfaceTextures.size(); i++)
  354. {
  355. stream.writeTabs(tabStop);
  356. char buffer[1024];
  357. dMemset(buffer, 0, 1024);
  358. dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].getMaterial());
  359. stream.writeLine((const U8*)buffer);
  360. }
  361. for ( U32 i = 0; i < count; i++ )
  362. {
  363. const MatrixF &mat = mSurfaces[i];
  364. QuatF quat( mat );
  365. Point3F pos( mat.getPosition() );
  366. stream.writeTabs(tabStop);
  367. char buffer[1024];
  368. dMemset( buffer, 0, 1024 );
  369. dSprintf( buffer, 1024, "surface = \"%g %g %g %g %g %g %g %i %g %g %g %g %g %i %i\";",
  370. quat.x, quat.y, quat.z, quat.w, pos.x, pos.y, pos.z, mSurfaceUVs[i].matID,
  371. mSurfaceUVs[i].offset.x, mSurfaceUVs[i].offset.y, mSurfaceUVs[i].scale.x,
  372. mSurfaceUVs[i].scale.y, mSurfaceUVs[i].zRot, mSurfaceUVs[i].horzFlip, mSurfaceUVs[i].vertFlip);
  373. stream.writeLine( (const U8*)buffer );
  374. }
  375. }
  376. bool ConvexShape::writeField( StringTableEntry fieldname, const char *value )
  377. {
  378. if ( fieldname == StringTable->insert("surface") )
  379. return false;
  380. if ( fieldname == StringTable->insert("surfaceTexture") )
  381. return false;
  382. return Parent::writeField( fieldname, value );
  383. }
  384. void ConvexShape::onScaleChanged()
  385. {
  386. if ( isProperlyAdded() )
  387. _updateCollision();
  388. }
  389. void ConvexShape::setTransform( const MatrixF &mat )
  390. {
  391. Parent::setTransform( mat );
  392. if ( mPhysicsRep )
  393. mPhysicsRep->setTransform( mat );
  394. setMaskBits( TransformMask );
  395. }
  396. U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
  397. {
  398. U32 retMask = Parent::packUpdate( conn, mask, stream );
  399. if ( stream->writeFlag( mask & TransformMask ) )
  400. {
  401. mathWrite(*stream, getTransform());
  402. mathWrite(*stream, getScale());
  403. }
  404. if ( stream->writeFlag( mask & UpdateMask ) )
  405. {
  406. PACK_ASSET(conn, Material);
  407. U32 surfCount = mSurfaces.size();
  408. stream->writeInt( surfCount, 32 );
  409. for ( S32 i = 0; i < surfCount; i++ )
  410. {
  411. QuatF quat( mSurfaces[i] );
  412. Point3F pos( mSurfaces[i].getPosition() );
  413. mathWrite( *stream, quat );
  414. mathWrite( *stream, pos );
  415. mathWrite(*stream, mSurfaceUVs[i].offset);
  416. mathWrite(*stream, mSurfaceUVs[i].scale);
  417. stream->writeFlag(mSurfaceUVs[i].horzFlip);
  418. stream->writeFlag(mSurfaceUVs[i].vertFlip);
  419. stream->writeInt(mSurfaceUVs[i].matID, 16);
  420. }
  421. const U32 surfaceTex = mSurfaceTextures.size();
  422. stream->writeInt( surfaceTex, 32 );
  423. //next check for any texture coord or scale mods
  424. for(U32 i=0; i < surfaceTex; i++)
  425. {
  426. if (stream->writeFlag(mSurfaceTextures[i].mMaterialAsset.notNull()))
  427. {
  428. NetStringHandle assetIdStr = mSurfaceTextures[i].mMaterialAsset.getAssetId();
  429. conn->packNetStringHandleU(stream, assetIdStr);
  430. }
  431. else
  432. stream->writeString(mSurfaceTextures[i].mMaterialName);
  433. }
  434. }
  435. return retMask;
  436. }
  437. void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
  438. {
  439. Parent::unpackUpdate( conn, stream );
  440. if ( stream->readFlag() ) // TransformMask
  441. {
  442. mathRead(*stream, &mObjToWorld);
  443. mathRead(*stream, &mObjScale);
  444. setTransform( mObjToWorld );
  445. setScale( mObjScale );
  446. }
  447. if ( stream->readFlag() ) // UpdateMask
  448. {
  449. UNPACK_ASSET(conn, Material);
  450. mSurfaces.clear();
  451. mSurfaceUVs.clear();
  452. const U32 surfCount = stream->readInt( 32 );
  453. for ( S32 i = 0; i < surfCount; i++ )
  454. {
  455. mSurfaces.increment();
  456. MatrixF &mat = mSurfaces.last();
  457. QuatF quat;
  458. Point3F pos;
  459. mathRead( *stream, &quat );
  460. mathRead( *stream, &pos );
  461. quat.setMatrix( &mat );
  462. mat.setPosition( pos );
  463. mSurfaceUVs.increment();
  464. mathRead(*stream, &mSurfaceUVs[i].offset);
  465. mathRead(*stream, &mSurfaceUVs[i].scale);
  466. mSurfaceUVs[i].horzFlip = stream->readFlag();
  467. mSurfaceUVs[i].vertFlip = stream->readFlag();
  468. mSurfaceUVs[i].matID = stream->readInt(16);
  469. }
  470. //now fetch our text coord mods to store into the geometry data
  471. mSurfaceTextures.clear();
  472. const U32 surfaceTex = stream->readInt( 32 );
  473. //next check for any texture coord or scale mods
  474. for(U32 i=0; i < surfaceTex; i++)
  475. {
  476. mSurfaceTextures.increment();
  477. if (stream->readFlag())
  478. {
  479. mSurfaceTextures[i].mMaterialAssetId = StringTable->insert(conn->unpackNetStringHandleU(stream).getString());
  480. mSurfaceTextures[i]._setMaterial(mSurfaceTextures[i].mMaterialAssetId);
  481. }
  482. else
  483. mSurfaceTextures[i].mMaterialName = stream->readSTString();
  484. }
  485. if (isProperlyAdded())
  486. _updateMaterial();
  487. if ( isProperlyAdded() )
  488. _updateGeometry( true );
  489. }
  490. }
  491. void ConvexShape::prepRenderImage( SceneRenderState *state )
  492. {
  493. /*
  494. if ( state->isDiffusePass() )
  495. {
  496. ObjectRenderInst *ri2 = state->getRenderPass()->allocInst<ObjectRenderInst>();
  497. ri2->renderDelegate.bind( this, &ConvexShape::_renderDebug );
  498. ri2->type = RenderPassManager::RIT_Editor;
  499. state->getRenderPass()->addInst( ri2 );
  500. }
  501. */
  502. for (U32 i = 0; i < mSurfaceBuffers.size(); i++)
  503. {
  504. if (mSurfaceBuffers[i].mPrimitiveBuffer.isNull())
  505. continue;
  506. // If we don't have a material instance after the override then
  507. // we can skip rendering all together.
  508. BaseMatInstance *matInst;
  509. if (i == 0)
  510. {
  511. matInst = state->getOverrideMaterial(mMaterialInst ? mMaterialInst : MATMGR->getWarningMatInstance());
  512. }
  513. else
  514. {
  515. matInst = state->getOverrideMaterial(mSurfaceTextures[i - 1].materialInst ? mSurfaceTextures[i - 1].materialInst : MATMGR->getWarningMatInstance());
  516. }
  517. if (!matInst)
  518. continue;
  519. // Get a handy pointer to our RenderPassmanager
  520. RenderPassManager *renderPass = state->getRenderPass();
  521. // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
  522. MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
  523. // Set our RenderInst as a standard mesh render
  524. ri->type = RenderPassManager::RIT_Mesh;
  525. // Calculate our sorting point
  526. if (state)
  527. {
  528. // Calculate our sort point manually.
  529. const Box3F& rBox = getRenderWorldBox();
  530. ri->sortDistSq = rBox.getSqDistanceToPoint(state->getCameraPosition());
  531. }
  532. else
  533. ri->sortDistSq = 0.0f;
  534. // Set up our transforms
  535. MatrixF objectToWorld = getRenderTransform();
  536. objectToWorld.scale(getScale());
  537. ri->objectToWorld = renderPass->allocUniqueXform(objectToWorld);
  538. ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
  539. ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection);
  540. // If we need lights then set them up.
  541. if (matInst->isForwardLit())
  542. {
  543. LightQuery query;
  544. query.init(getWorldSphere());
  545. query.getLights(ri->lights, 8);
  546. }
  547. // Make sure we have an up-to-date backbuffer in case
  548. // our Material would like to make use of it
  549. // NOTICE: SFXBB is removed and refraction is disabled!
  550. //ri->backBuffTex = GFX->getSfxBackBuffer();
  551. // Set our Material
  552. ri->matInst = matInst;
  553. if (matInst->getMaterial()->isTranslucent() && (!(matInst->getMaterial()->isAlphatest() && state->isShadowPass())))
  554. {
  555. ri->translucentSort = true;
  556. ri->type = RenderPassManager::RIT_Translucent;
  557. }
  558. // Set up our vertex buffer and primitive buffer
  559. ri->vertBuff = &mSurfaceBuffers[i].mVertexBuffer;
  560. ri->primBuff = &mSurfaceBuffers[i].mPrimitiveBuffer;
  561. ri->prim = renderPass->allocPrim();
  562. ri->prim->type = GFXTriangleList;
  563. ri->prim->minIndex = 0;
  564. ri->prim->startIndex = 0;
  565. ri->prim->numPrimitives = mSurfaceBuffers[i].mPrimCount;
  566. ri->prim->startVertex = 0;
  567. ri->prim->numVertices = mSurfaceBuffers[i].mVertCount;
  568. // We sort by the material then vertex buffer.
  569. ri->defaultKey = matInst->getStateHint();
  570. ri->defaultKey2 = (U32)(uintptr_t)ri->vertBuff; // Not 64bit safe!
  571. // Submit our RenderInst to the RenderPassManager
  572. state->getRenderPass()->addInst(ri);
  573. }
  574. }
  575. void ConvexShape::buildConvex( const Box3F &box, Convex *convex )
  576. {
  577. if ( mGeometry.faces.empty() )
  578. return;
  579. mConvexList->collectGarbage();
  580. Box3F realBox = box;
  581. mWorldToObj.mul( realBox );
  582. realBox.minExtents.convolveInverse( mObjScale );
  583. realBox.maxExtents.convolveInverse( mObjScale );
  584. if ( realBox.isOverlapped( getObjBox() ) == false )
  585. return;
  586. // See if this convex exists in the working set already...
  587. Convex *cc = 0;
  588. CollisionWorkingList &wl = convex->getWorkingList();
  589. for ( CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext )
  590. {
  591. if ( itr->mConvex->getType() == ConvexShapeCollisionConvexType )
  592. {
  593. ConvexShapeCollisionConvex *pConvex = static_cast<ConvexShapeCollisionConvex*>(itr->mConvex);
  594. if ( pConvex->pShape == this )
  595. {
  596. cc = itr->mConvex;
  597. return;
  598. }
  599. }
  600. }
  601. // Set up the convex...
  602. ConvexShapeCollisionConvex *cp = new ConvexShapeCollisionConvex();
  603. mConvexList->registerObject( cp );
  604. convex->addToWorkingList( cp );
  605. cp->mObject = this;
  606. cp->pShape = this;
  607. }
  608. bool ConvexShape::buildPolyList( PolyListContext context, AbstractPolyList *plist, const Box3F &box, const SphereF &sphere )
  609. {
  610. if ( mGeometry.points.empty() )
  611. return false;
  612. // If we're exporting deal with that first.
  613. if ( context == PLC_Export )
  614. {
  615. AssertFatal( dynamic_cast<OptimizedPolyList*>( plist ), "ConvexShape::buildPolyList - Bad polylist for export!" );
  616. _export( (OptimizedPolyList*)plist, box, sphere );
  617. return true;
  618. }
  619. plist->setTransform( &mObjToWorld, mObjScale );
  620. plist->setObject( this );
  621. // Add points...
  622. const Vector< Point3F > pointList = mGeometry.points;
  623. S32 base = plist->addPoint( pointList[0] );
  624. for ( S32 i = 1; i < pointList.size(); i++ )
  625. plist->addPoint( pointList[i] );
  626. // Add Surfaces...
  627. const Vector< ConvexShape::Face > faceList = mGeometry.faces;
  628. if(context == PLC_Navigation)
  629. {
  630. for(S32 i = 0; i < faceList.size(); i++)
  631. {
  632. const ConvexShape::Face &face = faceList[i];
  633. S32 s = face.triangles.size();
  634. for(S32 j = 0; j < s; j++)
  635. {
  636. plist->begin(0, s*i + j);
  637. plist->plane(PlaneF(face.centroid, face.normal));
  638. plist->vertex(base + face.points[face.triangles[j].p0]);
  639. plist->vertex(base + face.points[face.triangles[j].p1]);
  640. plist->vertex(base + face.points[face.triangles[j].p2]);
  641. plist->end();
  642. }
  643. }
  644. return true;
  645. }
  646. for ( S32 i = 0; i < faceList.size(); i++ )
  647. {
  648. const ConvexShape::Face &face = faceList[i];
  649. plist->begin( 0, i );
  650. plist->plane( PlaneF( face.centroid, face.normal ) );
  651. for ( S32 j = 0; j < face.triangles.size(); j++ )
  652. {
  653. plist->vertex( base + face.points[ face.triangles[j].p0 ] );
  654. plist->vertex( base + face.points[ face.triangles[j].p1 ] );
  655. plist->vertex( base + face.points[ face.triangles[j].p2 ] );
  656. }
  657. plist->end();
  658. }
  659. return true;
  660. }
  661. bool ConvexShape::buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &)
  662. {
  663. if (mGeometry.points.empty())
  664. return false;
  665. //Get the collision mesh geometry
  666. {
  667. ColladaUtils::ExportData::colMesh* colMesh;
  668. exportData->colMeshes.increment();
  669. colMesh = &exportData->colMeshes.last();
  670. colMesh->mesh.setTransform(&mObjToWorld, mObjScale);
  671. colMesh->mesh.setObject(this);
  672. //Just get the visible
  673. buildPolyList(PLC_Export, &colMesh->mesh, getWorldBox(), getWorldSphere());
  674. colMesh->colMeshName = String::ToString("ColMesh%d-1", exportData->colMeshes.size());
  675. }
  676. //Next, process the geometry and materials.
  677. //Convex shapes only have the one 'level', so we'll just rely on the export post-process to back-fill
  678. if (isServerObject() && getClientObject())
  679. {
  680. exportData->meshData.increment();
  681. //Prep a meshData for this shape in particular
  682. ColladaUtils::ExportData::meshLODData* meshData = &exportData->meshData.last();
  683. //Fill out the info we'll need later to actually append our mesh data for the detail levels during the processing phase
  684. meshData->shapeInst = nullptr;
  685. meshData->originatingObject = this;
  686. meshData->meshTransform = mObjToWorld;
  687. meshData->scale = mObjScale;
  688. meshData->meshDetailLevels.increment();
  689. ColladaUtils::ExportData::detailLevel* curDetail = &meshData->meshDetailLevels.last();
  690. //Make sure we denote the size this detail level has
  691. curDetail->size = getNextPow2(getObjBox().len());
  692. }
  693. return true;
  694. }
  695. void ConvexShape::_export( OptimizedPolyList *plist, const Box3F &box, const SphereF &sphere )
  696. {
  697. BaseMatInstance *matInst = mMaterialInst;
  698. if ( isServerObject() && getClientObject() )
  699. matInst = dynamic_cast<ConvexShape*>(getClientObject())->mMaterialInst;
  700. MatrixF saveMat;
  701. Point3F saveScale;
  702. plist->getTransform( &saveMat, &saveScale );
  703. plist->setTransform( &mObjToWorld, mObjScale );
  704. plist->setObject( this );
  705. const Vector< ConvexShape::Face > faceList = mGeometry.faces;
  706. const Vector< Point3F > &pointList = mGeometry.points;
  707. for ( S32 i = 0; i < faceList.size(); i++ )
  708. {
  709. const ConvexShape::Face &face = faceList[i];
  710. plist->begin( matInst, i, OptimizedPolyList::TriangleList );
  711. plist->plane( PlaneF( face.centroid, face.normal ) );
  712. for ( S32 j = 0; j < face.triangles.size(); j++ )
  713. {
  714. for ( S32 k = 0; k < 3; k++ )
  715. {
  716. U32 vertId = face.triangles[j][k];
  717. plist->vertex( pointList[ face.points[ vertId ] ], face.normal, face.texcoords[ vertId ] );
  718. }
  719. }
  720. plist->end();
  721. }
  722. plist->setTransform( &saveMat, saveScale );
  723. }
  724. bool ConvexShape::castRay( const Point3F &start, const Point3F &end, RayInfo *info )
  725. {
  726. if ( mPlanes.empty() )
  727. return false;
  728. const Vector< PlaneF > &planeList = mPlanes;
  729. const U32 planeCount = planeList.size();
  730. F32 t;
  731. F32 tmin = F32_MAX;
  732. S32 hitFace = -1;
  733. Point3F hitPnt, pnt;
  734. VectorF rayDir( end - start );
  735. rayDir.normalizeSafe();
  736. for ( S32 i = 0; i < planeCount; i++ )
  737. {
  738. // Don't hit the back-side of planes.
  739. if ( mDot( rayDir, planeList[i] ) >= 0.0f )
  740. continue;
  741. t = planeList[i].intersect( start, end );
  742. if ( t >= 0.0f && t <= 1.0f && t < tmin )
  743. {
  744. pnt.interpolate( start, end, t );
  745. S32 j = 0;
  746. for ( ; j < planeCount; j++ )
  747. {
  748. if ( i == j )
  749. continue;
  750. F32 dist = planeList[j].distToPlane( pnt );
  751. if ( dist > 1.0e-004f )
  752. break;
  753. }
  754. if ( j == planeCount )
  755. {
  756. tmin = t;
  757. hitFace = i;
  758. }
  759. }
  760. }
  761. if ( hitFace == -1 )
  762. return false;
  763. info->face = hitFace;
  764. info->material = mMaterialInst;
  765. info->normal = planeList[ hitFace ];
  766. info->object = this;
  767. info->t = tmin;
  768. //mObjToWorld.mulV( info->normal );
  769. return true;
  770. }
  771. bool ConvexShape::collideBox( const Point3F &start, const Point3F &end, RayInfo *info )
  772. {
  773. return Parent::collideBox( start, end, info );
  774. }
  775. void ConvexShape::updateBounds( bool recenter )
  776. {
  777. if ( mGeometry.points.size() == 0 )
  778. return;
  779. Vector<Point3F> &pointListOS = mGeometry.points;
  780. U32 pointCount = pointListOS.size();
  781. Point3F volumnCenter( 0,0,0 );
  782. F32 areaSum = 0.0f;
  783. F32 faceCount = mGeometry.faces.size();
  784. for ( S32 i = 0; i < faceCount; i++ )
  785. {
  786. volumnCenter += mGeometry.faces[i].centroid * mGeometry.faces[i].area;
  787. areaSum += mGeometry.faces[i].area;
  788. }
  789. if ( areaSum == 0.0f )
  790. return;
  791. volumnCenter /= areaSum;
  792. mObjBox.minExtents = mObjBox.maxExtents = Point3F::Zero;
  793. mObjBox.setCenter( volumnCenter );
  794. for ( S32 i = 0; i < pointCount; i++ )
  795. mObjBox.extend( pointListOS[i] );
  796. resetWorldBox();
  797. }
  798. void ConvexShape::recenter()
  799. {
  800. if ( mGeometry.points.size() == 0 )
  801. return;
  802. Point3F volCenterOS( 0,0,0 );
  803. F32 areaSum = 0.0f;
  804. F32 faceCount = mGeometry.faces.size();
  805. for ( S32 i = 0; i < faceCount; i++ )
  806. {
  807. volCenterOS += mGeometry.faces[i].centroid * mGeometry.faces[i].area;
  808. areaSum += mGeometry.faces[i].area;
  809. }
  810. volCenterOS /= areaSum;
  811. for ( S32 i = 0; i < mSurfaces.size(); i++ )
  812. mSurfaces[i].setPosition( mSurfaces[i].getPosition() - volCenterOS );
  813. Point3F volCenterWS;
  814. MatrixF objToWorld( mObjToWorld );
  815. objToWorld.scale( mObjScale );
  816. objToWorld.mulP( volCenterOS, &volCenterWS );
  817. setPosition( volCenterWS );
  818. _updateGeometry(true);
  819. }
  820. MatrixF ConvexShape::getSurfaceWorldMat( S32 surfId, bool scaled ) const
  821. {
  822. if ( surfId < 0 || surfId >= mSurfaces.size() )
  823. return MatrixF::Identity;
  824. MatrixF objToWorld( mObjToWorld );
  825. if ( scaled )
  826. objToWorld.scale( mObjScale );
  827. MatrixF surfMat;
  828. surfMat.mul( objToWorld, mSurfaces[surfId] );
  829. return surfMat;
  830. }
  831. // Used in cullEmptyPlanes.
  832. S32 QSORT_CALLBACK sortDescendingU32( const void *a, const void *b )
  833. {
  834. U32 *aa = (U32*)(a);
  835. U32 *bb = (U32*)(b);
  836. return (S32)(*bb) - (S32)(*aa);
  837. }
  838. void ConvexShape::cullEmptyPlanes( Vector< U32 > *removedPlanes )
  839. {
  840. //if ( mPlanes.size() == mGeometry.faces.size() )
  841. // return;
  842. removedPlanes->clear();
  843. const U32 startPlaneCount = mPlanes.size();
  844. const Vector< ConvexShape::Face > &faceList = mGeometry.faces;
  845. const U32 faceCount = faceList.size();
  846. S32 *used = new S32[ startPlaneCount ];
  847. for ( S32 i = 0; i < startPlaneCount; i++ )
  848. used[i] = i;
  849. for ( S32 i = 0; i < faceCount; i++ )
  850. {
  851. if ( faceList[i].area > 0.001f )
  852. used[ faceList[i].id ] = -1;
  853. }
  854. for ( S32 i = 0; i < startPlaneCount; i++ )
  855. {
  856. if ( used[i] != -1 )
  857. removedPlanes->push_back( used[i] );
  858. }
  859. dQsort( removedPlanes->address(), removedPlanes->size(), sizeof( U32 ), sortDescendingU32 );
  860. for ( S32 i = 0; i < removedPlanes->size(); i++ )
  861. {
  862. mPlanes.erase( (*removedPlanes)[i] );
  863. mSurfaces.erase( (*removedPlanes)[i] );
  864. }
  865. delete [] used;
  866. }
  867. void ConvexShape::exportToCollada()
  868. {
  869. if ( mSurfaces.size() == 0 )
  870. {
  871. Con::errorf( "ConvexShape::exportToCollada() - has no surfaces to export!" );
  872. return;
  873. }
  874. }
  875. void ConvexShape::resizePlanes( const Point3F &size )
  876. {
  877. //Point3F nSize;
  878. //mWorldToObj.mulV( nSize );
  879. for ( S32 i = 0; i < mSurfaces.size(); i++ )
  880. {
  881. MatrixF objToPlane( mSurfaces[i] );
  882. objToPlane.inverse();
  883. Point3F lim;
  884. objToPlane.mulV( size, &lim );
  885. F32 sign = ( mPlanes[i].d > 0.0f ) ? 1.0f : -1.0f;
  886. mPlanes[i].d = mFabs(lim.z) * 0.5f * sign;
  887. //mPlanes[i].d = -lim.z * 0.5f;
  888. mSurfaces[i].setPosition( mPlanes[i].getPosition() );
  889. }
  890. }
  891. void ConvexShape::getSurfaceLineList( S32 surfId, Vector< Point3F > &lineList )
  892. {
  893. if ( surfId < 0 || surfId > mSurfaces.size() - 1 )
  894. return;
  895. S32 faceId = -1;
  896. for ( S32 i = 0; i < mGeometry.faces.size(); i++ )
  897. {
  898. if ( mGeometry.faces[i].id == surfId )
  899. {
  900. faceId = i;
  901. break;
  902. }
  903. }
  904. if ( faceId == -1 )
  905. return;
  906. ConvexShape::Face &face = mGeometry.faces[faceId];
  907. const Vector< Point3F > &pointList = mGeometry.points;
  908. if ( pointList.size() == 0 )
  909. return;
  910. for ( S32 i = 0; i < face.winding.size(); i++ )
  911. lineList.push_back( pointList[ face.points[ face.winding[i] ] ] );
  912. lineList.push_back( pointList[ face.points[ face.winding.first() ] ] );
  913. }
  914. void ConvexShape::_updateMaterial()
  915. {
  916. //update our custom surface materials
  917. for (U32 i = 0; i<mSurfaceTextures.size(); i++)
  918. {
  919. mSurfaceTextures[i]._setMaterial(mSurfaceTextures[i].getMaterial());
  920. //If we already have the material inst and it hasn't changed, skip
  921. if (mSurfaceTextures[i].materialInst &&
  922. mSurfaceTextures[i].getMaterialAsset()->getMaterialDefinitionName() == mSurfaceTextures[i].materialInst->getMaterial()->getName() &&
  923. mSurfaceTextures[i].materialInst->getVertexFormat() == getGFXVertexFormat<VertexType>())
  924. continue;
  925. SAFE_DELETE(mSurfaceTextures[i].materialInst);
  926. Material* material = mSurfaceTextures[i].getMaterialResource();
  927. if (material == nullptr)
  928. continue;
  929. mSurfaceTextures[i].materialInst = material->createMatInstance();
  930. FeatureSet features = MATMGR->getDefaultFeatures();
  931. mSurfaceTextures[i].materialInst->init(features, getGFXVertexFormat<VertexType>());
  932. if (!mSurfaceTextures[i].materialInst->isValid())
  933. {
  934. SAFE_DELETE(mSurfaceTextures[i].materialInst);
  935. }
  936. }
  937. _setMaterial(getMaterial());
  938. // If the material name matches then don't bother updating it.
  939. if (mMaterialInst && getMaterialAsset()->getMaterialDefinitionName() == mMaterialInst->getMaterial()->getName() &&
  940. mMaterialInst->getVertexFormat() == getGFXVertexFormat<VertexType>())
  941. return;
  942. SAFE_DELETE( mMaterialInst );
  943. Material* material = getMaterialResource();
  944. if (material == nullptr)
  945. return;
  946. mMaterialInst = material->createMatInstance();
  947. FeatureSet features = MATMGR->getDefaultFeatures();
  948. //features.addFeature( MFT_DiffuseVertColor );
  949. mMaterialInst->init( features, getGFXVertexFormat<VertexType>() );
  950. if ( !mMaterialInst->isValid() )
  951. {
  952. SAFE_DELETE( mMaterialInst );
  953. }
  954. }
  955. void ConvexShape::_updateGeometry( bool updateCollision )
  956. {
  957. mPlanes.clear();
  958. for ( S32 i = 0; i < mSurfaces.size(); i++ )
  959. mPlanes.push_back( PlaneF( mSurfaces[i].getPosition(), mSurfaces[i].getUpVector() ) );
  960. Vector< Point3F > tangents;
  961. for (S32 i = 0; i < mSurfaces.size(); i++)
  962. tangents.push_back(mSurfaces[i].getRightVector());
  963. //prepping the texture info
  964. Vector<Point2F> texOffset;
  965. Vector<Point2F> texScale;
  966. Vector<bool> horzFlip;
  967. Vector<bool> vertFlip;
  968. //step in here, and add new surfaceTextures if we don't match the count of surfaces, we use
  969. //msurfaces as the counter, because we need to match it.
  970. if (mSurfaceUVs.size() > mSurfaces.size())
  971. {
  972. for (U32 x = mSurfaceUVs.size(); x > mSurfaces.size(); x--)
  973. mSurfaceUVs.pop_front();
  974. }
  975. else if (mSurfaceUVs.size() < mSurfaces.size())
  976. {
  977. for (U32 x = mSurfaceUVs.size(); x <= mSurfaces.size(); x++)
  978. {
  979. mSurfaceUVs.increment();
  980. mSurfaceUVs[x].offset = Point2F(0, 0);
  981. mSurfaceUVs[x].scale = Point2F(1, 1);
  982. mSurfaceUVs[x].zRot = 0;
  983. mSurfaceUVs[x].horzFlip = false;
  984. mSurfaceUVs[x].vertFlip = false;
  985. mSurfaceUVs[x].matID = 0;
  986. }
  987. }
  988. for (S32 i = 0; i < mSurfaceUVs.size(); i++)
  989. {
  990. //add our offsets/scales for passing to the geometry now
  991. texOffset.push_back(mSurfaceUVs[i].offset);
  992. texScale.push_back(mSurfaceUVs[i].scale);
  993. horzFlip.push_back(mSurfaceUVs[i].horzFlip);
  994. vertFlip.push_back(mSurfaceUVs[i].vertFlip);
  995. }
  996. mGeometry.generate(mPlanes, tangents, mSurfaceTextures, texOffset, texScale, horzFlip, vertFlip);
  997. AssertFatal(mGeometry.faces.size() <= mSurfaces.size(), "Got more faces than planes?");
  998. const Vector< ConvexShape::Face > &faceList = mGeometry.faces;
  999. const Vector< Point3F > &pointList = mGeometry.points;
  1000. // Reset our surface center points.
  1001. for (S32 i = 0; i < faceList.size(); i++)
  1002. mSurfaces[faceList[i].id].setPosition(faceList[i].centroid);
  1003. mPlanes.clear();
  1004. for (S32 i = 0; i < mSurfaces.size(); i++)
  1005. mPlanes.push_back(PlaneF(mSurfaces[i].getPosition(), mSurfaces[i].getUpVector()));
  1006. // Update bounding box.
  1007. updateBounds( false );
  1008. /*mVertexBuffer = NULL;
  1009. mPrimitiveBuffer = NULL;
  1010. mVertCount = 0;
  1011. mPrimCount = 0;*/
  1012. mSurfaceBuffers.clear();
  1013. //set up buffers based on how many materials we have, but we always have at least one for our default mat
  1014. mSurfaceBuffers.increment();
  1015. mSurfaceBuffers[0].mVertexBuffer = NULL;
  1016. mSurfaceBuffers[0].mVertCount = 0;
  1017. mSurfaceBuffers[0].mPrimCount = 0;
  1018. for (U32 i = 0; i < mSurfaceTextures.size(); i++)
  1019. {
  1020. mSurfaceBuffers.increment();
  1021. mSurfaceBuffers[i+1].mVertexBuffer = NULL;
  1022. mSurfaceBuffers[i + 1].mVertCount = 0;
  1023. mSurfaceBuffers[i + 1].mPrimCount = 0;
  1024. }
  1025. if ( updateCollision )
  1026. _updateCollision();
  1027. // Server does not need to generate vertex/prim buffers.
  1028. if ( isServerObject() )
  1029. return;
  1030. if ( faceList.empty() )
  1031. return;
  1032. //We do this in 2 parts. First, going through and building the buffers for all faces with the default material(matID -1)
  1033. //After that, we then through and build buffers for all faces sharing materials. This means we can have a single buffer,
  1034. //or one for each face of the brush, depending on how it's textured
  1035. // Get total vert and prim count.
  1036. for ( S32 i = 0; i < faceList.size(); i++ )
  1037. {
  1038. U32 count = faceList[i].triangles.size();
  1039. mSurfaceBuffers[mSurfaceUVs[i].matID].mPrimCount += count;
  1040. mSurfaceBuffers[mSurfaceUVs[i].matID].mVertCount += count * 3;
  1041. }
  1042. //Build the buffer for our default material
  1043. /*if (mVertCount > 0)
  1044. {
  1045. mVertexBuffer.set(GFX, mVertCount, GFXBufferTypeStatic);
  1046. VertexType *pVert = mVertexBuffer.lock();
  1047. for (S32 i = 0; i < faceList.size(); i++)
  1048. {
  1049. if (mSurfaceUVs[i].matID == -1)
  1050. {
  1051. const ConvexShape::Face &face = faceList[i];
  1052. const Vector< U32 > &facePntMap = face.points;
  1053. const Vector< ConvexShape::Triangle > &triangles = face.triangles;
  1054. const ColorI &faceColor = sgConvexFaceColors[i % sgConvexFaceColorCount];
  1055. const Point3F binormal = mCross(face.normal, face.tangent);
  1056. pVert++;
  1057. }
  1058. }
  1059. }
  1060. }
  1061. mVertexBuffer.unlock();
  1062. // Allocate PB
  1063. mPrimitiveBuffer.set(GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic);
  1064. U16 *pIndex;
  1065. mPrimitiveBuffer.lock(&pIndex);
  1066. for (U16 i = 0; i < mPrimCount * 3; i++)
  1067. {
  1068. *pIndex = i;
  1069. pIndex++;
  1070. }
  1071. mPrimitiveBuffer.unlock();
  1072. }*/
  1073. //
  1074. //
  1075. for (U32 i = 0; i < mSurfaceBuffers.size(); i++)
  1076. {
  1077. if (mSurfaceBuffers[i].mVertCount > 0)
  1078. {
  1079. mSurfaceBuffers[i].mVertexBuffer.set(GFX, mSurfaceBuffers[i].mVertCount, GFXBufferTypeStatic);
  1080. VertexType *pVert = mSurfaceBuffers[i].mVertexBuffer.lock();
  1081. U32 vc = 0;
  1082. for (S32 f = 0; f < faceList.size(); f++)
  1083. {
  1084. if (mSurfaceUVs[f].matID == i)
  1085. {
  1086. const ConvexShape::Face &face = faceList[f];
  1087. const Vector< U32 > &facePntMap = face.points;
  1088. const Vector< ConvexShape::Triangle > &triangles = face.triangles;
  1089. const ColorI &faceColor = sgConvexFaceColors[f % sgConvexFaceColorCount];
  1090. const Point3F binormal = mCross(face.normal, face.tangent);
  1091. for (S32 j = 0; j < triangles.size(); j++)
  1092. {
  1093. for (S32 k = 0; k < 3; k++)
  1094. {
  1095. pVert->normal = face.normal;
  1096. pVert->T = face.tangent;
  1097. pVert->B = mCross(face.normal,face.tangent);
  1098. //pVert->color = faceColor;
  1099. pVert->point = pointList[facePntMap[triangles[j][k]]];
  1100. pVert->texCoord = face.texcoords[triangles[j][k]];
  1101. pVert->texCoord2 = pVert->texCoord;
  1102. pVert++;
  1103. vc++;
  1104. }
  1105. }
  1106. }
  1107. }
  1108. mSurfaceBuffers[i].mVertexBuffer.unlock();
  1109. // Allocate PB
  1110. mSurfaceBuffers[i].mPrimitiveBuffer.set(GFX, mSurfaceBuffers[i].mPrimCount * 3, mSurfaceBuffers[i].mPrimCount, GFXBufferTypeStatic);
  1111. U16 *pIndex;
  1112. mSurfaceBuffers[i].mPrimitiveBuffer.lock(&pIndex);
  1113. for (U16 p = 0; p < mSurfaceBuffers[i].mPrimCount * 3; p++)
  1114. {
  1115. *pIndex = p;
  1116. pIndex++;
  1117. }
  1118. mSurfaceBuffers[i].mPrimitiveBuffer.unlock();
  1119. }
  1120. }
  1121. //
  1122. //
  1123. /*// Allocate VB and copy in data.
  1124. for (S32 i = 0; i < faceList.size(); i++)
  1125. {
  1126. mVertexBuffer.set(GFX, mVertCount, GFXBufferTypeStatic);
  1127. VertexType *pVert = mVertexBuffer.lock();
  1128. for (S32 i = 0; i < faceList.size(); i++)
  1129. {
  1130. const ConvexShape::Face &face = faceList[i];
  1131. const Vector< U32 > &facePntMap = face.points;
  1132. const Vector< ConvexShape::Triangle > &triangles = face.triangles;
  1133. const ColorI &faceColor = sgConvexFaceColors[i % sgConvexFaceColorCount];
  1134. const Point3F binormal = mCross(face.normal, face.tangent);
  1135. for (S32 j = 0; j < triangles.size(); j++)
  1136. {
  1137. for (S32 k = 0; k < 3; k++)
  1138. {
  1139. pVert->normal = face.normal;
  1140. pVert->tangent = face.tangent;
  1141. pVert->color = faceColor;
  1142. pVert->point = pointList[facePntMap[triangles[j][k]]];
  1143. pVert->texCoord = face.texcoords[triangles[j][k]];
  1144. pVert++;
  1145. }
  1146. }
  1147. }
  1148. mVertexBuffer.unlock();
  1149. // Allocate PB
  1150. mPrimitiveBuffer.set(GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic);
  1151. U16 *pIndex;
  1152. mPrimitiveBuffer.lock(&pIndex);
  1153. for (U16 i = 0; i < mPrimCount * 3; i++)
  1154. {
  1155. *pIndex = i;
  1156. pIndex++;
  1157. }
  1158. mPrimitiveBuffer.unlock();
  1159. }*/
  1160. }
  1161. void ConvexShape::_updateCollision()
  1162. {
  1163. SAFE_DELETE( mPhysicsRep );
  1164. if ( !PHYSICSMGR )
  1165. return;
  1166. PhysicsCollision *colShape = PHYSICSMGR->createCollision();
  1167. // We need the points untransformed!
  1168. Vector<Point3F> rawPoints;
  1169. MatrixF xfm( getWorldTransform() );
  1170. xfm.setPosition( Point3F::Zero );
  1171. for ( U32 i=0; i < mGeometry.points.size(); i++ )
  1172. {
  1173. Point3F p = mGeometry.points[i];
  1174. xfm.mulP( p );
  1175. rawPoints.push_back( p );
  1176. }
  1177. // The convex generation from a point cloud
  1178. // can fail at times... give up in that case.
  1179. if ( !colShape->addConvex( mGeometry.points.address(),
  1180. mGeometry.points.size(),
  1181. MatrixF::Identity ) )
  1182. {
  1183. delete colShape;
  1184. return;
  1185. }
  1186. PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
  1187. mPhysicsRep = PHYSICSMGR->createBody();
  1188. mPhysicsRep->init( colShape, 0, 0, this, world );
  1189. mPhysicsRep->setTransform( getTransform() );
  1190. }
  1191. void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat )
  1192. {
  1193. GFXDrawUtil *drawer = GFX->getDrawUtil();
  1194. GFX->setTexture( 0, NULL );
  1195. // Render world box.
  1196. if (Con::getBoolVariable("$pref::convexDBG::ShowWorldBox", false))
  1197. {
  1198. Box3F wbox( mWorldBox );
  1199. if ( getServerObject() )
  1200. wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox;
  1201. GFXStateBlockDesc desc;
  1202. desc.setCullMode( GFXCullNone );
  1203. desc.setFillModeWireframe();
  1204. drawer->drawCube( desc, wbox, ColorI::RED );
  1205. }
  1206. const Vector< Point3F > &pointList = mGeometry.points;
  1207. const Vector< ConvexShape::Face > &faceList = mGeometry.faces;
  1208. // Render Edges.
  1209. if (Con::getBoolVariable("$pref::convexDBG::ShowEdges", false))
  1210. {
  1211. GFXTransformSaver saver;
  1212. //GFXFrustumSaver fsaver;
  1213. MatrixF xfm( getRenderTransform() );
  1214. xfm.scale( getScale() );
  1215. GFX->multWorld( xfm );
  1216. GFXStateBlockDesc desc;
  1217. desc.setZReadWrite( true, false );
  1218. desc.setBlend( true );
  1219. GFX->setStateBlockByDesc( desc );
  1220. //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), )
  1221. const Point3F &camFvec = state->getCameraTransform().getForwardVector();
  1222. for ( S32 i = 0; i < faceList.size(); i++ )
  1223. {
  1224. const ConvexShape::Face &face = faceList[i];
  1225. const Vector< ConvexShape::Edge > &edgeList = face.edges;
  1226. const Vector< U32 > &facePntList = face.points;
  1227. PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
  1228. PrimBuild::color( LinearColorF(ColorI::WHITE) * 0.8f );
  1229. for ( S32 j = 0; j < edgeList.size(); j++ )
  1230. {
  1231. PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f );
  1232. PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f );
  1233. }
  1234. PrimBuild::end();
  1235. }
  1236. }
  1237. ColorI faceColorsx[4] =
  1238. {
  1239. ColorI( 255, 0, 0 ),
  1240. ColorI( 0, 255, 0 ),
  1241. ColorI( 0, 0, 255 ),
  1242. ColorI( 255, 0, 255 )
  1243. };
  1244. MatrixF objToWorld( mObjToWorld );
  1245. objToWorld.scale( mObjScale );
  1246. // Render faces centers/colors.
  1247. if (Con::getBoolVariable("$pref::convexDBG::ShowFaceColors", false))
  1248. {
  1249. GFXStateBlockDesc desc;
  1250. desc.setCullMode( GFXCullNone );
  1251. Point3F size( 0.1f );
  1252. for ( S32 i = 0; i < faceList.size(); i++ )
  1253. {
  1254. ColorI color = faceColorsx[ i % 4 ];
  1255. LinearColorF tCol = LinearColorF(color);
  1256. S32 div = ( i / 4 ) * 4;
  1257. if ( div > 0 )
  1258. tCol /= div;
  1259. tCol.alpha = 1;
  1260. color = tCol.toColorI();
  1261. Point3F pnt;
  1262. objToWorld.mulP( faceList[i].centroid, &pnt );
  1263. drawer->drawCube( desc, size, pnt, color, NULL );
  1264. }
  1265. }
  1266. // Render winding order.
  1267. if (Con::getBoolVariable("$pref::convexDBG::ShowWinding", false))
  1268. {
  1269. GFXStateBlockDesc desc;
  1270. desc.setCullMode( GFXCullNone );
  1271. desc.setZReadWrite( true, false );
  1272. GFX->setStateBlockByDesc( desc );
  1273. U32 pointCount = 0;
  1274. for ( S32 i = 0; i < faceList.size(); i++ )
  1275. pointCount += faceList[i].winding.size();
  1276. PrimBuild::begin( GFXLineList, pointCount * 2 );
  1277. for ( S32 i = 0; i < faceList.size(); i++ )
  1278. {
  1279. for ( S32 j = 0; j < faceList[i].winding.size(); j++ )
  1280. {
  1281. Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ];
  1282. Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale );
  1283. objToWorld.mulP( p0 );
  1284. objToWorld.mulP( p1 );
  1285. ColorI color = faceColorsx[j % 4];
  1286. LinearColorF tCol = LinearColorF(color);
  1287. S32 div = (j / 4) * 4;
  1288. if (div > 0)
  1289. tCol /= div;
  1290. tCol.alpha = 1;
  1291. color = tCol.toColorI();
  1292. PrimBuild::color( color );
  1293. PrimBuild::vertex3fv( p0 );
  1294. PrimBuild::color( color );
  1295. PrimBuild::vertex3fv( p1 );
  1296. }
  1297. }
  1298. PrimBuild::end();
  1299. }
  1300. // Render Points.
  1301. if ( false )
  1302. {
  1303. /*
  1304. GFXTransformSaver saver;
  1305. MatrixF xfm( getRenderTransform() );
  1306. xfm.scale( getScale() );
  1307. GFX->multWorld( xfm );
  1308. GFXStateBlockDesc desc;
  1309. Point3F size( 0.05f );
  1310. */
  1311. }
  1312. // Render surface transforms.
  1313. if (Con::getBoolVariable("$pref::convexDBG::ShowSurfaceTransforms", false))
  1314. {
  1315. GFXStateBlockDesc desc;
  1316. desc.setBlend( false );
  1317. desc.setZReadWrite( true, true );
  1318. Point3F scale(mNormalLength);
  1319. for ( S32 i = 0; i < mSurfaces.size(); i++ )
  1320. {
  1321. objToWorld = mObjToWorld;
  1322. objToWorld.scale( mObjScale );
  1323. MatrixF renderMat;
  1324. renderMat.mul( objToWorld, mSurfaces[i] );
  1325. renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f );
  1326. drawer->drawTransform( desc, renderMat, &scale, NULL );
  1327. }
  1328. }
  1329. }
  1330. void ConvexShape::renderFaceEdges( S32 faceid, const ColorI &color /*= ColorI::WHITE*/, F32 lineWidth /*= 1.0f */ )
  1331. {
  1332. const Vector< ConvexShape::Face > &faceList = mGeometry.faces;
  1333. if ( faceid >= faceList.size() )
  1334. return;
  1335. GFXTransformSaver saver;
  1336. MatrixF xfm( mObjToWorld );
  1337. xfm.scale( mObjScale );
  1338. GFX->multWorld( xfm );
  1339. GFXStateBlockDesc desc;
  1340. desc.setBlend( true );
  1341. GFX->setStateBlockByDesc( desc );
  1342. MatrixF projBias(true);
  1343. const Frustum& frustum = GFX->getFrustum();
  1344. MathUtils::getZBiasProjectionMatrix( 0.001f, frustum, &projBias );
  1345. GFX->setProjectionMatrix( projBias );
  1346. S32 s = faceid;
  1347. S32 e = faceid + 1;
  1348. if ( faceid == -1 )
  1349. {
  1350. s = 0;
  1351. e = faceList.size();
  1352. }
  1353. for ( S32 i = s; i < e; i++ )
  1354. {
  1355. const ConvexShape::Face &face = faceList[i];
  1356. const Vector< ConvexShape::Edge > &edgeList = face.edges;
  1357. const Vector< U32 > &facePntList = face.points;
  1358. const Vector< Point3F > &pointList = mGeometry.points;
  1359. PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
  1360. PrimBuild::color( color );
  1361. for ( S32 j = 0; j < edgeList.size(); j++ )
  1362. {
  1363. PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] );
  1364. PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] );
  1365. }
  1366. PrimBuild::end();
  1367. }
  1368. }
  1369. void ConvexShape::getSurfaceTriangles( S32 surfId, Vector< Point3F > *outPoints, Vector< Point2F > *outCoords, bool worldSpace )
  1370. {
  1371. S32 faceId = -1;
  1372. for ( S32 i = 0; i < mGeometry.faces.size(); i++ )
  1373. {
  1374. if ( mGeometry.faces[i].id == surfId )
  1375. {
  1376. faceId = i;
  1377. break;
  1378. }
  1379. }
  1380. if ( faceId == -1 )
  1381. return;
  1382. const ConvexShape::Face &face = mGeometry.faces[ faceId ];
  1383. const Vector< Point3F > &pointList = mGeometry.points;
  1384. const MatrixF &surfToObj = mSurfaces[ faceId ];
  1385. MatrixF objToSurf( surfToObj );
  1386. objToSurf.inverse();
  1387. Point3F surfScale( 1.5f, 1.5f, 1.0f );
  1388. for ( S32 i = 0; i < face.triangles.size(); i++ )
  1389. {
  1390. for ( S32 j = 0; j < 3; j++ )
  1391. {
  1392. Point3F pnt( pointList[ face.points[ face.triangles[i][j] ] ] );
  1393. objToSurf.mulP( pnt );
  1394. pnt *= surfScale;
  1395. surfToObj.mulP( pnt );
  1396. outPoints->push_back( pnt );
  1397. if ( outCoords )
  1398. outCoords->push_back( face.texcoords[ face.triangles[i][j] ] );
  1399. }
  1400. }
  1401. if ( worldSpace )
  1402. {
  1403. MatrixF objToWorld( mObjToWorld );
  1404. objToWorld.scale( mObjScale );
  1405. for ( S32 i = 0; i < outPoints->size(); i++ )
  1406. objToWorld.mulP( (*outPoints)[i] );
  1407. }
  1408. }
  1409. void ConvexShape::Geometry::generate(const Vector< PlaneF > &planes, const Vector< Point3F > &tangents, const Vector< surfaceMaterial > surfaceTextures, const Vector< Point2F > texOffset, const Vector< Point2F > texScale, const Vector< bool > horzFlip, const Vector< bool > vertFlip)
  1410. {
  1411. PROFILE_SCOPE( Geometry_generate );
  1412. points.clear();
  1413. faces.clear();
  1414. AssertFatal( planes.size() == tangents.size(), "ConvexShape - incorrect plane/tangent count." );
  1415. #ifdef TORQUE_ENABLE_ASSERTS
  1416. for ( S32 i = 0; i < planes.size(); i++ )
  1417. {
  1418. F32 dt = mDot( planes[i], tangents[i] );
  1419. AssertFatal( mIsZero( dt, 0.0001f ), "ConvexShape - non perpendicular input vectors." );
  1420. AssertFatal( planes[i].isUnitLength() && tangents[i].isUnitLength(), "ConvexShape - non unit length input vector." );
  1421. }
  1422. #endif
  1423. const U32 planeCount = planes.size();
  1424. Point3F linePt, lineDir;
  1425. for ( S32 i = 0; i < planeCount; i++ )
  1426. {
  1427. Vector< MathUtils::Line > collideLines;
  1428. // Find the lines defined by the intersection of this plane with all others.
  1429. for ( S32 j = 0; j < planeCount; j++ )
  1430. {
  1431. if ( i == j )
  1432. continue;
  1433. if ( planes[i].intersect( planes[j], linePt, lineDir ) )
  1434. {
  1435. collideLines.increment();
  1436. MathUtils::Line &line = collideLines.last();
  1437. line.origin = linePt;
  1438. line.direction = lineDir;
  1439. }
  1440. }
  1441. if ( collideLines.empty() )
  1442. continue;
  1443. // Find edges and points defined by the intersection of these lines.
  1444. // As we find them we fill them into our working ConvexShape::Face
  1445. // structure.
  1446. Face newFace;
  1447. for ( S32 j = 0; j < collideLines.size(); j++ )
  1448. {
  1449. Vector< Point3F > collidePoints;
  1450. for ( S32 k = 0; k < collideLines.size(); k++ )
  1451. {
  1452. if ( j == k )
  1453. continue;
  1454. MathUtils::LineSegment segment;
  1455. MathUtils::mShortestSegmentBetweenLines( collideLines[j], collideLines[k], &segment );
  1456. F32 dist = ( segment.p0 - segment.p1 ).len();
  1457. if ( dist < 0.0005f )
  1458. {
  1459. S32 l = 0;
  1460. for ( ; l < planeCount; l++ )
  1461. {
  1462. if ( planes[l].whichSide( segment.p0 ) == PlaneF::Front )
  1463. break;
  1464. }
  1465. if ( l == planeCount )
  1466. collidePoints.push_back( segment.p0 );
  1467. }
  1468. }
  1469. //AssertFatal( collidePoints.size() <= 2, "A line can't collide with more than 2 other lines in a convex shape..." );
  1470. if ( collidePoints.size() != 2 )
  1471. continue;
  1472. // Push back collision points into our points vector
  1473. // if they are not duplicates and determine the id
  1474. // index for those points to be used by Edge(s).
  1475. const Point3F &pnt0 = collidePoints[0];
  1476. const Point3F &pnt1 = collidePoints[1];
  1477. S32 idx0 = -1;
  1478. S32 idx1 = -1;
  1479. for ( S32 k = 0; k < points.size(); k++ )
  1480. {
  1481. if ( pnt0.equal( points[k] ) )
  1482. {
  1483. idx0 = k;
  1484. break;
  1485. }
  1486. }
  1487. for ( S32 k = 0; k < points.size(); k++ )
  1488. {
  1489. if ( pnt1.equal( points[k] ) )
  1490. {
  1491. idx1 = k;
  1492. break;
  1493. }
  1494. }
  1495. if ( idx0 == -1 )
  1496. {
  1497. points.push_back( pnt0 );
  1498. idx0 = points.size() - 1;
  1499. }
  1500. if ( idx1 == -1 )
  1501. {
  1502. points.push_back( pnt1 );
  1503. idx1 = points.size() - 1;
  1504. }
  1505. // Construct the Face::Edge defined by this collision.
  1506. S32 localIdx0 = newFace.points.push_back_unique( idx0 );
  1507. S32 localIdx1 = newFace.points.push_back_unique( idx1 );
  1508. newFace.edges.increment();
  1509. ConvexShape::Edge &newEdge = newFace.edges.last();
  1510. newEdge.p0 = localIdx0;
  1511. newEdge.p1 = localIdx1;
  1512. }
  1513. if ( newFace.points.size() < 3 )
  1514. continue;
  1515. //AssertFatal( newFace.points.size() == newFace.edges.size(), "ConvexShape - face point count does not equal edge count." );
  1516. // Fill in some basic Face information.
  1517. newFace.id = i;
  1518. newFace.normal = planes[i];
  1519. newFace.tangent = tangents[i];
  1520. // Make a working array of Point3Fs on this face.
  1521. U32 pntCount = newFace.points.size();
  1522. Point3F *workPoints = new Point3F[ pntCount ];
  1523. for ( S32 j = 0; j < pntCount; j++ )
  1524. workPoints[j] = points[ newFace.points[j] ];
  1525. // Calculate the average point for calculating winding order.
  1526. Point3F averagePnt = Point3F::Zero;
  1527. for ( S32 j = 0; j < pntCount; j++ )
  1528. averagePnt += workPoints[j];
  1529. averagePnt /= pntCount;
  1530. // Sort points in correct winding order.
  1531. U32 *vertMap = new U32[pntCount];
  1532. MatrixF quadMat( true );
  1533. quadMat.setPosition( averagePnt );
  1534. quadMat.setColumn( 0, newFace.tangent );
  1535. quadMat.setColumn( 1, mCross( newFace.normal, newFace.tangent ) );
  1536. quadMat.setColumn( 2, newFace.normal );
  1537. quadMat.inverse();
  1538. // Transform working points into quad space
  1539. // so we can work with them as 2D points.
  1540. for ( S32 j = 0; j < pntCount; j++ )
  1541. quadMat.mulP( workPoints[j] );
  1542. MathUtils::sortQuadWindingOrder( true, workPoints, vertMap, pntCount );
  1543. // Save points in winding order.
  1544. for ( S32 j = 0; j < pntCount; j++ )
  1545. newFace.winding.push_back( vertMap[j] );
  1546. // Calculate the area and centroid of the face.
  1547. newFace.area = 0.0f;
  1548. for ( S32 j = 0; j < pntCount; j++ )
  1549. {
  1550. S32 k = ( j + 1 ) % pntCount;
  1551. const Point3F &p0 = workPoints[ vertMap[j] ];
  1552. const Point3F &p1 = workPoints[ vertMap[k] ];
  1553. // Note that this calculation returns positive area for clockwise winding
  1554. // and negative area for counterclockwise winding.
  1555. newFace.area += p0.y * p1.x;
  1556. newFace.area -= p0.x * p1.y;
  1557. }
  1558. //AssertFatal( newFace.area > 0.0f, "ConvexShape - face area was not positive." );
  1559. if ( newFace.area > 0.0f )
  1560. newFace.area /= 2.0f;
  1561. F32 factor;
  1562. F32 cx = 0.0f, cy = 0.0f;
  1563. for ( S32 j = 0; j < pntCount; j++ )
  1564. {
  1565. S32 k = ( j + 1 ) % pntCount;
  1566. const Point3F &p0 = workPoints[ vertMap[j] ];
  1567. const Point3F &p1 = workPoints[ vertMap[k] ];
  1568. factor = p0.x * p1.y - p1.x * p0.y;
  1569. cx += ( p0.x + p1.x ) * factor;
  1570. cy += ( p0.y + p1.y ) * factor;
  1571. }
  1572. factor = 1.0f / ( newFace.area * 6.0f );
  1573. newFace.centroid.set( cx * factor, cy * factor, 0.0f );
  1574. quadMat.inverse();
  1575. quadMat.mulP( newFace.centroid );
  1576. delete [] workPoints;
  1577. workPoints = NULL;
  1578. // Make polygons / triangles for this face.
  1579. const U32 polyCount = pntCount - 2;
  1580. newFace.triangles.setSize( polyCount );
  1581. for ( S32 j = 0; j < polyCount; j++ )
  1582. {
  1583. ConvexShape::Triangle &poly = newFace.triangles[j];
  1584. poly.p0 = vertMap[0];
  1585. if ( j == 0 )
  1586. {
  1587. poly.p1 = vertMap[ 1 ];
  1588. poly.p2 = vertMap[ 2 ];
  1589. }
  1590. else
  1591. {
  1592. poly.p1 = vertMap[ 1 + j ];
  1593. poly.p2 = vertMap[ 2 + j ];
  1594. }
  1595. }
  1596. delete [] vertMap;
  1597. // Calculate texture coordinates for each point in this face.
  1598. const Point3F binormal = mCross( newFace.normal, newFace.tangent );
  1599. PlaneF planey( newFace.centroid - 0.5f * binormal, binormal );
  1600. PlaneF planex( newFace.centroid - 0.5f * newFace.tangent, newFace.tangent );
  1601. newFace.texcoords.setSize( newFace.points.size() );
  1602. for ( S32 j = 0; j < newFace.points.size(); j++ )
  1603. {
  1604. F32 x = planex.distToPlane( points[ newFace.points[ j ] ] );
  1605. F32 y = planey.distToPlane( points[ newFace.points[ j ] ] );
  1606. if (!texOffset.empty())
  1607. {
  1608. x += texOffset[i].x;
  1609. y += texOffset[i].y;
  1610. }
  1611. //now scale
  1612. if (!texScale.empty() && !texScale[i].isZero())
  1613. {
  1614. x *= (texScale[i].x);
  1615. y *= (texScale[i].y);
  1616. }
  1617. if (horzFlip.size() > 0 && horzFlip[i])
  1618. x *= -1;
  1619. if (vertFlip.size() > 0 && vertFlip[i])
  1620. y *= -1;
  1621. newFace.texcoords[j].set(-x, -y);
  1622. }
  1623. // Data verification tests.
  1624. #ifdef TORQUE_ENABLE_ASSERTS
  1625. //S32 triCount = newFace.triangles.size();
  1626. //S32 edgeCount = newFace.edges.size();
  1627. //AssertFatal( triCount == edgeCount - 2, "ConvexShape - triangle/edge count do not match." );
  1628. /*
  1629. for ( S32 j = 0; j < triCount; j++ )
  1630. {
  1631. F32 area = MathUtils::mTriangleArea( points[ newFace.points[ newFace.triangles[j][0] ] ],
  1632. points[ newFace.points[ newFace.triangles[j][1] ] ],
  1633. points[ newFace.points[ newFace.triangles[j][2] ] ] );
  1634. AssertFatal( area > 0.0f, "ConvexShape - triangle winding bad." );
  1635. }*/
  1636. #endif
  1637. // Done with this Face.
  1638. faces.push_back( newFace );
  1639. }
  1640. }
  1641. DEF_ASSET_BINDS(ConvexShape, Material);