river.cpp 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581
  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 "environment/river.h"
  24. #include "console/consoleTypes.h"
  25. #include "console/engineAPI.h"
  26. #include "util/catmullRom.h"
  27. #include "math/util/quadTransforms.h"
  28. #include "scene/simPath.h"
  29. #include "scene/sceneRenderState.h"
  30. #include "scene/sceneManager.h"
  31. #include "materials/sceneData.h"
  32. #include "materials/baseMatInstance.h"
  33. #include "scene/sgUtil.h"
  34. #include "T3D/gameBase/gameConnection.h"
  35. #include "core/stream/bitStream.h"
  36. #include "gfx/gfxDrawUtil.h"
  37. #include "gfx/gfxTransformSaver.h"
  38. #include "gfx/primBuilder.h"
  39. #include "gfx/gfxDebugEvent.h"
  40. #include "gfx/gfxOcclusionQuery.h"
  41. #include "math/mathIO.h"
  42. #include "math/mathUtils.h"
  43. #include "math/util/frustum.h"
  44. #include "math/util/quadTransforms.h"
  45. #include "gui/3d/guiTSControl.h"
  46. #include "gfx/sim/debugDraw.h"
  47. #include "T3D/fx/particleEmitter.h"
  48. #include "scene/reflectionManager.h"
  49. #include "ts/tsShapeInstance.h"
  50. #include "postFx/postEffect.h"
  51. #include "math/util/matrixSet.h"
  52. #include "environment/nodeListManager.h"
  53. ConsoleDocClass( River,
  54. "@brief A water volume defined by a 3D spline.\n\n"
  55. "User may control width and depth per node and overall spline shape in three "
  56. "dimensions.\n\n"
  57. "%River supports dynamic planar reflections (fullReflect) like all WaterObject "
  58. "classes, but keep in mind it is not necessarily a planar surface. For best "
  59. "visual quality a %River should be less reflective the more it twists and "
  60. "bends. This caution only applies to %Rivers with fullReflect on.\n\n"
  61. "@see WaterObject for inherited functionality.\n\n"
  62. "@ingroup Water"
  63. );
  64. #define MIN_METERS_PER_SEGMENT 1.0f
  65. #define MIN_NODE_DEPTH 0.25f
  66. #define MAX_NODE_DEPTH 500.0f
  67. #define MIN_NODE_WIDTH 0.25f
  68. #define MAX_NODE_WIDTH 1000.0f
  69. #define NODE_RADIUS 15.0f
  70. static U32 gIdxArray[6][2][3] = {
  71. { { 0, 4, 5 }, { 0, 5, 1 }, }, // Top Face
  72. { { 2, 6, 4 }, { 2, 4, 0 }, }, // Left Face
  73. { { 1, 5, 7 }, { 1, 7, 3 }, }, // Right Face
  74. { { 2, 3, 7 }, { 2, 7, 6 }, }, // Bottom Face
  75. { { 0, 1, 3 }, { 0, 3, 2 }, }, // Front Face
  76. { { 4, 6, 7 }, { 4, 7, 5 }, }, // Back Face
  77. };
  78. struct RiverHitSegment
  79. {
  80. U32 idx;
  81. F32 t;
  82. };
  83. static S32 QSORT_CALLBACK compareHitSegments(const void* a,const void* b)
  84. {
  85. const RiverHitSegment *fa = (RiverHitSegment*)a;
  86. const RiverHitSegment *fb = (RiverHitSegment*)b;
  87. return mSign(fb->t - fa->t);
  88. }
  89. static Point3F sSegmentPointComparePoints[4];
  90. //-----------------------------------------------------------------------------
  91. // DecalRoadNodeList Struct
  92. //-----------------------------------------------------------------------------
  93. struct RiverNodeList : public NodeListManager::NodeList
  94. {
  95. Vector<Point3F> mPositions;
  96. Vector<F32> mWidths;
  97. Vector<F32> mDepths;
  98. Vector<VectorF> mNormals;
  99. RiverNodeList() { }
  100. virtual ~RiverNodeList() { }
  101. };
  102. //-----------------------------------------------------------------------------
  103. // RiverNodeEvent Class
  104. //-----------------------------------------------------------------------------
  105. class RiverNodeEvent : public NodeListEvent
  106. {
  107. typedef NodeListEvent Parent;
  108. public:
  109. Vector<Point3F> mPositions;
  110. Vector<F32> mWidths;
  111. Vector<F32> mDepths;
  112. Vector<VectorF> mNormals;
  113. public:
  114. RiverNodeEvent() { mNodeList = NULL; }
  115. virtual ~RiverNodeEvent() { }
  116. void pack(NetConnection*, BitStream*) override;
  117. void unpack(NetConnection*, BitStream*) override;
  118. void copyIntoList(NodeListManager::NodeList* copyInto) override;
  119. void padListToSize() override;
  120. DECLARE_CONOBJECT(RiverNodeEvent);
  121. };
  122. void RiverNodeEvent::pack(NetConnection* conn, BitStream* stream)
  123. {
  124. Parent::pack( conn, stream );
  125. stream->writeInt( mPositions.size(), 16 );
  126. for (U32 i=0; i<mPositions.size(); ++i)
  127. {
  128. mathWrite( *stream, mPositions[i] );
  129. stream->write( mWidths[i] );
  130. stream->write( mDepths[i] );
  131. mathWrite( *stream, mNormals[i] );
  132. }
  133. }
  134. void RiverNodeEvent::unpack(NetConnection* conn, BitStream* stream)
  135. {
  136. mNodeList = new RiverNodeList();
  137. Parent::unpack( conn, stream );
  138. U32 count = stream->readInt( 16 );
  139. Point3F pos;
  140. F32 width, depth;
  141. VectorF normal;
  142. RiverNodeList* list = static_cast<RiverNodeList*>(mNodeList);
  143. for (U32 i=0; i<count; ++i)
  144. {
  145. mathRead( *stream, &pos );
  146. stream->read( &width );
  147. stream->read( &depth );
  148. mathRead( *stream, &normal );
  149. list->mPositions.push_back( pos );
  150. list->mWidths.push_back( width );
  151. list->mDepths.push_back( depth );
  152. list->mNormals.push_back( normal );
  153. }
  154. list->mTotalValidNodes = count;
  155. // Do we have a complete list?
  156. if (list->mPositions.size() >= mTotalNodes)
  157. list->mListComplete = true;
  158. }
  159. void RiverNodeEvent::copyIntoList(NodeListManager::NodeList* copyInto)
  160. {
  161. RiverNodeList* prevList = dynamic_cast<RiverNodeList*>(copyInto);
  162. RiverNodeList* list = static_cast<RiverNodeList*>(mNodeList);
  163. // Merge our list with the old list.
  164. for (U32 i=mLocalListStart, index=0; i<mLocalListStart+list->mPositions.size(); ++i, ++index)
  165. {
  166. prevList->mPositions[i] = list->mPositions[index];
  167. prevList->mWidths[i] = list->mWidths[index];
  168. prevList->mDepths[i] = list->mDepths[index];
  169. prevList->mNormals[i] = list->mNormals[index];
  170. }
  171. }
  172. void RiverNodeEvent::padListToSize()
  173. {
  174. RiverNodeList* list = static_cast<RiverNodeList*>(mNodeList);
  175. U32 totalValidNodes = list->mTotalValidNodes;
  176. // Pad our list front?
  177. if (mLocalListStart)
  178. {
  179. RiverNodeList* newlist = new RiverNodeList();
  180. newlist->mPositions.increment(mLocalListStart);
  181. newlist->mWidths.increment(mLocalListStart);
  182. newlist->mDepths.increment(mLocalListStart);
  183. newlist->mNormals.increment(mLocalListStart);
  184. newlist->mPositions.merge(list->mPositions);
  185. newlist->mWidths.merge(list->mWidths);
  186. newlist->mDepths.merge(list->mDepths);
  187. newlist->mNormals.merge(list->mNormals);
  188. delete list;
  189. mNodeList = list = newlist;
  190. }
  191. // Pad our list end?
  192. if (list->mPositions.size() < mTotalNodes)
  193. {
  194. U32 delta = mTotalNodes - list->mPositions.size();
  195. list->mPositions.increment(delta);
  196. list->mWidths.increment(delta);
  197. list->mDepths.increment(delta);
  198. list->mNormals.increment(delta);
  199. }
  200. list->mTotalValidNodes = totalValidNodes;
  201. }
  202. IMPLEMENT_CO_NETEVENT_V1(RiverNodeEvent);
  203. ConsoleDocClass( RiverNodeEvent,
  204. "@brief Sends messages to the River Editor\n\n"
  205. "Editor use only.\n\n"
  206. "@internal"
  207. );
  208. //-----------------------------------------------------------------------------
  209. // RiverNodeListNotify Class
  210. //-----------------------------------------------------------------------------
  211. class RiverNodeListNotify : public NodeListNotify
  212. {
  213. typedef NodeListNotify Parent;
  214. protected:
  215. SimObjectPtr<River> mRiver;
  216. public:
  217. RiverNodeListNotify( River* river, U32 listId ) { mRiver = river; mListId = listId; }
  218. virtual ~RiverNodeListNotify() { mRiver = NULL; }
  219. void sendNotification( NodeListManager::NodeList* list ) override;
  220. };
  221. void RiverNodeListNotify::sendNotification( NodeListManager::NodeList* list )
  222. {
  223. if (mRiver.isValid())
  224. {
  225. // Build the road's nodes
  226. RiverNodeList* riverList = dynamic_cast<RiverNodeList*>( list );
  227. if (riverList)
  228. mRiver->buildNodesFromList( riverList );
  229. }
  230. }
  231. //------------------------------------------------------------------------------
  232. // Class: RiverSegment
  233. //------------------------------------------------------------------------------
  234. RiverSegment::RiverSegment()
  235. {
  236. mPlaneCount = 0;
  237. columns = 0;
  238. rows = 0;
  239. numVerts = 0;
  240. numTriangles = 0;
  241. startVert = 0;
  242. endVert = 0;
  243. startIndex = 0;
  244. endIndex = 0;
  245. slice0 = NULL;
  246. slice1 = NULL;
  247. }
  248. RiverSegment::RiverSegment( RiverSlice *rs0, RiverSlice *rs1 )
  249. {
  250. columns = 0;
  251. rows = 0;
  252. numVerts = 0;
  253. numTriangles = 0;
  254. startVert = 0;
  255. endVert = 0;
  256. startIndex = 0;
  257. endIndex = 0;
  258. slice0 = rs0;
  259. slice1 = rs1;
  260. // Calculate the planes for this segment
  261. // Will be used for intersection/buoyancy tests
  262. VectorF normal;
  263. mPlaneCount = 6;
  264. sSegmentPointCompareReference = getFaceCenter(6);
  265. // left
  266. mPlanes[0] = _getBestPlane( &slice1->p0, &slice1->pb0, &slice0->pb0, &slice0->p0 );
  267. // right
  268. mPlanes[1] = _getBestPlane( &slice0->pb2, &slice1->pb2, &slice1->p2, &slice0->p2 );
  269. // near
  270. mPlanes[2] = _getBestPlane( &slice0->pb0, &slice0->pb2, &slice0->p2, &slice0->p0 );
  271. // far
  272. mPlanes[3] = _getBestPlane( &slice1->pb2, &slice1->pb0, &slice1->p0, &slice1->p2 );
  273. // top
  274. mPlanes[4] = _getBestPlane( &slice0->p2, &slice1->p2, &slice1->p0, &slice0->p0 );
  275. // bottom
  276. mPlanes[5] = _getBestPlane( &slice0->pb2, &slice0->pb0, &slice1->pb0, &slice1->pb2 );
  277. // Calculate the bounding box(s)
  278. worldbounds.minExtents = worldbounds.maxExtents = rs0->p0;
  279. worldbounds.extend( rs0->p2 );
  280. worldbounds.extend( rs0->pb0 );
  281. worldbounds.extend( rs0->pb2 );
  282. worldbounds.extend( rs1->p0 );
  283. worldbounds.extend( rs1->p2 );
  284. worldbounds.extend( rs1->pb0 );
  285. worldbounds.extend( rs1->pb2 );
  286. /*
  287. // Calculate tetrahedrons (for collision and buoyancy testing)
  288. // This is 0 in the diagram.
  289. mCubePoints[0] = cornerPoint;
  290. mCubePoints[1] = cornerPoint + (VectorF( 1.0f, 0.0f, 0.0f ) * size );
  291. mCubePoints[2] = cornerPoint + (VectorF( 0.0f, 1.0f, 0.0f ) * size );
  292. mCubePoints[3] = cornerPoint + (VectorF( 1.0f, 1.0f, 0.0f ) * size );
  293. mCubePoints[4] = cornerPoint + (VectorF( 0.0f, 0.0f, 1.0f );
  294. mCubePoints[5] = cornerPoint + (VectorF( 1.0f, 0.0f, 1.0f );
  295. mCubePoints[6] = cornerPoint + (VectorF( 0.0f, 1.0f, 1.0f );
  296. mCubePoints[7] = cornerPoint + (VectorF( 1.0f, 1.0f, 1.0f );
  297. // Center tetra.
  298. mTetras[0].p0 = &mCubePoints[1];
  299. mTetras[0].p1 = &mCubePoints[2];
  300. mTetras[0].p2 = &mCubePoints[4];
  301. mTetras[0].p3 = &mCubePoints[7];
  302. mTetras[1].p0 = &mCubePoints[0]; // this is the tip
  303. mTetras[1].p1 = &mCubePoints[1];
  304. mTetras[1].p2 = &mCubePoints[2];
  305. mTetras[1].p3 = &mCubePoints[4];
  306. mTetras[2].p0 = &mCubePoints[3]; // tip
  307. mTetras[2].p1 = &mCubePoints[2];
  308. mTetras[2].p2 = &mCubePoints[1];
  309. mTetras[2].p3 = &mCubePoints[7];
  310. mTetras[3].p0 = &mCubePoints[6]; // tip
  311. mTetras[3].p1 = &mCubePoints[7];
  312. mTetras[3].p2 = &mCubePoints[4];
  313. mTetras[3].p3 = &mCubePoints[2];
  314. mTetras[4].p0 = &mCubePoints[5]; // tip
  315. mTetras[4].p1 = &mCubePoints[7];
  316. mTetras[4].p2 = &mCubePoints[4];
  317. mTetras[4].p3 = &mCubePoints[3];*/
  318. }
  319. void RiverSegment::set( RiverSlice *rs0, RiverSlice *rs1 )
  320. {
  321. columns = 0;
  322. rows = 0;
  323. numVerts = 0;
  324. numTriangles = 0;
  325. startVert = 0;
  326. endVert = 0;
  327. startIndex = 0;
  328. endIndex = 0;
  329. slice0 = rs0;
  330. slice1 = rs1;
  331. }
  332. static S32 QSORT_CALLBACK SegmentPointCompare(const void *aptr, const void *bptr)
  333. {
  334. const U32 a = *(const U32*)aptr;
  335. const U32 b = *(const U32*)bptr;
  336. F32 lenA = ( sSegmentPointCompareReference - sSegmentPointComparePoints[a] ).lenSquared();
  337. F32 lenB = ( sSegmentPointCompareReference - sSegmentPointComparePoints[b] ).lenSquared();
  338. return ( lenB - lenA );
  339. }
  340. PlaneF RiverSegment::_getBestPlane( const Point3F *p0, const Point3F *p1, const Point3F *p2, const Point3F *p3 )
  341. {
  342. sSegmentPointComparePoints[0] = *p0;
  343. sSegmentPointComparePoints[1] = *p1;
  344. sSegmentPointComparePoints[2] = *p2;
  345. sSegmentPointComparePoints[3] = *p3;
  346. Point3F points[4] = {
  347. *p0, *p1, *p2, *p3
  348. };
  349. U32 indices[4] = {
  350. 0,1,2,3
  351. };
  352. dQsort(indices, 4, sizeof(U32), SegmentPointCompare);
  353. // Collect the best three points (in correct winding order)
  354. // To generate the plane's normal
  355. Vector<Point3F> normalPnts;
  356. for ( U32 i = 0; i < 4; i++ )
  357. {
  358. if ( i == indices[3] )
  359. continue;
  360. normalPnts.push_back(points[i]);
  361. }
  362. PlaneF plane( normalPnts[0], normalPnts[1], normalPnts[2] );
  363. return plane;
  364. }
  365. Point3F RiverSegment::getFaceCenter( U32 faceIdx ) const
  366. {
  367. Point3F center(0,0,0);
  368. switch ( faceIdx )
  369. {
  370. case 0: // left
  371. center = slice1->p0 + slice0->p0 + slice0->pb0 + slice1->pb0;
  372. center *= 0.25f;
  373. break;
  374. case 1: // right
  375. center = slice0->p2 + slice1->p2 + slice1->pb2 + slice0->pb2;
  376. center *= 0.25f;
  377. break;
  378. case 2: // near
  379. center = slice0->p0 + slice0->p2 + slice0->pb2 + slice0->pb0;
  380. center *= 0.25f;
  381. break;
  382. case 3: // far
  383. center = slice1->pb0 + slice1->p0 + slice1->pb0 + slice1->pb2;
  384. center *= 0.25f;
  385. break;
  386. case 4: // top
  387. center = slice0->p0 + slice1->p0 + slice1->p2 + slice0->p2;
  388. center *= 0.25f;
  389. break;
  390. case 5: // bottom
  391. center = slice1->pb2 + slice1->pb0 + slice0->pb0 + slice0->pb2;
  392. center *= 0.25f;
  393. break;
  394. case 6: // segment center
  395. center = slice0->p0 + slice0->p2 + slice1->p0 + slice1->p2 + slice0->pb0 + slice0->pb2 + slice1->pb0 + slice1->pb2;
  396. center /= 8;
  397. break;
  398. }
  399. return center;
  400. }
  401. bool RiverSegment::intersectBox( const Box3F &bounds ) const
  402. {
  403. // This code copied from Frustum class.
  404. Point3F maxPoint;
  405. F32 maxDot;
  406. // Note the planes are ordered left, right, near,
  407. // far, top, bottom for getting early rejections
  408. // from the typical horizontal scene.
  409. for ( S32 i = 0; i < mPlaneCount; i++ )
  410. {
  411. // This is pretty much as optimal as you can
  412. // get for a plane vs AABB test...
  413. //
  414. // 4 comparisons
  415. // 3 multiplies
  416. // 2 adds
  417. // 1 negation
  418. //
  419. // It will early out as soon as it detects the
  420. // bounds is outside one of the planes.
  421. if ( mPlanes[i].x > 0 )
  422. maxPoint.x = bounds.maxExtents.x;
  423. else
  424. maxPoint.x = bounds.minExtents.x;
  425. if ( mPlanes[i].y > 0 )
  426. maxPoint.y = bounds.maxExtents.y;
  427. else
  428. maxPoint.y = bounds.minExtents.y;
  429. if ( mPlanes[i].z > 0 )
  430. maxPoint.z = bounds.maxExtents.z;
  431. else
  432. maxPoint.z = bounds.minExtents.z;
  433. maxDot = mDot( maxPoint, mPlanes[ i ] );
  434. if ( maxDot <= -mPlanes[ i ].d )
  435. return false;
  436. }
  437. return true;
  438. }
  439. bool RiverSegment::containsPoint( const Point3F &pnt ) const
  440. {
  441. // NOTE: this code from Frustum class.
  442. F32 maxDot;
  443. // Note the planes are ordered left, right, near,
  444. // far, top, bottom for getting early rejections
  445. // from the typical horizontal scene.
  446. for ( S32 i = 0; i < mPlaneCount; i++ )
  447. {
  448. const PlaneF &plane = mPlanes[ i ];
  449. // This is pretty much as optimal as you can
  450. // get for a plane vs point test...
  451. //
  452. // 1 comparison
  453. // 2 multiplies
  454. // 1 adds
  455. //
  456. // It will early out as soon as it detects the
  457. // point is outside one of the planes.
  458. maxDot = mDot( pnt, plane ) + plane.d;
  459. if ( maxDot < -0.1f )
  460. return false;
  461. }
  462. return true;
  463. }
  464. F32 RiverSegment::distanceToSurface(const Point3F &pnt) const
  465. {
  466. return mPlanes[4].distToPlane( pnt );
  467. }
  468. bool River::smEditorOpen = false;
  469. bool River::smWireframe = false;
  470. bool River::smShowWalls = false;
  471. bool River::smShowNodes = false;
  472. bool River::smShowSpline = true;
  473. bool River::smShowRiver = true;
  474. SimObjectPtr<SimSet> River::smServerRiverSet = NULL;
  475. IMPLEMENT_CO_NETOBJECT_V1(River);
  476. River::River()
  477. : mLowVertCount(0),
  478. mHighVertCount(0),
  479. mLowTriangleCount(0),
  480. mHighTriangleCount(0),
  481. mSegmentsPerBatch(10),
  482. mMetersPerSegment(10.0f),
  483. mDepthScale(1.0f),
  484. mFlowMagnitude(1.0f),
  485. mLodDistance( 50.0f ),
  486. mMaxDivisionSize(2.5f),
  487. mMinDivisionSize(0.25f),
  488. mColumnCount(5)
  489. {
  490. mNetFlags.set( Ghostable | ScopeAlways );
  491. mObjScale.set( 1, 1, 1 );
  492. mObjBox.minExtents.set( -0.5, -0.5, -0.5 );
  493. mObjBox.maxExtents.set( 0.5, 0.5, 0.5 );
  494. mReflectNormalUp = false;
  495. // We use the shader const miscParams.w to signify
  496. // that this object is a River.
  497. mMiscParamW = 1.0f;
  498. }
  499. River::~River()
  500. {
  501. }
  502. FRangeValidator riverSegRange(MIN_METERS_PER_SEGMENT, FLT_MAX);
  503. void River::initPersistFields()
  504. {
  505. docsURL;
  506. addGroup( "River" );
  507. addFieldV( "SegmentLength", TypeRangedF32, Offset( mMetersPerSegment, River ), &riverSegRange,
  508. "Divide the River lengthwise into segments of this length in meters. "
  509. "These geometric volumes are used for spacial queries like determining containment." );
  510. addFieldV( "SubdivideLength", TypeRangedF32, Offset( mMaxDivisionSize, River ), &CommonValidators::PositiveFloat,
  511. "For purposes of generating the renderable geometry River segments are further subdivided "
  512. "such that no quad is of greater width or length than this distance in meters." );
  513. addFieldV( "FlowMagnitude", TypeRangedF32, Offset( mFlowMagnitude, River ), &CommonValidators::F32Range,
  514. "Magnitude of the force vector applied to dynamic objects within the River." );
  515. addFieldV( "LowLODDistance", TypeRangedF32, Offset( mLodDistance, River ), &CommonValidators::PositiveFloat,
  516. "Segments of the river at this distance in meters or greater will "
  517. "render as a single unsubdivided without undulation effects." );
  518. endGroup( "River" );
  519. addGroup( "Internal" );
  520. addProtectedField( "Node", TypeString, 0, &addNodeFromField, &emptyStringProtectedGetFn, "For internal use, do not modify.",
  521. AbstractClassRep::FIELD_HideInInspectors | AbstractClassRep::FIELD_SpecialtyArrayField);
  522. endGroup( "Internal" );
  523. Parent::initPersistFields();
  524. }
  525. void River::consoleInit()
  526. {
  527. Parent::consoleInit();
  528. Con::addVariable( "$River::EditorOpen", TypeBool, &River::smEditorOpen, "For editor use.\n"
  529. "@ingroup Editors\n" );
  530. Con::addVariable( "$River::showWalls", TypeBool, &River::smShowWalls, "For editor use.\n"
  531. "@ingroup Editors\n" );
  532. Con::addVariable( "$River::showNodes", TypeBool, &River::smShowNodes, "For editor use.\n"
  533. "@ingroup Editors\n");
  534. Con::addVariable( "$River::showSpline", TypeBool, &River::smShowSpline, "For editor use.\n"
  535. "@ingroup Editors\n" );
  536. Con::addVariable( "$River::showRiver", TypeBool, &River::smShowRiver, "For editor use.\n"
  537. "@ingroup Editors\n" );
  538. Con::addVariable( "$River::showWireframe", TypeBool, &River::smWireframe, "For editor use.\n"
  539. "@ingroup Editors\n");
  540. }
  541. bool River::addNodeFromField( void *object, const char *index, const char *data )
  542. {
  543. River *pObj = static_cast<River*>(object);
  544. //if ( !pObj->isProperlyAdded() )
  545. //{
  546. F32 x,y,z,width,depth;
  547. VectorF normal;
  548. U32 result = dSscanf( data, "%f %f %f %f %f %f %f %f", &x, &y, &z, &width, &depth, &normal.x, &normal.y, &normal.z );
  549. if ( result == 8 )
  550. pObj->_addNode( Point3F(x,y,z), width, depth, normal );
  551. //}
  552. return false;
  553. }
  554. bool River::onAdd()
  555. {
  556. if ( !Parent::onAdd() )
  557. return false;
  558. // Reset the World Box.
  559. //setGlobalBounds();
  560. resetWorldBox();
  561. // Set the Render Transform.
  562. setRenderTransform(mObjToWorld);
  563. // Add to Scene.
  564. addToScene();
  565. if ( isServerObject() )
  566. getServerSet()->addObject( this );
  567. _regenerate();
  568. return true;
  569. }
  570. void River::onRemove()
  571. {
  572. removeFromScene();
  573. Parent::onRemove();
  574. }
  575. void River::inspectPostApply()
  576. {
  577. // Set Parent.
  578. Parent::inspectPostApply();
  579. if ( mMetersPerSegment < MIN_METERS_PER_SEGMENT )
  580. mMetersPerSegment = MIN_METERS_PER_SEGMENT;
  581. mMaxDivisionSize = getMax( mMaxDivisionSize, mMinDivisionSize );
  582. // Set fxPortal Mask.
  583. setMaskBits(RiverMask|RegenMask);
  584. }
  585. void River::onStaticModified( const char* slotName, const char*newValue )
  586. {
  587. Parent::onStaticModified( slotName, newValue );
  588. if ( dStricmp( slotName, "surfMaterial" ) == 0 )
  589. setMaskBits( MaterialMask );
  590. }
  591. SimSet* River::getServerSet()
  592. {
  593. if ( !smServerRiverSet )
  594. {
  595. smServerRiverSet = new SimSet();
  596. smServerRiverSet->registerObject( "ServerRiverSet" );
  597. Sim::getRootGroup()->addObject( smServerRiverSet );
  598. }
  599. return smServerRiverSet;
  600. }
  601. void River::writeFields( Stream &stream, U32 tabStop )
  602. {
  603. Parent::writeFields( stream, tabStop );
  604. // Now write all nodes
  605. stream.write(2, "\r\n");
  606. for ( U32 i = 0; i < mNodes.size(); i++ )
  607. {
  608. const RiverNode &node = mNodes[i];
  609. stream.writeTabs(tabStop);
  610. char buffer[1024];
  611. dMemset( buffer, 0, 1024 );
  612. dSprintf( buffer, 1024, "Node = \"%f %f %f %f %f %f %f %f\";", node.point.x, node.point.y, node.point.z,
  613. node.width,
  614. node.depth,
  615. node.normal.x, node.normal.y, node.normal.z );
  616. stream.writeLine( (const U8*)buffer );
  617. }
  618. }
  619. bool River::writeField( StringTableEntry fieldname, const char *value )
  620. {
  621. if ( fieldname == StringTable->insert("node") )
  622. return false;
  623. return Parent::writeField( fieldname, value );
  624. }
  625. U32 River::getSpecialFieldSize(StringTableEntry fieldName)
  626. {
  627. if (fieldName == StringTable->insert("node"))
  628. {
  629. return mNodes.size();
  630. }
  631. return 0;
  632. }
  633. const char* River::getSpecialFieldOut(StringTableEntry fieldName, const U32& index)
  634. {
  635. if (fieldName == StringTable->insert("node"))
  636. {
  637. if (index >= mNodes.size())
  638. return NULL;
  639. const RiverNode& node = mNodes[index];
  640. char buffer[1024];
  641. dMemset(buffer, 0, 1024);
  642. dSprintf(buffer, 1024, "Node = \"%f %f %f %f %f %f %f %f\";", node.point.x, node.point.y, node.point.z,
  643. node.width,
  644. node.depth,
  645. node.normal.x, node.normal.y, node.normal.z);
  646. return StringTable->insert(buffer);
  647. }
  648. return NULL;
  649. }
  650. void River::innerRender( SceneRenderState *state )
  651. {
  652. GFXDEBUGEVENT_SCOPE( River_innerRender, ColorI( 255, 0, 0 ) );
  653. PROFILE_SCOPE( River_innerRender );
  654. // Setup SceneData
  655. SceneData sgData;
  656. sgData.init( state );
  657. sgData.lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
  658. sgData.backBuffTex = REFLECTMGR->getRefractTex();
  659. sgData.reflectTex = mPlaneReflector.reflectTex;
  660. sgData.wireframe |= smWireframe;
  661. const Point3F &camPosition = state->getCameraPosition();
  662. // set the material
  663. S32 matIdx = getMaterialIndex( camPosition );
  664. if ( !initMaterial( matIdx ) )
  665. return;
  666. BaseMatInstance *mat = mMatInstances[matIdx];
  667. WaterMatParams matParams = mMatParamHandles[matIdx];
  668. if ( !mat )
  669. return;
  670. // setup proj/world transform
  671. GFXTransformSaver saver;
  672. setShaderParams( state, mat, matParams );
  673. _makeRenderBatches( camPosition );
  674. if ( !River::smShowRiver )
  675. return;
  676. // If no material... we're done.
  677. if ( mLowLODBatches.empty() && mHighLODBatches.empty() )
  678. return;
  679. if ( !mHighLODBatches.empty() )
  680. _makeHighLODBuffers();
  681. mMatrixSet->restoreSceneViewProjection();
  682. mMatrixSet->setWorld( MatrixF::Identity );
  683. while( mat->setupPass( state, sgData ) )
  684. {
  685. mat->setSceneInfo(state, sgData);
  686. mat->setTransforms(*mMatrixSet, state);
  687. setCustomTextures( matIdx, mat->getCurPass(), matParams );
  688. GFX->setVertexBuffer( mVB_low );
  689. GFX->setPrimitiveBuffer( mPB_low );
  690. for ( U32 i = 0; i < mLowLODBatches.size(); i++ )
  691. {
  692. const RiverRenderBatch &batch = mLowLODBatches[i];
  693. U32 startVert = batch.startSegmentIdx * 2;
  694. U32 endVert = ( batch.endSegmentIdx + 1 ) * 2 + 1;
  695. U32 startIdx = batch.startSegmentIdx * 6;
  696. U32 endIdx = batch.endSegmentIdx * 6 + 5;
  697. U32 vertCount = ( endVert - startVert ) + 1;
  698. U32 idxCount = ( endIdx - startIdx ) + 1;
  699. U32 triangleCount = idxCount / 3;
  700. AssertFatal( startVert < mLowVertCount, "River, bad draw call!" );
  701. AssertFatal( startVert + vertCount <= mLowVertCount, "River, bad draw call!" );
  702. AssertFatal( triangleCount <= mLowTriangleCount, "River, bad draw call!" );
  703. GFX->drawIndexedPrimitive( GFXTriangleList, 0, startVert, vertCount, startIdx, triangleCount );
  704. }
  705. // Render all high detail batches.
  706. //
  707. // It is possible that the buffers could not be allocated because
  708. // the max number of verts/indices was exceeded. We don't want to
  709. // crash because that would be unhelpful for working in the editor.
  710. if ( mVB_high.isValid() && mPB_high.isValid() )
  711. {
  712. GFX->setVertexBuffer( mVB_high );
  713. GFX->setPrimitiveBuffer( mPB_high );
  714. for ( U32 i = 0; i < mHighLODBatches.size(); i++ )
  715. {
  716. const RiverRenderBatch &batch = mHighLODBatches[i];
  717. AssertFatal( batch.startVert < mHighVertCount, "River, bad draw call!" );
  718. AssertFatal( batch.startVert + batch.vertCount <= mHighVertCount, "River, bad draw call!" );
  719. AssertFatal( batch.triangleCount <= mHighTriangleCount, "River, bad draw call!" );
  720. AssertFatal( batch.startIndex < mHighTriangleCount * 3, "River, bad draw call!" );
  721. AssertFatal( batch.startIndex + batch.triangleCount * 3 <= mHighTriangleCount * 3, "River, bad draw call!" );
  722. GFX->drawIndexedPrimitive( GFXTriangleList,
  723. 0,
  724. 0,
  725. batch.vertCount,
  726. batch.startIndex,
  727. batch.triangleCount );
  728. }
  729. }
  730. } // while( mat->setupPass( sgData ) )
  731. }
  732. void River::updateUnderwaterEffect( SceneRenderState *state )
  733. {
  734. // Calculate mWaterPlane before calling updateUnderwaterEffect.
  735. Point3F dummy;
  736. _getWaterPlane( state->getCameraPosition(), mWaterFogData.plane, dummy );
  737. Parent::updateUnderwaterEffect( state );
  738. }
  739. void River::setShaderParams( SceneRenderState *state, BaseMatInstance* mat, const WaterMatParams& paramHandles )
  740. {
  741. // Set variables that will be assigned to shader consts within WaterCommon
  742. // before calling Parent::setShaderParams
  743. mUndulateMaxDist = mLodDistance;
  744. Parent::setShaderParams( state, mat, paramHandles );
  745. // Now set the rest of the shader consts that are either unique to this
  746. // class or that WaterObject leaves to us to handle...
  747. MaterialParameters* matParams = mat->getMaterialParameters();
  748. // set vertex shader constants
  749. //-----------------------------------
  750. matParams->setSafe(paramHandles.mGridElementSizeSC, 1.0f);
  751. if ( paramHandles.mModelMatSC->isValid() )
  752. matParams->set(paramHandles.mModelMatSC, MatrixF::Identity, GFXSCT_Float4x4);
  753. // set pixel shader constants
  754. //-----------------------------------
  755. LinearColorF c( mWaterFogData.color );
  756. matParams->setSafe(paramHandles.mBaseColorSC, c);
  757. // By default we need to show a true reflection is fullReflect is enabled and
  758. // we are above water.
  759. F32 reflect = mPlaneReflector.isEnabled() && !isUnderwater( state->getCameraPosition() );
  760. // If we were occluded the last frame a query was fetched ( not necessarily last frame )
  761. // and we weren't updated last frame... we don't have a valid texture to show
  762. // so use the cubemap / fake reflection color this frame.
  763. if ( mPlaneReflector.lastUpdateMs != REFLECTMGR->getLastUpdateMs() && mPlaneReflector.isOccluded() )
  764. reflect = false;
  765. Point4F reflectParams( mWaterPos.z, 0.0f, 1000.0f, !reflect );
  766. matParams->setSafe(paramHandles.mReflectParamsSC, reflectParams );
  767. matParams->setSafe(paramHandles.mReflectNormalSC, mPlaneReflector.refplane );
  768. }
  769. bool River::isUnderwater( const Point3F &pnt ) const
  770. {
  771. return containsPoint( pnt, NULL );
  772. }
  773. U32 River::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
  774. {
  775. // Pack Parent.
  776. U32 retMask = Parent::packUpdate(con, mask, stream);
  777. if ( stream->writeFlag( mask & RiverMask ) )
  778. {
  779. // Write Object Transform.
  780. stream->writeAffineTransform(mObjToWorld);
  781. stream->write( mMetersPerSegment );
  782. stream->write( mSegmentsPerBatch );
  783. stream->write( mDepthScale );
  784. stream->write( mMaxDivisionSize );
  785. stream->write( mColumnCount );
  786. stream->write( mFlowMagnitude );
  787. stream->write( mLodDistance );
  788. }
  789. if ( stream->writeFlag( mask & NodeMask ) )
  790. {
  791. const U32 nodeByteSize = 32; // Based on sending all of a node's parameters
  792. // Test if we can fit all of our nodes within the current stream.
  793. // We make sure we leave 100 bytes still free in the stream for whatever
  794. // may follow us.
  795. S32 allowedBytes = stream->getWriteByteSize() - 100;
  796. if ( stream->writeFlag( (nodeByteSize * mNodes.size()) < allowedBytes ) )
  797. {
  798. // All nodes should fit, so send them out now.
  799. stream->writeInt( mNodes.size(), 16 );
  800. for ( U32 i = 0; i < mNodes.size(); i++ )
  801. {
  802. mathWrite( *stream, mNodes[i].point );
  803. stream->write( mNodes[i].width );
  804. stream->write( mNodes[i].depth );
  805. mathWrite( *stream, mNodes[i].normal );
  806. }
  807. }
  808. else
  809. {
  810. // There isn't enough space left in the stream for all of the
  811. // nodes. Batch them up into NetEvents.
  812. U32 id = gServerNodeListManager->nextListId();
  813. U32 count = 0;
  814. U32 index = 0;
  815. while (count < mNodes.size())
  816. {
  817. count += NodeListManager::smMaximumNodesPerEvent;
  818. if (count > mNodes.size())
  819. {
  820. count = mNodes.size();
  821. }
  822. RiverNodeEvent* event = new RiverNodeEvent();
  823. event->mId = id;
  824. event->mTotalNodes = mNodes.size();
  825. event->mLocalListStart = index;
  826. for (; index<count; ++index)
  827. {
  828. event->mPositions.push_back( mNodes[index].point );
  829. event->mWidths.push_back( mNodes[index].width );
  830. event->mDepths.push_back( mNodes[index].depth );
  831. event->mNormals.push_back( mNodes[index].normal );
  832. }
  833. con->postNetEvent( event );
  834. }
  835. stream->write( id );
  836. }
  837. }
  838. if( stream->writeFlag( mask & ( RiverMask | InitialUpdateMask ) ) )
  839. {
  840. // This is set to allow the user to modify the size of the water dynamically
  841. // in the editor
  842. mathWrite( *stream, mObjScale );
  843. stream->writeAffineTransform( mObjToWorld );
  844. }
  845. stream->writeFlag( mask & RegenMask );
  846. return retMask;
  847. }
  848. void River::unpackUpdate(NetConnection * con, BitStream * stream)
  849. {
  850. // Unpack Parent.
  851. Parent::unpackUpdate(con, stream);
  852. // RiverMask
  853. if(stream->readFlag())
  854. {
  855. MatrixF ObjectMatrix;
  856. stream->readAffineTransform(&ObjectMatrix);
  857. Parent::setTransform(ObjectMatrix);
  858. stream->read( &mMetersPerSegment );
  859. stream->read( &mSegmentsPerBatch );
  860. stream->read( &mDepthScale );
  861. stream->read( &mMaxDivisionSize );
  862. stream->read( &mColumnCount );
  863. stream->read( &mFlowMagnitude );
  864. stream->read( &mLodDistance );
  865. }
  866. // NodeMask
  867. if ( stream->readFlag() )
  868. {
  869. if (stream->readFlag())
  870. {
  871. // Nodes have been passed in this update
  872. U32 count = stream->readInt( 16 );
  873. mNodes.clear();
  874. Point3F pos;
  875. VectorF normal;
  876. F32 width,depth;
  877. for ( U32 i = 0; i < count; i++ )
  878. {
  879. mathRead( *stream, &pos );
  880. stream->read( &width );
  881. stream->read( &depth );
  882. mathRead( *stream, &normal );
  883. _addNode( pos, width, depth, normal );
  884. }
  885. }
  886. else
  887. {
  888. // Nodes will arrive as events
  889. U32 id;
  890. stream->read( &id );
  891. // Check if the road's nodes made it here before we did.
  892. NodeListManager::NodeList* list = NULL;
  893. if ( gClientNodeListManager->findListById( id, &list, true) )
  894. {
  895. // Work with the completed list
  896. RiverNodeList* riverList = dynamic_cast<RiverNodeList*>( list );
  897. if (riverList)
  898. buildNodesFromList( riverList );
  899. delete list;
  900. }
  901. else
  902. {
  903. // Nodes have not yet arrived, so register our interest in the list
  904. RiverNodeListNotify* notify = new RiverNodeListNotify( this, id );
  905. gClientNodeListManager->registerNotification( notify );
  906. }
  907. }
  908. }
  909. // RiverMask | InitialUpdateMask
  910. if( stream->readFlag() )
  911. {
  912. mathRead( *stream, &mObjScale );
  913. stream->readAffineTransform( &mObjToWorld );
  914. }
  915. // RegenMask
  916. if ( stream->readFlag() && isProperlyAdded() )
  917. regenerate();
  918. }
  919. void River::_getWaterPlane( const Point3F &camPos, PlaneF &outPlane, Point3F &outPos )
  920. {
  921. // Find the RiverSegment closest to the camera.
  922. F32 closestDist = F32_MAX;
  923. S32 closestSegment = 0;
  924. Point3F projPnt(0.0f, 0.0f, 0.0f);
  925. VectorF normal(0,0,0);
  926. for ( U32 i = 0; i < mSegments.size(); i++ )
  927. {
  928. const RiverSegment &segment = mSegments[i];
  929. const Point3F pos = MathUtils::mClosestPointOnSegment( segment.slice0->p1, segment.slice1->p1, camPos );
  930. F32 dist = ( camPos - pos ).len();
  931. if ( dist < closestDist )
  932. {
  933. closestDist = dist;
  934. closestSegment = i;
  935. projPnt = pos;
  936. }
  937. normal += segment.getSurfaceNormal();
  938. }
  939. if ( mReflectNormalUp )
  940. normal.set(0,0,1);
  941. else
  942. normal.normalizeSafe();
  943. outPos = projPnt;
  944. outPlane.set( projPnt, normal );
  945. }
  946. void River::setTransform( const MatrixF &mat )
  947. {
  948. for ( U32 i = 0; i < mNodes.size(); i++ )
  949. {
  950. mWorldToObj.mulP( mNodes[i].point );
  951. mat.mulP( mNodes[i].point );
  952. }
  953. /*
  954. // Get the amount of change in position.
  955. MatrixF oldMat = getTransform();
  956. Point3F oldPos = oldMat.getPosition();
  957. Point3F newPos = mat.getPosition();
  958. Point3F delta = newPos - oldPos;
  959. // Offset all nodes by that amount
  960. for ( U32 i = 0; i < mNodes.size(); i++ )
  961. {
  962. mNodes[i].point += delta;
  963. }
  964. // Assign the new position ( we ignore rotation )
  965. MatrixF newMat( oldMat );
  966. newMat.setPosition( newPos );
  967. */
  968. Parent::setTransform( mat );
  969. // Regenerate and update the client
  970. _regenerate();
  971. setMaskBits( NodeMask | RegenMask );
  972. }
  973. void River::setScale( const VectorF &scale )
  974. {
  975. // We ignore scale requests from the editor
  976. // right now.
  977. }
  978. bool River::castRay(const Point3F &s, const Point3F &e, RayInfo* info)
  979. {
  980. Point3F start = s;
  981. Point3F end = e;
  982. mObjToWorld.mulP(start);
  983. mObjToWorld.mulP(end);
  984. F32 out = 1.0f; // The output fraction/percentage along the line defined by s and e
  985. VectorF norm(0.0f, 0.0f, 0.0f); // The normal of the face intersected
  986. Vector<RiverHitSegment> hitSegments;
  987. for ( U32 i = 0; i < mSegments.size(); i++ )
  988. {
  989. const RiverSegment &segment = mSegments[i];
  990. F32 t;
  991. VectorF n;
  992. if ( segment.worldbounds.collideLine( start, end, &t, &n ) )
  993. {
  994. hitSegments.increment();
  995. hitSegments.last().t = t;
  996. hitSegments.last().idx = i;
  997. }
  998. }
  999. dQsort( hitSegments.address(), hitSegments.size(), sizeof(RiverHitSegment), compareHitSegments );
  1000. U32 idx0, idx1, idx2;
  1001. F32 t;
  1002. for ( U32 i = 0; i < hitSegments.size(); i++ )
  1003. {
  1004. U32 segIdx = hitSegments[i].idx;
  1005. const RiverSegment &segment = mSegments[segIdx];
  1006. // Each segment has 6 faces
  1007. for ( U32 j = 0; j < 6; j++ )
  1008. {
  1009. if ( j == 4 && segIdx != 0 )
  1010. continue;
  1011. if ( j == 5 && segIdx != mSegments.size() - 1 )
  1012. continue;
  1013. // Each face has 2 triangles
  1014. for ( U32 k = 0; k < 2; k++ )
  1015. {
  1016. idx0 = gIdxArray[j][k][0];
  1017. idx1 = gIdxArray[j][k][1];
  1018. idx2 = gIdxArray[j][k][2];
  1019. const Point3F &v0 = segment[idx0];
  1020. const Point3F &v1 = segment[idx1];
  1021. const Point3F &v2 = segment[idx2];
  1022. if ( !MathUtils::mLineTriangleCollide( start, end,
  1023. v2, v1, v0,
  1024. NULL,
  1025. &t ) )
  1026. continue;
  1027. if ( t >= 0.0f && t < 1.0f && t < out )
  1028. {
  1029. out = t;
  1030. // optimize this, can be calculated easily within
  1031. // the collision test
  1032. norm = PlaneF( v0, v1, v2 );
  1033. }
  1034. }
  1035. }
  1036. if (out >= 0.0f && out < 1.0f)
  1037. break;
  1038. }
  1039. if (out >= 0.0f && out < 1.0f)
  1040. {
  1041. info->t = out;
  1042. info->normal = norm;
  1043. info->point.interpolate(start, end, out);
  1044. info->face = -1;
  1045. info->object = this;
  1046. return true;
  1047. }
  1048. return false;
  1049. }
  1050. bool River::collideBox(const Point3F &start, const Point3F &end, RayInfo* info)
  1051. {
  1052. return false;
  1053. }
  1054. bool River::buildPolyList( PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere )
  1055. {
  1056. Vector<const RiverSegment*> hitSegments;
  1057. for ( U32 i = 0; i < mSegments.size(); i++ )
  1058. {
  1059. const RiverSegment &segment = mSegments[i];
  1060. if ( segment.worldbounds.isOverlapped( box ) )
  1061. {
  1062. hitSegments.push_back( &segment );
  1063. }
  1064. }
  1065. if ( !hitSegments.size() )
  1066. return false;
  1067. polyList->setObject( this );
  1068. polyList->setTransform( &MatrixF::Identity, Point3F( 1.0f, 1.0f, 1.0f ) );
  1069. for ( U32 i = 0; i < hitSegments.size(); i++ )
  1070. {
  1071. const RiverSegment* segment = hitSegments[i];
  1072. for ( U32 k = 0; k < 2; k++ )
  1073. {
  1074. // gIdxArray[0] gives us the top plane (see table definition).
  1075. U32 idx0 = gIdxArray[0][k][0];
  1076. U32 idx1 = gIdxArray[0][k][1];
  1077. U32 idx2 = gIdxArray[0][k][2];
  1078. const Point3F &v0 = (*segment)[idx0];
  1079. const Point3F &v1 = (*segment)[idx1];
  1080. const Point3F &v2 = (*segment)[idx2];
  1081. // Add vertices to poly list.
  1082. U32 i0 = polyList->addPoint(v0);
  1083. polyList->addPoint(v1);
  1084. polyList->addPoint(v2);
  1085. // Add plane between them.
  1086. polyList->begin(0, 0);
  1087. polyList->vertex(i0);
  1088. polyList->vertex(i0+1);
  1089. polyList->vertex(i0+2);
  1090. polyList->plane(i0, i0+1, i0+2);
  1091. polyList->end();
  1092. }
  1093. }
  1094. return true;
  1095. }
  1096. F32 River::getWaterCoverage( const Box3F &worldBox ) const
  1097. {
  1098. PROFILE_SCOPE( River_GetWaterCoverage );
  1099. if ( !mWorldBox.isOverlapped(worldBox) )
  1100. return 0.0f;
  1101. Point3F bottomPnt = worldBox.getCenter();
  1102. bottomPnt.z = worldBox.minExtents.z;
  1103. F32 farthest = 0.0f;
  1104. for ( U32 i = 0; i < mSegments.size(); i++ )
  1105. {
  1106. const RiverSegment &segment = mSegments[i];
  1107. if ( !segment.worldbounds.isOverlapped(worldBox) )
  1108. continue;
  1109. if ( !segment.intersectBox( worldBox ) )
  1110. continue;
  1111. F32 distance = segment.distanceToSurface( bottomPnt );
  1112. if ( distance > farthest )
  1113. farthest = distance;
  1114. }
  1115. F32 height = worldBox.maxExtents.z - worldBox.minExtents.z;
  1116. F32 distance = mClampF( farthest, 0.0f, height );
  1117. F32 coverage = distance / height;
  1118. return coverage;
  1119. }
  1120. F32 River::getSurfaceHeight( const Point2F &pos ) const
  1121. {
  1122. PROFILE_SCOPE( River_GetSurfaceHeight );
  1123. Point3F origin( pos.x, pos.y, mWorldBox.maxExtents.z );
  1124. Point3F direction(0,0,-1);
  1125. U32 nodeIdx;
  1126. Point3F collisionPnt;
  1127. if ( !collideRay( origin, direction, &nodeIdx, &collisionPnt ) )
  1128. return -1.0f;
  1129. return collisionPnt.z;
  1130. }
  1131. VectorF River::getFlow( const Point3F &pos ) const
  1132. {
  1133. PROFILE_SCOPE( River_GetFlow );
  1134. for ( U32 i = 0; i < mSegments.size(); i++ )
  1135. {
  1136. const RiverSegment &segment = mSegments[i];
  1137. if ( !segment.containsPoint(pos) )
  1138. continue;
  1139. VectorF flow = segment.slice0->p1 - segment.slice1->p1;
  1140. flow.normalize();
  1141. flow *= mFlowMagnitude;
  1142. return flow;
  1143. }
  1144. return VectorF::Zero;
  1145. }
  1146. void River::onReflectionInfoChanged()
  1147. {
  1148. /*
  1149. if ( isClientObject() && GFX->getPixelShaderVersion() >= 1.4 )
  1150. {
  1151. if ( mFullReflect )
  1152. REFLECTMGR->registerObject( this, ReflectDelegate( this, &River::updateReflection ), mReflectPriority, mReflectMaxRateMs, mReflectMaxDist );
  1153. else
  1154. {
  1155. REFLECTMGR->unregisterObject( this );
  1156. mReflectTex = NULL;
  1157. }
  1158. }
  1159. */
  1160. }
  1161. void River::_regenerate()
  1162. {
  1163. if ( mNodes.size() == 0 )
  1164. return;
  1165. const Point3F &nodePt = mNodes.first().point;
  1166. MatrixF mat( true );
  1167. mat.setPosition( nodePt );
  1168. Parent::setTransform( mat );
  1169. _generateSlices();
  1170. }
  1171. void River::_generateSlices()
  1172. {
  1173. if ( mNodes.size() < 2 )
  1174. return;
  1175. U32 nodeCount = mNodes.size();
  1176. RiverSplineNode *splineNodes = new RiverSplineNode[nodeCount];
  1177. for ( U32 i = 0; i < nodeCount; i++ )
  1178. {
  1179. const RiverNode &node = mNodes[i];
  1180. splineNodes[i].x = node.point.x;
  1181. splineNodes[i].y = node.point.y;
  1182. splineNodes[i].z = node.point.z;
  1183. splineNodes[i].width = node.width;
  1184. splineNodes[i].depth = node.depth;
  1185. splineNodes[i].normal = node.normal;
  1186. }
  1187. CatmullRom<RiverSplineNode> spline;
  1188. spline.initialize( nodeCount, splineNodes );
  1189. delete [] splineNodes;
  1190. mSlices.clear();
  1191. for ( U32 i = 1; i < nodeCount; i++ )
  1192. {
  1193. F32 t0 = spline.getTime( i-1 );
  1194. F32 t1 = spline.getTime( i );
  1195. F32 segLength = spline.arcLength( t0, t1 );
  1196. U32 numSegments = mCeil( segLength / mMetersPerSegment );
  1197. numSegments = getMax( numSegments, (U32)1 );
  1198. F32 tstep = ( t1 - t0 ) / numSegments;
  1199. //AssertFatal( numSegments > 0, "River::_generateSlices, got zero segments!" );
  1200. U32 startIdx = 0;
  1201. U32 endIdx = ( i == nodeCount - 1 ) ? numSegments + 1 : numSegments;
  1202. for ( U32 j = startIdx; j < endIdx; j++ )
  1203. {
  1204. F32 t = t0 + tstep * j; //spline.findParameterByDistance( 0.0f, i * segLen );
  1205. RiverSplineNode val = spline.evaluate(t);
  1206. RiverSlice slice;
  1207. slice.p1.set( val.x, val.y, val.z );
  1208. slice.uvec.set( 0,0,1 );
  1209. slice.width = val.width;
  1210. slice.depth = val.depth;
  1211. slice.parentNodeIdx = i-1;
  1212. slice.normal = val.normal;
  1213. slice.normal.normalize();
  1214. mSlices.push_back( slice );
  1215. }
  1216. }
  1217. //
  1218. // Calculate fvec and rvec for all slices
  1219. //
  1220. RiverSlice *pSlice = NULL;
  1221. RiverSlice *pNextSlice = NULL;
  1222. // Must do the first slice outside the loop
  1223. {
  1224. pSlice = &mSlices[0];
  1225. pNextSlice = &mSlices[1];
  1226. pSlice->fvec = pNextSlice->p1 - pSlice->p1;
  1227. pSlice->fvec.normalize();
  1228. pSlice->rvec = mCross( pSlice->fvec, pSlice->normal );
  1229. pSlice->rvec.normalize();
  1230. pSlice->uvec = mCross( pSlice->rvec, pSlice->fvec );
  1231. pSlice->uvec.normalize();
  1232. pSlice->rvec = mCross( pSlice->fvec, pSlice->uvec );
  1233. pSlice->rvec.normalize();
  1234. }
  1235. for ( U32 i = 1; i < mSlices.size() - 1; i++ )
  1236. {
  1237. pSlice = &mSlices[i];
  1238. pNextSlice = &mSlices[i+1];
  1239. pSlice->fvec = pNextSlice->p1 - pSlice->p1;
  1240. pSlice->fvec.normalize();
  1241. pSlice->rvec = mCross( pSlice->fvec, pSlice->normal );
  1242. pSlice->rvec.normalize();
  1243. pSlice->uvec = mCross( pSlice->rvec, pSlice->fvec );
  1244. pSlice->uvec.normalize();
  1245. pSlice->rvec = mCross( pSlice->fvec, pSlice->uvec );
  1246. pSlice->rvec.normalize();
  1247. }
  1248. // Must do the last slice outside the loop
  1249. {
  1250. RiverSlice *lastSlice = &mSlices[mSlices.size()-1];
  1251. RiverSlice *prevSlice = &mSlices[mSlices.size()-2];
  1252. lastSlice->fvec = prevSlice->fvec;
  1253. lastSlice->rvec = mCross( lastSlice->fvec, lastSlice->normal );
  1254. lastSlice->rvec.normalize();
  1255. lastSlice->uvec = mCross( lastSlice->rvec, lastSlice->fvec );
  1256. lastSlice->uvec.normalize();
  1257. lastSlice->rvec = mCross( lastSlice->fvec, lastSlice->uvec );
  1258. lastSlice->rvec.normalize();
  1259. }
  1260. //
  1261. // Calculate p0/p2/pb0/pb2 for all slices
  1262. //
  1263. for ( U32 i = 0; i < mSlices.size(); i++ )
  1264. {
  1265. RiverSlice *slice = &mSlices[i];
  1266. slice->p0 = slice->p1 - slice->rvec * slice->width * 0.5f;
  1267. slice->p2 = slice->p1 + slice->rvec * slice->width * 0.5f;
  1268. slice->pb0 = slice->p0 - slice->uvec * slice->depth;
  1269. slice->pb2 = slice->p2 - slice->uvec * slice->depth;
  1270. }
  1271. // Generate the object/world bounds
  1272. Box3F box;
  1273. for ( U32 i = 0; i < mSlices.size(); i++ )
  1274. {
  1275. const RiverSlice &slice = mSlices[i];
  1276. if ( i == 0 )
  1277. {
  1278. box.minExtents = slice.p0;
  1279. box.maxExtents = slice.p2;
  1280. box.extend( slice.pb0 );
  1281. box.extend( slice.pb2 );
  1282. }
  1283. else
  1284. {
  1285. box.extend( slice.p0 );
  1286. box.extend( slice.p2 );
  1287. box.extend( slice.pb0 );
  1288. box.extend( slice.pb2 );
  1289. }
  1290. }
  1291. mWorldBox = box;
  1292. //mObjBox.minExtents -= pos;
  1293. //mObjBox.maxExtents -= pos;
  1294. resetObjectBox();
  1295. // Make sure we are in the correct bins given our world box.
  1296. if( getSceneManager() != NULL )
  1297. getSceneManager()->notifyObjectDirty( this );
  1298. _generateSegments();
  1299. }
  1300. void River::_generateSegments()
  1301. {
  1302. mSegments.clear();
  1303. for ( U32 i = 0; i < mSlices.size() - 1; i++ )
  1304. {
  1305. RiverSegment seg( &mSlices[i], &mSlices[i+1] );
  1306. mSegments.push_back( seg );
  1307. }
  1308. /*
  1309. #ifdef TORQUE_DEBUG
  1310. for ( U32 i = 0; i < mSegments.size(); i++ )
  1311. {
  1312. const RiverSegment &segment = mSegments[i];
  1313. PlaneF normal0 = MathUtils::mTriangleNormal( segment.slice0->p0, segment.slice1->p0, segment.slice1->p2 );
  1314. PlaneF normal1 = MathUtils::mTriangleNormal( segment.slice0->p0, segment.slice1->p2, segment.slice0->p2 );
  1315. AssertFatal( true || normal0 != normal1, "River::generateSegments, segment is not coplanar!" );
  1316. }
  1317. #endif // TORQUE_DEBUG
  1318. */
  1319. // We have to go back and generate normals for each slice
  1320. // to be used in calculation of the reflect plane.
  1321. // The slice-normal we calculate are relative to the surface normal
  1322. // of the segments adjacent to the slice.
  1323. /*
  1324. if ( mSlices.size() >= 2 )
  1325. {
  1326. mSlices[0].normal = mSegments[0].getSurfaceNormal();
  1327. for ( U32 i = 1; i < mSlices.size() - 1; i++ )
  1328. {
  1329. mSlices[i].normal = ( mSegments[i-1].getSurfaceNormal() + mSegments[i].getSurfaceNormal() ) / 2;
  1330. }
  1331. mSlices.last().normal = mSegments.last().getSurfaceNormal();
  1332. }
  1333. */
  1334. _generateVerts();
  1335. }
  1336. void River::_generateVerts()
  1337. {
  1338. if ( isServerObject() )
  1339. return;
  1340. // These will depend on the level of subdivision per segment
  1341. // calculated below.
  1342. mHighVertCount = 0;
  1343. mHighTriangleCount = 0;
  1344. // Calculate the number of row/column subdivisions per each
  1345. // RiverSegment.
  1346. F32 greatestWidth = 0.1f;
  1347. for ( U32 i = 0; i < mNodes.size(); i++ )
  1348. {
  1349. RiverNode &node = mNodes[i];
  1350. if ( node.width > greatestWidth )
  1351. greatestWidth = node.width;
  1352. }
  1353. mColumnCount = mCeil( greatestWidth / mMaxDivisionSize );
  1354. for ( U32 i = 0; i < mSegments.size(); i++ )
  1355. {
  1356. RiverSegment &segment = mSegments[i];
  1357. const RiverSlice *slice = segment.slice0;
  1358. const RiverSlice *nextSlice = segment.slice1;
  1359. // Calculate the size of divisions in the forward direction ( p00 -> p01 )
  1360. F32 segLength = (nextSlice->p1 - slice->p1).len();
  1361. // A division count of one is actually NO subdivision,
  1362. // the segment corners are the only verts in this segment.
  1363. U32 numRows = 1;
  1364. if ( segLength > 0.0f )
  1365. numRows = mCeil( segLength / mMaxDivisionSize );
  1366. // The problem with calculating num columns per segment is
  1367. // two adjacent - high lod segments of different width can have
  1368. // verts that don't line up! So even though RiverSegment HAS a
  1369. // column data member we initialize all segments in the river to
  1370. // the same (River::mColumnCount)
  1371. // Calculate the size of divisions in the right direction ( p00 -> p10 )
  1372. // F32 segWidth = ( ( p11 - p01 ).len() + ( p10 - p00 ).len() ) * 0.5f;
  1373. // U32 numColumns = 5;
  1374. //F32 columnSize = segWidth / numColumns;
  1375. //while ( columnSize > mMaxDivisionSize )
  1376. //{
  1377. // numColumns++;
  1378. // columnSize = segWidth / numColumns;
  1379. //}
  1380. // Save the calculated numb of columns / rows for this segment.
  1381. segment.columns = mColumnCount;
  1382. segment.rows = numRows;
  1383. // Save the corresponding number of verts/prims
  1384. segment.numVerts = ( 1 + mColumnCount ) * ( 1 + numRows );
  1385. segment.numTriangles = mColumnCount * numRows * 2;
  1386. mHighVertCount += segment.numVerts;
  1387. mHighTriangleCount += segment.numTriangles;
  1388. }
  1389. // Number of low detail verts/prims.
  1390. mLowVertCount = mSlices.size() * 2;
  1391. mLowTriangleCount = mSegments.size() * 2;
  1392. // Allocate the low detail VertexBuffer,
  1393. // this will stay in memory and will never need to change.
  1394. mVB_low.set( GFX, mLowVertCount, GFXBufferTypeStatic );
  1395. GFXWaterVertex *lowVertPtr = mVB_low.lock();
  1396. U32 vertCounter = 0;
  1397. // The texCoord.y value start/end for a segment
  1398. // as we loop through them.
  1399. F32 textCoordV = 0;
  1400. //
  1401. // Fill the low-detail VertexBuffer
  1402. //
  1403. for ( U32 i = 0; i < mSlices.size(); i++ )
  1404. {
  1405. RiverSlice &slice = mSlices[i];
  1406. lowVertPtr->point = slice.p0;
  1407. lowVertPtr->normal = slice.normal;
  1408. lowVertPtr->undulateData.set( -slice.width*0.5f, textCoordV );
  1409. lowVertPtr->horizonFactor.set( 0, 0, 0, 0 );
  1410. lowVertPtr++;
  1411. vertCounter++;
  1412. lowVertPtr->point = slice.p2;
  1413. lowVertPtr->normal = slice.normal;
  1414. lowVertPtr->undulateData.set( slice.width*0.5f, textCoordV );
  1415. lowVertPtr->horizonFactor.set( 0, 0, 0, 0 );
  1416. lowVertPtr++;
  1417. vertCounter++;
  1418. // Save this so we can get it later.
  1419. slice.texCoordV = textCoordV;
  1420. if ( i < mSlices.size() - 1 )
  1421. {
  1422. // Increment the textCoordV for the next slice.
  1423. F32 segLen = ( mSlices[i+1].p1 - slice.p1 ).len();
  1424. textCoordV += segLen;
  1425. }
  1426. }
  1427. AssertFatal( vertCounter == mLowVertCount, "River, wrote incorrect number of verts in mBV_low!" );
  1428. // Unlock the low-detail VertexBuffer, we are done filling it.
  1429. mVB_low.unlock();
  1430. //
  1431. // Create the low-detail prim buffer(s)
  1432. //
  1433. mPB_low.set( GFX, mLowTriangleCount * 3, mLowTriangleCount, GFXBufferTypeStatic );
  1434. U16 *lowIdxBuff;
  1435. mPB_low.lock(&lowIdxBuff);
  1436. U32 curLowIdx = 0;
  1437. // Temporaries to hold indices for the corner points of a quad.
  1438. U32 p00, p01, p11, p10;
  1439. U32 offset = 0;
  1440. // Fill the low-detail PrimitiveBuffer
  1441. for ( U32 i = 0; i < mSegments.size(); i++ )
  1442. {
  1443. //const RiverSegment &segment = mSegments[i];
  1444. // Two triangles formed by the corner points of this segment
  1445. // into the the low detail primitive buffer.
  1446. p00 = offset;
  1447. p01 = p00 + 2;
  1448. p11 = p01 + 1;
  1449. p10 = p00 + 1;
  1450. // Upper-Left triangle
  1451. lowIdxBuff[curLowIdx] = p00;
  1452. curLowIdx++;
  1453. lowIdxBuff[curLowIdx] = p01;
  1454. curLowIdx++;
  1455. lowIdxBuff[curLowIdx] = p11;
  1456. curLowIdx++;
  1457. // Lower-Right Triangle
  1458. lowIdxBuff[curLowIdx] = p00;
  1459. curLowIdx++;
  1460. lowIdxBuff[curLowIdx] = p11;
  1461. curLowIdx++;
  1462. lowIdxBuff[curLowIdx] = p10;
  1463. curLowIdx++;
  1464. offset += 2;
  1465. }
  1466. AssertFatal( curLowIdx == mLowTriangleCount * 3, "River, wrote incorrect number of indices in mPB_low!" );
  1467. // Unlock the low-detail PrimitiveBuffer, we are done filling it.
  1468. mPB_low.unlock();
  1469. }
  1470. bool River::getClosestNode( const Point3F &pos, U32 &idx ) const
  1471. {
  1472. F32 closestDist = F32_MAX;
  1473. for ( U32 i = 0; i < mNodes.size(); i++ )
  1474. {
  1475. F32 dist = ( mNodes[i].point - pos ).len();
  1476. if ( dist < closestDist )
  1477. {
  1478. closestDist = dist;
  1479. idx = i;
  1480. }
  1481. }
  1482. return closestDist != F32_MAX;
  1483. }
  1484. bool River::containsPoint( const Point3F &worldPos, U32 *nodeIdx ) const
  1485. {
  1486. // If point isn't in the world box,
  1487. // it's definitely not in the River.
  1488. //if ( !getWorldBox().isContained( worldPos ) )
  1489. // return false;
  1490. // Look through all edges, does the polygon
  1491. // formed from adjacent edge's contain the worldPos?
  1492. for ( U32 i = 0; i < mSegments.size(); i++ )
  1493. {
  1494. const RiverSegment &segment = mSegments[i];
  1495. if ( segment.containsPoint( worldPos ) )
  1496. {
  1497. if ( nodeIdx )
  1498. *nodeIdx = i;
  1499. return true;
  1500. }
  1501. }
  1502. return false;
  1503. }
  1504. F32 River::distanceToSurface( const Point3F &pnt, U32 segmentIdx )
  1505. {
  1506. return mSegments[segmentIdx].distanceToSurface( pnt );
  1507. }
  1508. bool River::collideRay( const Point3F &origin, const Point3F &direction, U32 *nodeIdx, Point3F *collisionPnt ) const
  1509. {
  1510. Point3F p0 = origin;
  1511. Point3F p1 = origin + direction * 2000.0f;
  1512. // If the line segment does not collide with the river's world box,
  1513. // it definitely does not collide with any part of the river.
  1514. if ( !getWorldBox().collideLine( p0, p1 ) )
  1515. return false;
  1516. if ( mSlices.size() < 2 )
  1517. return false;
  1518. MathUtils::Quad quad;
  1519. MathUtils::Ray ray;
  1520. F32 t;
  1521. // Check each river segment (formed by a pair of slices) for collision
  1522. // with the line segment.
  1523. for ( U32 i = 0; i < mSlices.size() - 1; i++ )
  1524. {
  1525. const RiverSlice &slice0 = mSlices[i];
  1526. const RiverSlice &slice1 = mSlices[i+1];
  1527. // For simplicities sake we will only test for collision between the
  1528. // line segment and the Top face of the river segment.
  1529. // Clockwise starting with the leftmost/closest point.
  1530. quad.p00 = slice0.p0;
  1531. quad.p01 = slice1.p0;
  1532. quad.p11 = slice1.p2;
  1533. quad.p10 = slice0.p2;
  1534. ray.origin = origin;
  1535. ray.direction = direction;
  1536. // NOTE:
  1537. // mRayQuadCollide is designed for a "real" quad in which all four points
  1538. // are coplanar which is actually not the case here. The more twist
  1539. // and turn in-between two neighboring river slices the more incorrect
  1540. // this calculation will be.
  1541. if ( MathUtils::mRayQuadCollide( quad, ray, NULL, &t ) )
  1542. {
  1543. if ( nodeIdx )
  1544. *nodeIdx = slice0.parentNodeIdx;
  1545. if ( collisionPnt )
  1546. *collisionPnt = ray.origin + ray.direction * t;
  1547. return true;
  1548. }
  1549. }
  1550. return false;
  1551. }
  1552. Point3F River::getNodePosition( U32 idx ) const
  1553. {
  1554. if ( mNodes.size() - 1 < idx )
  1555. return Point3F();
  1556. return mNodes[idx].point;
  1557. }
  1558. void River::setNodePosition( U32 idx, const Point3F &pos )
  1559. {
  1560. if ( mNodes.size() - 1 < idx )
  1561. return;
  1562. mNodes[idx].point = pos;
  1563. regenerate();
  1564. setMaskBits( NodeMask | RegenMask );
  1565. }
  1566. U32 River::addNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal )
  1567. {
  1568. U32 idx = _addNode( pos, width, depth, normal );
  1569. regenerate();
  1570. setMaskBits( NodeMask | RegenMask );
  1571. return idx;
  1572. }
  1573. U32 River::insertNode(const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx)
  1574. {
  1575. U32 ret = _insertNode( pos, width, depth, normal, idx );
  1576. regenerate();
  1577. setMaskBits( NodeMask | RegenMask );
  1578. return ret;
  1579. }
  1580. void River::setNode(const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx)
  1581. {
  1582. if ( mNodes.size() - 1 < idx )
  1583. return;
  1584. RiverNode &node = mNodes[idx];
  1585. node.point = pos;
  1586. node.width = width;
  1587. node.depth = depth;
  1588. node.normal = normal;
  1589. regenerate();
  1590. setMaskBits( NodeMask | RegenMask );
  1591. }
  1592. void River::setNodeWidth( U32 idx, F32 meters )
  1593. {
  1594. meters = mClampF( meters, MIN_NODE_WIDTH, MAX_NODE_WIDTH );
  1595. if ( mNodes.size() - 1 < idx )
  1596. return;
  1597. mNodes[idx].width = meters;
  1598. _regenerate();
  1599. setMaskBits( RegenMask | NodeMask );
  1600. }
  1601. void River::setNodeHeight( U32 idx, F32 height )
  1602. {
  1603. if ( mNodes.size() - 1 < idx )
  1604. return;
  1605. mNodes[idx].point.z = height;
  1606. _regenerate();
  1607. setMaskBits( RegenMask | NodeMask );
  1608. }
  1609. F32 River::getNodeWidth( U32 idx ) const
  1610. {
  1611. if ( mNodes.size() - 1 < idx )
  1612. return -1.0f;
  1613. return mNodes[idx].width;
  1614. }
  1615. void River::setNodeDepth( U32 idx, F32 meters )
  1616. {
  1617. meters = mClampF( meters, MIN_NODE_DEPTH, MAX_NODE_DEPTH );
  1618. if ( mNodes.size() - 1 < idx )
  1619. return;
  1620. mNodes[idx].depth = meters;
  1621. _regenerate();
  1622. setMaskBits( RiverMask | RegenMask | NodeMask );
  1623. }
  1624. void River::setNodeNormal( U32 idx, const VectorF &normal )
  1625. {
  1626. if ( mNodes.size() - 1 < idx )
  1627. return;
  1628. mNodes[idx].normal = normal;
  1629. regenerate();
  1630. setMaskBits( NodeMask | RegenMask );
  1631. }
  1632. F32 River::getNodeDepth( U32 idx ) const
  1633. {
  1634. if ( mNodes.size() - 1 < idx )
  1635. return -1.0f;
  1636. return mNodes[idx].depth;
  1637. }
  1638. VectorF River::getNodeNormal( U32 idx ) const
  1639. {
  1640. if ( mNodes.size() - 1 < idx )
  1641. return VectorF::Zero;
  1642. return mNodes[idx].normal;
  1643. }
  1644. MatrixF River::getNodeTransform( U32 idx ) const
  1645. {
  1646. MatrixF mat(true);
  1647. if ( mNodes.size() - 1 < idx )
  1648. return mat;
  1649. bool hasNext = idx + 1 < mNodes.size();
  1650. bool hasPrev = (S32)idx - 1 >= 0;
  1651. const RiverNode &node = mNodes[idx];
  1652. VectorF fvec( 0, 1, 0 );
  1653. if ( hasNext )
  1654. {
  1655. fvec = mNodes[idx+1].point - node.point;
  1656. fvec.normalizeSafe();
  1657. }
  1658. else if ( hasPrev )
  1659. {
  1660. fvec = node.point - mNodes[idx-1].point;
  1661. fvec.normalizeSafe();
  1662. }
  1663. else
  1664. fvec = mPerp( node.normal );
  1665. if ( fvec.isZero() )
  1666. fvec = mPerp( node.normal );
  1667. F32 dot = mDot( fvec, node.normal );
  1668. if ( dot < -0.9f || dot > 0.9f )
  1669. fvec = mPerp( node.normal );
  1670. VectorF rvec = mCross( fvec, node.normal );
  1671. if ( rvec.isZero() )
  1672. rvec = mPerp( fvec );
  1673. rvec.normalize();
  1674. fvec = mCross( node.normal, rvec );
  1675. fvec.normalize();
  1676. mat.setColumn( 0, rvec );
  1677. mat.setColumn( 1, fvec );
  1678. mat.setColumn( 2, node.normal );
  1679. mat.setColumn( 3, node.point );
  1680. AssertFatal( m_matF_determinant( mat ) != 0.0f, "no inverse!");
  1681. return mat;
  1682. }
  1683. void River::deleteNode( U32 idx )
  1684. {
  1685. if ( mNodes.size() - 1 < idx )
  1686. return;
  1687. mNodes.erase(idx);
  1688. _regenerate();
  1689. setMaskBits( RegenMask | NodeMask );
  1690. }
  1691. void River::buildNodesFromList( RiverNodeList* list )
  1692. {
  1693. mNodes.clear();
  1694. for (U32 i=0; i<list->mPositions.size(); ++i)
  1695. {
  1696. _addNode( list->mPositions[i], list->mWidths[i], list->mDepths[i], list->mNormals[i] );
  1697. }
  1698. _regenerate();
  1699. }
  1700. void River::_makeRenderBatches( const Point3F &cameraPos )
  1701. {
  1702. // Loop through each segment to determine if it is either 1 [not visible], 2 [high LOD], 3 [low LOD]
  1703. mHighLODBatches.clear();
  1704. mLowLODBatches.clear();
  1705. // Keeps track of what we batch type we are currently collecting.
  1706. // -1 is uninitialized, 0 is low detail, 1 is high detail
  1707. S32 lastDetail = -1;
  1708. bool highDetail;
  1709. U32 startSegmentIdx = -1;
  1710. U32 endSegmentIdx = 0;
  1711. F32 lodDistSquared = mLodDistance * mLodDistance;
  1712. for ( U32 i = 0; i < mSegments.size(); i++ )
  1713. {
  1714. const RiverSegment &segment = mSegments[i];
  1715. const RiverSlice *slice = segment.slice0;
  1716. const RiverSlice *nextSlice = segment.slice1;
  1717. // TODO: add bounds BoxF to RiverSegment
  1718. const bool isVisible = true; //frustum.intersects( segment.bounds );
  1719. if ( isVisible )
  1720. {
  1721. F32 dist0 = MathUtils::mTriangleDistance( slice->p0, nextSlice->p0, nextSlice->p2, cameraPos );
  1722. F32 dist1 = MathUtils::mTriangleDistance( slice->p0, nextSlice->p2, slice->p2, cameraPos );
  1723. F32 dist = getMin( dist0, dist1 );
  1724. highDetail = ( dist < lodDistSquared );
  1725. if ( (highDetail && lastDetail == 0) ||
  1726. (!highDetail && lastDetail == 1) )
  1727. {
  1728. // We hit a segment with a different lod than the previous.
  1729. // Save what we have so far...
  1730. RiverRenderBatch batch;
  1731. batch.startSegmentIdx = startSegmentIdx;
  1732. batch.endSegmentIdx = endSegmentIdx;
  1733. if ( lastDetail == 0 )
  1734. {
  1735. mLowLODBatches.push_back( batch );
  1736. }
  1737. else
  1738. {
  1739. mHighLODBatches.push_back( batch );
  1740. }
  1741. // Reset the batching
  1742. startSegmentIdx = -1;
  1743. lastDetail = -1;
  1744. i--;
  1745. continue;
  1746. }
  1747. // If this is the start of a set of batches.
  1748. if ( startSegmentIdx == -1 )
  1749. {
  1750. endSegmentIdx = startSegmentIdx = i;
  1751. lastDetail = ( highDetail ) ? 1 : 0;
  1752. }
  1753. // Else we're extending the end batch index.
  1754. else
  1755. ++endSegmentIdx;
  1756. // If this isn't the last batch then continue.
  1757. if ( i < mSegments.size()-1 )
  1758. continue;
  1759. }
  1760. // If we still don't have a start batch skip.
  1761. if ( startSegmentIdx == -1 )
  1762. continue;
  1763. // Save what we have so far...
  1764. RiverRenderBatch batch;
  1765. batch.startSegmentIdx = startSegmentIdx;
  1766. batch.endSegmentIdx = endSegmentIdx;
  1767. if ( lastDetail == 0 )
  1768. {
  1769. mLowLODBatches.push_back( batch );
  1770. }
  1771. else
  1772. {
  1773. mHighLODBatches.push_back( batch );
  1774. }
  1775. // Reset the batching.
  1776. startSegmentIdx = -1;
  1777. lastDetail = -1;
  1778. }
  1779. }
  1780. void River::_makeHighLODBuffers()
  1781. {
  1782. PROFILE_SCOPE( River_makeHighLODBuffers );
  1783. // This is the number of verts/triangles for ALL high lod batches combined.
  1784. // eg. the size for the buffers.
  1785. U32 numVerts = 0;
  1786. U32 numTriangles = 0;
  1787. for ( U32 i = 0; i < mHighLODBatches.size(); i++ )
  1788. {
  1789. RiverRenderBatch &batch = mHighLODBatches[i];
  1790. for ( U32 j = batch.startSegmentIdx; j <= batch.endSegmentIdx; j++ )
  1791. {
  1792. const RiverSegment &segment = mSegments[j];
  1793. numTriangles += segment.numTriangles;
  1794. numVerts += segment.numVerts;
  1795. }
  1796. }
  1797. if ( numVerts > GFX_MAX_DYNAMIC_VERTS || numTriangles * 3 > GFX_MAX_DYNAMIC_INDICES )
  1798. {
  1799. mVB_high = NULL;
  1800. mPB_high = NULL;
  1801. return;
  1802. }
  1803. mHighTriangleCount = numTriangles;
  1804. mHighVertCount = numVerts;
  1805. mVB_high.set( GFX, numVerts, GFXBufferTypeVolatile );
  1806. GFXWaterVertex *vertPtr = mVB_high.lock();
  1807. U32 vertCounter = 0;
  1808. // NOTE: this will break if different segments have different number
  1809. // of columns, but that will also cause T-junction triangles so just don't
  1810. // do that.
  1811. // For each batch, loop through the segments contained by
  1812. // that batch, and add their verts to the buffer.
  1813. for ( U32 i = 0; i < mHighLODBatches.size(); i++ )
  1814. {
  1815. RiverRenderBatch &batch = mHighLODBatches[i];
  1816. batch.startVert = vertCounter;
  1817. batch.vertCount = 0;
  1818. VectorF lastNormal(0,0,1);
  1819. for ( U32 j = batch.startSegmentIdx; j <= batch.endSegmentIdx; j++ )
  1820. {
  1821. // Add the verts for this segment to the buffer.
  1822. RiverSegment &segment = mSegments[j];
  1823. BiSqrToQuad3D squareToQuad( segment.getP00(),
  1824. segment.getP10(),
  1825. segment.getP11(),
  1826. segment.getP01() );
  1827. // We are duplicating the last row of verts in a segment on
  1828. // the first row of the next segment. This could be optimized but
  1829. // shouldn't cause any problems.
  1830. VectorF normal = segment.getSurfaceNormal();
  1831. for ( U32 k = 0; k <= segment.rows; k++ )
  1832. {
  1833. VectorF vertNormal = ( k == 0 && j != batch.startSegmentIdx ) ? lastNormal : normal;
  1834. F32 rowLen = mLerp( segment.slice0->width, segment.slice1->width, (F32)k / (F32)segment.rows );
  1835. for ( U32 l = 0; l <= segment.columns; l++ )
  1836. {
  1837. // We are generating a "row" of verts along the forwardDivision
  1838. // Each l iteration is a step to the right along with row.
  1839. Point2F uv( (F32)l / (F32)segment.columns, (F32)k / (F32)segment.rows );
  1840. Point3F pnt = squareToQuad.transform( uv );
  1841. // Assign the Vert
  1842. vertPtr->point = pnt;
  1843. vertPtr->normal = vertNormal;
  1844. vertPtr->undulateData.x = ( uv.x - 0.5f ) * rowLen;
  1845. vertPtr->undulateData.y = ( segment.TexCoordEnd() - segment.TexCoordStart() ) * uv.y + segment.TexCoordStart();
  1846. vertPtr->horizonFactor.set( 0, 0, 0, 0 );
  1847. vertPtr++;
  1848. vertCounter++;
  1849. batch.vertCount++;
  1850. }
  1851. }
  1852. lastNormal = normal;
  1853. }
  1854. }
  1855. AssertFatal( vertCounter == mHighVertCount, "River, wrote incorrect number of verts in mVB_high" );
  1856. mVB_high.unlock();
  1857. //
  1858. // Do the high lod primitive buffer.
  1859. //
  1860. mPB_high.set( GFX, numTriangles * 3, numTriangles, GFXBufferTypeVolatile );
  1861. U16 *idxBuff;
  1862. mPB_high.lock(&idxBuff);
  1863. U32 curIdx = 0;
  1864. U32 batchOffset = 0;
  1865. // For each high lod batch, we must add indices to the buffer
  1866. // for each segment it contains ( and the count will depend on
  1867. // the division level columns/rows for each segment ).
  1868. // Temporaries for holding the indices of a quad
  1869. U32 p00, p01, p11, p10;
  1870. for ( U32 i = 0; i < mHighLODBatches.size(); i++ )
  1871. {
  1872. RiverRenderBatch &batch = mHighLODBatches[i];
  1873. batch.indexCount = 0;
  1874. batch.triangleCount = 0;
  1875. batch.startIndex = curIdx;
  1876. U32 temp = 0;
  1877. U32 segmentOffset = 0;
  1878. for ( U32 j = batch.startSegmentIdx; j <= batch.endSegmentIdx; j++ )
  1879. {
  1880. const RiverSegment &segment = mSegments[j];
  1881. // Loop through all divisions adding the indices to the
  1882. // high detail primitive buffer.
  1883. for ( U32 k = 0; k < segment.rows; k++ )
  1884. {
  1885. for ( U32 l = 0; l < segment.columns; l++ )
  1886. {
  1887. // The indices for this quad.
  1888. p00 = batchOffset + segmentOffset + l + k * ( segment.columns + 1 );
  1889. p01 = p00 + segment.columns + 1;
  1890. p11 = p01 + 1;
  1891. p10 = p00 + 1;
  1892. AssertFatal( p00 <= mHighTriangleCount * 3, "River, bad draw call!" );
  1893. AssertFatal( p01 <= mHighTriangleCount * 3, "River, bad draw call!" );
  1894. AssertFatal( p11 <= mHighTriangleCount * 3, "River, bad draw call!" );
  1895. AssertFatal( p10 <= mHighTriangleCount * 3, "River, bad draw call!" );
  1896. // Upper-Left triangle
  1897. idxBuff[curIdx] = p00;
  1898. curIdx++;
  1899. idxBuff[curIdx] = p01;
  1900. curIdx++;
  1901. idxBuff[curIdx] = p11;
  1902. curIdx++;
  1903. // Lower-Right Triangle
  1904. idxBuff[curIdx] = p00;
  1905. curIdx++;
  1906. idxBuff[curIdx] = p11;
  1907. curIdx++;
  1908. idxBuff[curIdx] = p10;
  1909. curIdx++;
  1910. batch.indexCount += 6;
  1911. batch.triangleCount += 2;
  1912. }
  1913. }
  1914. // Increment the sliceOffset by the number of verts
  1915. // used by this segment. So the next segment will index
  1916. // into new verts.
  1917. segmentOffset += ( segment.columns + 1 ) * ( segment.rows + 1 );
  1918. temp += ( segment.columns + 1 ) * ( segment.rows + 1 );
  1919. }
  1920. batchOffset += temp;
  1921. }
  1922. // Unlock the PrimitiveBuffer, we are done filling it.
  1923. mPB_high.unlock();
  1924. }
  1925. U32 River::_addNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal )
  1926. {
  1927. mNodes.increment();
  1928. RiverNode &node = mNodes.last();
  1929. node.point = pos;
  1930. node.width = width;
  1931. node.depth = depth;
  1932. node.normal = normal;
  1933. setMaskBits( NodeMask | RegenMask );
  1934. return mNodes.size() - 1;
  1935. }
  1936. U32 River::_insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx )
  1937. {
  1938. U32 ret;
  1939. RiverNode *node;
  1940. if ( idx == U32_MAX )
  1941. {
  1942. mNodes.increment();
  1943. node = &mNodes.last();
  1944. ret = mNodes.size() - 1;
  1945. }
  1946. else
  1947. {
  1948. mNodes.insert( idx );
  1949. node = &mNodes[idx];
  1950. ret = idx;
  1951. }
  1952. node->point = pos;
  1953. node->depth = depth;
  1954. node->width = width;
  1955. node->normal = normal;
  1956. return ret;
  1957. }
  1958. void River::setMetersPerSegment( F32 meters )
  1959. {
  1960. if ( meters < MIN_METERS_PER_SEGMENT )
  1961. {
  1962. Con::warnf( "River::setMetersPerSegment, specified meters (%g) is below the min meters (%g), NOT SET!", meters, MIN_METERS_PER_SEGMENT );
  1963. return;
  1964. }
  1965. mMetersPerSegment = meters;
  1966. _regenerate();
  1967. setMaskBits( RiverMask | RegenMask );
  1968. }
  1969. void River::setBatchSize( U32 size )
  1970. {
  1971. // Not functional
  1972. //mSegmentsPerBatch = size;
  1973. //_regenerate();
  1974. //setMaskBits( RiverMask | RegenMask );
  1975. }
  1976. void River::regenerate()
  1977. {
  1978. _regenerate();
  1979. setMaskBits( RegenMask );
  1980. }
  1981. void River::setMaxDivisionSize( F32 meters )
  1982. {
  1983. if ( meters < mMinDivisionSize )
  1984. mMaxDivisionSize = mMinDivisionSize;
  1985. else
  1986. mMaxDivisionSize = meters;
  1987. _regenerate();
  1988. setMaskBits( RiverMask | RegenMask );
  1989. }
  1990. //-------------------------------------------------------------------------
  1991. // Console Methods
  1992. //-------------------------------------------------------------------------
  1993. DefineEngineMethod( River, regenerate, void, (),,
  1994. "Intended as a helper to developers and editor scripts.\n"
  1995. "Force River to recreate its geometry."
  1996. )
  1997. {
  1998. object->regenerate();
  1999. }
  2000. DefineEngineMethod( River, setMetersPerSegment, void, ( F32 meters ),,
  2001. "Intended as a helper to developers and editor scripts.\n"
  2002. "@see SegmentLength field."
  2003. )
  2004. {
  2005. object->setMetersPerSegment( meters );
  2006. }
  2007. DefineEngineMethod( River, setBatchSize, void, ( F32 meters ),,
  2008. "Intended as a helper to developers and editor scripts.\n"
  2009. "BatchSize is not currently used."
  2010. )
  2011. {
  2012. object->setBatchSize( meters );
  2013. }
  2014. DefineEngineMethod( River, setNodeDepth, void, ( S32 idx, F32 meters ),,
  2015. "Intended as a helper to developers and editor scripts.\n"
  2016. "Sets the depth in meters of a particular node."
  2017. )
  2018. {
  2019. object->setNodeDepth( idx, meters );
  2020. }
  2021. DefineEngineMethod( River, setMaxDivisionSize, void, ( F32 meters ),,
  2022. "Intended as a helper to developers and editor scripts.\n"
  2023. "@see SubdivideLength field."
  2024. )
  2025. {
  2026. object->setMaxDivisionSize( meters );
  2027. }