W3DTerrainVisual.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DTerrainVisual.cpp /////////////////////////////////////////////////////////////////////
  24. // W3D implementation details for visual aspects of terrain
  25. // Author: Colin Day, April 2001
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <windows.h>
  30. #include "Common/GameState.h"
  31. #include "Common/GlobalData.h"
  32. #include "Common/PerfTimer.h"
  33. #include "Common/MapReaderWriterInfo.h"
  34. #include "Common/ThingTemplate.h"
  35. #include "Common/WellKnownKeys.h"
  36. #include "Common/TerrainTypes.h"
  37. #include "Common/Xfer.h"
  38. #include "GameClient/Drawable.h"
  39. #include "GameLogic/Object.h"
  40. #include "W3DDevice/GameClient/W3DScene.h"
  41. #include "W3DDevice/GameClient/W3DTerrainVisual.h"
  42. #include "W3DDevice/GameClient/WorldHeightMap.h"
  43. #include "W3DDevice/GameClient/W3DWater.h"
  44. #include "W3DDevice/GameClient/W3DDisplay.h"
  45. #include "W3DDevice/GameClient/W3DDebugIcons.h"
  46. #include "W3DDevice/GameClient/W3DTerrainTracks.h"
  47. #include "W3DDevice/GameClient/W3DGranny.h"
  48. #include "W3DDevice/GameClient/W3DShadow.h"
  49. #include "W3DDevice/GameClient/heightmap.h"
  50. #include "WW3D2/Light.h"
  51. #include "WW3D2/RendObj.h"
  52. #include "WW3D2/ColType.h"
  53. #include "WW3D2/ColTest.h"
  54. #include "WW3D2/assetmgr.h"
  55. #include "Common/UnitTimings.h" //Contains the DO_UNIT_TIMINGS define jba.
  56. //-------------------------------------------------------------------------------------------------
  57. //-------------------------------------------------------------------------------------------------
  58. W3DTerrainVisual::W3DTerrainVisual()
  59. {
  60. m_terrainRenderObject = NULL;
  61. m_terrainHeightMap = NULL;
  62. m_waterRenderObject = NULL;
  63. TheWaterRenderObj = NULL;
  64. } // end W3DTerrainVisual
  65. //-------------------------------------------------------------------------------------------------
  66. //-------------------------------------------------------------------------------------------------
  67. W3DTerrainVisual::~W3DTerrainVisual()
  68. {
  69. // release our render object
  70. if (TheTerrainRenderObject == m_terrainRenderObject) {
  71. TheTerrainRenderObject = NULL;
  72. }
  73. if (TheTerrainTracksRenderObjClassSystem)
  74. {
  75. delete TheTerrainTracksRenderObjClassSystem;
  76. TheTerrainTracksRenderObjClassSystem=NULL;
  77. }
  78. #ifdef INCLUDE_GRANNY_IN_BUILD
  79. if (TheGrannyRenderObjSystem)
  80. {
  81. delete TheGrannyRenderObjSystem;
  82. TheGrannyRenderObjSystem=NULL;
  83. }
  84. #endif
  85. if (TheW3DShadowManager)
  86. {
  87. delete TheW3DShadowManager;
  88. TheW3DShadowManager=NULL;
  89. }
  90. REF_PTR_RELEASE( m_waterRenderObject );
  91. TheWaterRenderObj=NULL;
  92. REF_PTR_RELEASE( m_terrainRenderObject );
  93. REF_PTR_RELEASE( m_terrainHeightMap );
  94. } // end ~W3DTerrainVisual
  95. //-------------------------------------------------------------------------------------------------
  96. /** init */
  97. //-------------------------------------------------------------------------------------------------
  98. void W3DTerrainVisual::init( void )
  99. {
  100. // extend
  101. TerrainVisual::init();
  102. // create a new render object for W3D
  103. m_terrainRenderObject = NEW_REF( HeightMapRenderObjClass, () );
  104. m_terrainRenderObject->Set_Collision_Type( PICK_TYPE_TERRAIN );
  105. TheTerrainRenderObject = m_terrainRenderObject;
  106. // initialize track drawing system
  107. TheTerrainTracksRenderObjClassSystem = NEW TerrainTracksRenderObjClassSystem;
  108. TheTerrainTracksRenderObjClassSystem->init(W3DDisplay::m_3DScene);
  109. #ifdef INCLUDE_GRANNY_IN_BUILD
  110. // initialize Granny model drawing system
  111. TheGrannyRenderObjSystem = NEW GrannyRenderObjSystem;
  112. #endif
  113. // initialize object shadow drawing system
  114. TheW3DShadowManager = NEW W3DShadowManager;
  115. TheW3DShadowManager->init();
  116. // create a water plane render object
  117. TheWaterRenderObj=m_waterRenderObject = NEW_REF( WaterRenderObjClass, () );
  118. m_waterRenderObject->init(TheGlobalData->m_waterPositionZ, TheGlobalData->m_waterExtentX, TheGlobalData->m_waterExtentY, W3DDisplay::m_3DScene, (WaterRenderObjClass::WaterType)TheGlobalData->m_waterType); //create a water plane that's 128x128 units
  119. m_waterRenderObject->Set_Position(Vector3(TheGlobalData->m_waterPositionX,TheGlobalData->m_waterPositionY,TheGlobalData->m_waterPositionZ)); //place water in world
  120. #ifdef DO_UNIT_TIMINGS
  121. #pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ")
  122. #else
  123. if (TheGlobalData->m_waterType == WaterRenderObjClass::WATER_TYPE_1_FB_REFLECTION)
  124. { // add water render object to the pre-pass scene (to be rendered before main scene)
  125. //W3DDisplay::m_prePass3DScene->Add_Render_Object( m_waterRenderObject);
  126. }
  127. else
  128. { // add water render object to the post-pass scene (to be rendered after main scene)
  129. W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject);
  130. }
  131. #endif
  132. if (TheGlobalData->m_useCloudPlane)
  133. m_waterRenderObject->toggleCloudLayer(true);
  134. else
  135. m_waterRenderObject->toggleCloudLayer(false);
  136. // set the vertex animated water properties
  137. Int waterSettingIndex = 0; // use index 0 settings by default
  138. TheTerrainVisual->setWaterGridHeightClamps( NULL,
  139. TheGlobalData->m_vertexWaterHeightClampLow[ waterSettingIndex ],
  140. TheGlobalData->m_vertexWaterHeightClampHi[ waterSettingIndex ] );
  141. TheTerrainVisual->setWaterTransform( NULL,
  142. TheGlobalData->m_vertexWaterAngle[ waterSettingIndex ],
  143. TheGlobalData->m_vertexWaterXPosition[ waterSettingIndex ],
  144. TheGlobalData->m_vertexWaterYPosition[ waterSettingIndex ],
  145. TheGlobalData->m_vertexWaterZPosition[ waterSettingIndex ] );
  146. TheTerrainVisual->setWaterGridResolution( NULL,
  147. TheGlobalData->m_vertexWaterXGridCells[ waterSettingIndex ],
  148. TheGlobalData->m_vertexWaterYGridCells[ waterSettingIndex ],
  149. TheGlobalData->m_vertexWaterGridSize[ waterSettingIndex ] );
  150. TheTerrainVisual->setWaterAttenuationFactors( NULL,
  151. TheGlobalData->m_vertexWaterAttenuationA[ waterSettingIndex ],
  152. TheGlobalData->m_vertexWaterAttenuationB[ waterSettingIndex ],
  153. TheGlobalData->m_vertexWaterAttenuationC[ waterSettingIndex ],
  154. TheGlobalData->m_vertexWaterAttenuationRange[ waterSettingIndex ] );
  155. m_isWaterGridRenderingEnabled = FALSE;
  156. } // end init
  157. //-------------------------------------------------------------------------------------------------
  158. /** reset */
  159. //-------------------------------------------------------------------------------------------------
  160. void W3DTerrainVisual::reset( void )
  161. {
  162. // extend
  163. TerrainVisual::reset();
  164. m_terrainRenderObject->reset();
  165. if (TheW3DShadowManager)
  166. TheW3DShadowManager->Reset();
  167. if (TheTerrainTracksRenderObjClassSystem)
  168. TheTerrainTracksRenderObjClassSystem->Reset();
  169. // reset water render object if present
  170. if( m_waterRenderObject )
  171. {
  172. for (Int i=0; i<5; i++)
  173. {
  174. //check if this texture was ever changed from default
  175. if (m_currentSkyboxTexNames[i] != m_initialSkyboxTexNames[i])
  176. {
  177. m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], m_initialSkyboxTexNames[i]);
  178. m_currentSkyboxTexNames[i]=m_initialSkyboxTexNames[i]; //update current state to new texture
  179. }
  180. }
  181. m_waterRenderObject->reset();
  182. }
  183. } // end reset
  184. //-------------------------------------------------------------------------------------------------
  185. /** update */
  186. //-------------------------------------------------------------------------------------------------
  187. void W3DTerrainVisual::update( void )
  188. {
  189. // extend
  190. TerrainVisual::update();
  191. // if we have a water render object, it has an update method
  192. if( m_waterRenderObject )
  193. m_waterRenderObject->update();
  194. } // end update
  195. //-------------------------------------------------------------------------------------------------
  196. /** load method for W3D visual terrain */
  197. //-------------------------------------------------------------------------------------------------
  198. Bool W3DTerrainVisual::load( AsciiString filename )
  199. {
  200. #if 0
  201. // (gth) Testing exclusion list asset releasing
  202. DynamicVectorClass<StringClass> exclusion_list(8000);
  203. WW3DAssetManager::Get_Instance()->Create_Asset_List(exclusion_list);
  204. exclusion_list.Add(StringClass("avcomanche"));
  205. exclusion_list.Add(StringClass("avcomanche_d"));
  206. exclusion_list.Add(StringClass("ptdogwood08"));
  207. exclusion_list.Add(StringClass("ptdogwood01_b"));
  208. exclusion_list.Add(StringClass("ptpalm01"));
  209. exclusion_list.Add(StringClass("ptpalm01_b"));
  210. exclusion_list.Add(StringClass("avhummer"));
  211. exclusion_list.Add(StringClass("avhummer_d"));
  212. exclusion_list.Add(StringClass("avleopard"));
  213. exclusion_list.Add(StringClass("avleopard_d"));
  214. WW3DAssetManager::Get_Instance()->Free_Assets_With_Exclusion_List(exclusion_list);
  215. #endif
  216. // enhancing functionality specific for W3D terrain
  217. if( TerrainVisual::load( filename ) == FALSE )
  218. return FALSE; // failed
  219. // open the terrain file
  220. CachedFileInputStream fileStrm;
  221. if( !fileStrm.open(filename) )
  222. {
  223. REF_PTR_RELEASE( m_terrainRenderObject );
  224. return FALSE;
  225. } // end if
  226. if( m_terrainRenderObject == NULL )
  227. return FALSE;
  228. REF_PTR_RELEASE( m_terrainHeightMap );
  229. ChunkInputStream *pStrm = &fileStrm;
  230. // allocate new height map data to read from file
  231. m_terrainHeightMap = NEW WorldHeightMap(pStrm);
  232. // Add any lights loaded by map.
  233. MapObject *pMapObj = MapObject::getFirstMapObject();
  234. while (pMapObj)
  235. {
  236. Dict *d = pMapObj->getProperties();
  237. if (pMapObj->isLight())
  238. {
  239. Coord3D loc = *pMapObj->getLocation();
  240. if (loc.z < 0) {
  241. Vector3 vec;
  242. loc.z = m_terrainRenderObject->getHeightMapHeight(loc.x, loc.y, NULL);
  243. loc.z += d->getReal(TheKey_lightHeightAboveTerrain);
  244. }
  245. // It is a light, and handled at the device level. jba.
  246. LightClass* lightP = NEW_REF(LightClass, (LightClass::POINT));
  247. RGBColor c;
  248. c.setFromInt(d->getInt(TheKey_lightAmbientColor));
  249. lightP->Set_Ambient( Vector3( c.red, c.green, c.blue ) );
  250. c.setFromInt(d->getInt(TheKey_lightDiffuseColor));
  251. lightP->Set_Diffuse( Vector3( c.red, c.green, c.blue) );
  252. lightP->Set_Position(Vector3(loc.x, loc.y, loc.z));
  253. lightP->Set_Far_Attenuation_Range(d->getReal(TheKey_lightInnerRadius), d->getReal(TheKey_lightOuterRadius));
  254. W3DDisplay::m_3DScene->Add_Render_Object(lightP);
  255. REF_PTR_RELEASE( lightP );
  256. }
  257. pMapObj = pMapObj->getNext();
  258. }
  259. RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator();
  260. // apply the heightmap to the terrain render object
  261. m_terrainRenderObject->initHeightData( m_terrainHeightMap->getDrawWidth(),
  262. m_terrainHeightMap->getDrawHeight(),
  263. m_terrainHeightMap,
  264. it);
  265. if (it) {
  266. W3DDisplay::m_3DScene->destroyLightsIterator(it);
  267. it = NULL;
  268. }
  269. // add our terrain render object to the scene
  270. W3DDisplay::m_3DScene->Add_Render_Object( m_terrainRenderObject );
  271. #if defined _DEBUG || defined _INTERNAL
  272. // Icon drawing utility object for pathfinding.
  273. W3DDebugIcons *icons = NEW W3DDebugIcons;
  274. W3DDisplay::m_3DScene->Add_Render_Object( icons );
  275. icons->Release_Ref(); // belongs to scene.
  276. #endif
  277. #ifdef DO_UNIT_TIMINGS
  278. #pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ")
  279. #else
  280. if (m_waterRenderObject)
  281. {
  282. W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject);
  283. m_waterRenderObject->enableWaterGrid(false);
  284. }
  285. #endif
  286. pMapObj = MapObject::getFirstMapObject();
  287. while (pMapObj)
  288. {
  289. Dict *d = pMapObj->getProperties();
  290. if (pMapObj->isScorch()) {
  291. const Coord3D *pos = pMapObj->getLocation();
  292. Vector3 loc(pos->x, pos->y, pos->z);
  293. Real radius = d->getReal(TheKey_objectRadius);
  294. Scorches type = (Scorches)d->getInt(TheKey_scorchType);
  295. m_terrainRenderObject->addScorch(loc, radius, type);
  296. }
  297. pMapObj = pMapObj->getNext();
  298. }
  299. // reset water render object if present
  300. if( m_waterRenderObject )
  301. {
  302. m_waterRenderObject->load();
  303. }
  304. return TRUE; // success
  305. } // end load
  306. // ------------------------------------------------------------------------------------------------
  307. // ------------------------------------------------------------------------------------------------
  308. void W3DTerrainVisual::enableWaterGrid( Bool enable )
  309. {
  310. //Get default water type
  311. m_isWaterGridRenderingEnabled = enable;
  312. // make the changes in the water render object
  313. if( m_waterRenderObject )
  314. m_waterRenderObject->enableWaterGrid( enable );
  315. } // end enableWaterGrid
  316. //-------------------------------------------------------------------------------------------------
  317. /** intersect the ray with the terrain, if a hit occurs TRUE is returned
  318. * and the result point on the terrain is returned in "result" */
  319. //-------------------------------------------------------------------------------------------------
  320. Bool W3DTerrainVisual::intersectTerrain( Coord3D *rayStart,
  321. Coord3D *rayEnd,
  322. Coord3D *result )
  323. {
  324. Bool hit = FALSE;
  325. // sanity
  326. if( rayStart == NULL || rayEnd == NULL )
  327. return hit;
  328. if( m_terrainRenderObject )
  329. {
  330. CastResultStruct res;
  331. LineSegClass lineSeg( Vector3( rayStart->x, rayStart->y, rayStart->z ),
  332. Vector3( rayEnd->x, rayEnd->y, rayEnd->z ) );
  333. RayCollisionTestClass rayTest( lineSeg, &res );
  334. hit = m_terrainRenderObject->Cast_Ray( rayTest );
  335. if( hit && result )
  336. {
  337. Vector3 point = rayTest.Result->ContactPoint;
  338. result->x = point.X;
  339. result->y = point.Y;
  340. result->z = point.Z;
  341. } // end if
  342. } // end if
  343. // return hit result
  344. return hit;
  345. } // end intersectTerrain
  346. //-------------------------------------------------------------------------------------------------
  347. //-------------------------------------------------------------------------------------------------
  348. void W3DTerrainVisual::getTerrainColorAt( Real x, Real y, RGBColor *pColor )
  349. {
  350. if( m_terrainHeightMap )
  351. m_terrainHeightMap->getTerrainColorAt( x, y, pColor );
  352. } // end getTerrainColorAt
  353. //-------------------------------------------------------------------------------------------------
  354. //-------------------------------------------------------------------------------------------------
  355. TerrainType *W3DTerrainVisual::getTerrainTile( Real x, Real y )
  356. {
  357. TerrainType *tile = NULL;
  358. if( m_terrainHeightMap )
  359. {
  360. AsciiString tileName = m_terrainHeightMap->getTerrainNameAt( x, y );
  361. tile = TheTerrainTypes->findTerrain( tileName );
  362. } // end if
  363. return tile;
  364. } // end getTerrainTile
  365. // ------------------------------------------------------------------------------------------------
  366. /** set min/max height values allowed in water grid pointed to by waterTable */
  367. // ------------------------------------------------------------------------------------------------
  368. void W3DTerrainVisual::setWaterGridHeightClamps( const WaterHandle *waterTable,
  369. Real minZ, Real maxZ )
  370. {
  371. if( m_waterRenderObject )
  372. m_waterRenderObject->setGridHeightClamps( minZ, maxZ );
  373. } // end setWaterGridHeightClamps
  374. // ------------------------------------------------------------------------------------------------
  375. /** adjust fallof parameters for grid change method */
  376. // ------------------------------------------------------------------------------------------------
  377. void W3DTerrainVisual::setWaterAttenuationFactors( const WaterHandle *waterTable,
  378. Real a, Real b, Real c, Real range )
  379. {
  380. if( m_waterRenderObject )
  381. m_waterRenderObject->setGridChangeAttenuationFactors( a, b, c, range );
  382. } // end setWaterAttenuationFactors
  383. // ------------------------------------------------------------------------------------------------
  384. /** set the water table position and orientation in world space */
  385. // ------------------------------------------------------------------------------------------------
  386. void W3DTerrainVisual::setWaterTransform( const WaterHandle *waterTable,
  387. Real angle, Real x, Real y, Real z )
  388. {
  389. if( m_waterRenderObject )
  390. m_waterRenderObject->setGridTransform( angle, x, y, z );
  391. } // end setWaterTransform
  392. // ------------------------------------------------------------------------------------------------
  393. /** set water table transform by matrix */
  394. // ------------------------------------------------------------------------------------------------
  395. void W3DTerrainVisual::setWaterTransform( const Matrix3D *transform )
  396. {
  397. if( m_waterRenderObject )
  398. m_waterRenderObject->setGridTransform( transform );
  399. } // end setWaterTransform
  400. // ------------------------------------------------------------------------------------------------
  401. /** get the water transform matrix */
  402. // ------------------------------------------------------------------------------------------------
  403. void W3DTerrainVisual::getWaterTransform( const WaterHandle *waterTable, Matrix3D *transform )
  404. {
  405. if( m_waterRenderObject )
  406. m_waterRenderObject->getGridTransform( transform );
  407. } // end getWaterTransform
  408. // ------------------------------------------------------------------------------------------------
  409. /** water grid resolution spacing */
  410. // ------------------------------------------------------------------------------------------------
  411. void W3DTerrainVisual::setWaterGridResolution( const WaterHandle *waterTable,
  412. Real gridCellsX, Real gridCellsY, Real cellSize )
  413. {
  414. if( m_waterRenderObject )
  415. m_waterRenderObject->setGridResolution( gridCellsX, gridCellsY, cellSize );
  416. } // end setWaterGridResolution
  417. // ------------------------------------------------------------------------------------------------
  418. /** get water grid resolution spacing */
  419. // ------------------------------------------------------------------------------------------------
  420. void W3DTerrainVisual::getWaterGridResolution( const WaterHandle *waterTable,
  421. Real *gridCellsX, Real *gridCellsY, Real *cellSize )
  422. {
  423. if( m_waterRenderObject )
  424. m_waterRenderObject->getGridResolution( gridCellsX, gridCellsY, cellSize );
  425. } // end getWaterGridResolution
  426. // ------------------------------------------------------------------------------------------------
  427. /** adjust the water grid in world coords by the delta */
  428. // ------------------------------------------------------------------------------------------------
  429. void W3DTerrainVisual::changeWaterHeight( Real x, Real y, Real delta )
  430. {
  431. if( m_waterRenderObject )
  432. m_waterRenderObject->changeGridHeight( x, y, delta );
  433. } // end changeWaterHeight
  434. // ------------------------------------------------------------------------------------------------
  435. // ------------------------------------------------------------------------------------------------
  436. void W3DTerrainVisual::addWaterVelocity( Real worldX, Real worldY,
  437. Real velocity, Real preferredHeight )
  438. {
  439. if( m_waterRenderObject )
  440. m_waterRenderObject->addVelocity( worldX, worldY, velocity, preferredHeight );
  441. } // end addWaterVelocity
  442. // ------------------------------------------------------------------------------------------------
  443. // ------------------------------------------------------------------------------------------------
  444. Bool W3DTerrainVisual::getWaterGridHeight( Real worldX, Real worldY, Real *height)
  445. {
  446. Real gridX, gridY;
  447. if (m_isWaterGridRenderingEnabled && m_waterRenderObject &&
  448. m_waterRenderObject->worldToGridSpace(worldX, worldY, gridX, gridY))
  449. { //point falls within grid, return correct height
  450. m_waterRenderObject->getGridVertexHeight(REAL_TO_INT(gridX),REAL_TO_INT(gridY),height);
  451. return TRUE;
  452. }
  453. return FALSE;
  454. }
  455. // ------------------------------------------------------------------------------------------------
  456. // ------------------------------------------------------------------------------------------------
  457. void W3DTerrainVisual::setRawMapHeight(const ICoord2D *gridPos, Int height)
  458. {
  459. if (m_terrainHeightMap) {
  460. Int x = gridPos->x+m_terrainHeightMap->getBorderSize();
  461. Int y = gridPos->y+m_terrainHeightMap->getBorderSize();
  462. //if (m_terrainHeightMap->getHeight(x,y) != height) //ML changed to prevent scissoring with roads
  463. if (m_terrainHeightMap->getHeight(x,y) > height)
  464. {
  465. m_terrainHeightMap->setRawHeight(x, y, height);
  466. m_terrainRenderObject->staticLightingChanged();
  467. }
  468. }
  469. }
  470. // ------------------------------------------------------------------------------------------------
  471. // ------------------------------------------------------------------------------------------------
  472. void W3DTerrainVisual::addFactionBibDrawable(Drawable *factionBuilding, Bool highlight, Real extra)
  473. {
  474. if (m_terrainHeightMap) {
  475. const Matrix3D * mtx = factionBuilding->getTransformMatrix();
  476. Vector3 corners[4];
  477. Coord3D pos;
  478. pos.set(0,0,0);
  479. Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth();
  480. Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra;
  481. const GeometryInfo info = factionBuilding->getTemplate()->getTemplateGeometryInfo();
  482. Real sizeX = info.getMajorRadius();
  483. Real sizeY = info.getMinorRadius();
  484. if (info.getGeomType() != GEOMETRY_BOX) {
  485. sizeY = sizeX;
  486. }
  487. corners[0].Set(pos.x, pos.y, pos.z);
  488. corners[0].X -= sizeX+extraWidth;
  489. corners[0].Y -= sizeY+extraWidth;
  490. corners[1].Set(pos.x, pos.y, pos.z);
  491. corners[1].X += sizeX+exitWidth+extraWidth;
  492. corners[1].Y -= sizeY+extraWidth;
  493. corners[2].Set(pos.x, pos.y, pos.z);
  494. corners[2].X += sizeX+exitWidth+extraWidth;
  495. corners[2].Y += sizeY+extraWidth;
  496. corners[3].Set(pos.x, pos.y, pos.z);
  497. corners[3].X -= sizeX+extraWidth;
  498. corners[3].Y += sizeY+extraWidth;
  499. mtx->Transform_Vector(*mtx, corners[0], &corners[0]);
  500. mtx->Transform_Vector(*mtx, corners[1], &corners[1]);
  501. mtx->Transform_Vector(*mtx, corners[2], &corners[2]);
  502. mtx->Transform_Vector(*mtx, corners[3], &corners[3]);
  503. m_terrainRenderObject->addTerrainBibDrawable(corners, factionBuilding->getID(), highlight);
  504. }
  505. }
  506. // ------------------------------------------------------------------------------------------------
  507. // ------------------------------------------------------------------------------------------------
  508. void W3DTerrainVisual::addFactionBib(Object *factionBuilding, Bool highlight, Real extra)
  509. {
  510. if (m_terrainHeightMap) {
  511. const Matrix3D * mtx = factionBuilding->getTransformMatrix();
  512. Vector3 corners[4];
  513. Coord3D pos;
  514. pos.set(0,0,0);
  515. Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth();
  516. Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra;
  517. const GeometryInfo info = factionBuilding->getGeometryInfo();
  518. Real sizeX = info.getMajorRadius();
  519. Real sizeY = info.getMinorRadius();
  520. if (info.getGeomType() != GEOMETRY_BOX) {
  521. sizeY = sizeX;
  522. }
  523. corners[0].Set(pos.x, pos.y, pos.z);
  524. corners[0].X -= sizeX+extraWidth;
  525. corners[0].Y -= sizeY+extraWidth;
  526. corners[1].Set(pos.x, pos.y, pos.z);
  527. corners[1].X += sizeX+exitWidth+extraWidth;
  528. corners[1].Y -= sizeY+extraWidth;
  529. corners[2].Set(pos.x, pos.y, pos.z);
  530. corners[2].X += sizeX+exitWidth+extraWidth;
  531. corners[2].Y += sizeY+extraWidth;
  532. corners[3].Set(pos.x, pos.y, pos.z);
  533. corners[3].X -= sizeX+extraWidth;
  534. corners[3].Y += sizeY+extraWidth;
  535. mtx->Transform_Vector(*mtx, corners[0], &corners[0]);
  536. mtx->Transform_Vector(*mtx, corners[1], &corners[1]);
  537. mtx->Transform_Vector(*mtx, corners[2], &corners[2]);
  538. mtx->Transform_Vector(*mtx, corners[3], &corners[3]);
  539. m_terrainRenderObject->addTerrainBib(corners, factionBuilding->getID(), highlight);
  540. }
  541. }
  542. // ------------------------------------------------------------------------------------------------
  543. // ------------------------------------------------------------------------------------------------
  544. void W3DTerrainVisual::removeFactionBibDrawable(Drawable *factionBuilding)
  545. {
  546. if (m_terrainHeightMap) {
  547. m_terrainRenderObject->removeTerrainBibDrawable(factionBuilding->getID());
  548. }
  549. }
  550. // ------------------------------------------------------------------------------------------------
  551. // ------------------------------------------------------------------------------------------------
  552. void W3DTerrainVisual::removeFactionBib(Object *factionBuilding)
  553. {
  554. if (m_terrainHeightMap) {
  555. m_terrainRenderObject->removeTerrainBib(factionBuilding->getID());
  556. }
  557. }
  558. // ------------------------------------------------------------------------------------------------
  559. // ------------------------------------------------------------------------------------------------
  560. void W3DTerrainVisual::removeAllBibs(void)
  561. {
  562. if (m_terrainHeightMap) {
  563. m_terrainRenderObject->removeAllTerrainBibs();
  564. }
  565. }
  566. // ------------------------------------------------------------------------------------------------
  567. // ------------------------------------------------------------------------------------------------
  568. void W3DTerrainVisual::removeBibHighlighting(void)
  569. {
  570. if (m_terrainHeightMap) {
  571. m_terrainRenderObject->removeTerrainBibHighlighting();
  572. }
  573. }
  574. // ------------------------------------------------------------------------------------------------
  575. // ------------------------------------------------------------------------------------------------
  576. void W3DTerrainVisual::setTerrainTracksDetail(void)
  577. {
  578. if (TheTerrainTracksRenderObjClassSystem)
  579. TheTerrainTracksRenderObjClassSystem->setDetail();
  580. }
  581. // ------------------------------------------------------------------------------------------------
  582. // ------------------------------------------------------------------------------------------------
  583. void W3DTerrainVisual::setShoreLineDetail(void)
  584. {
  585. if (m_terrainRenderObject)
  586. m_terrainRenderObject->setShoreLineDetail();
  587. }
  588. // ------------------------------------------------------------------------------------------------
  589. // ------------------------------------------------------------------------------------------------
  590. /// Replace the skybox texture
  591. void W3DTerrainVisual::replaceSkyboxTextures(const AsciiString *oldTexName[5], const AsciiString *newTexName[5])
  592. {
  593. if (m_waterRenderObject)
  594. {
  595. for (Int i=0; i<5; i++)
  596. {
  597. //check if this texture was never changed before and is still using the default art.
  598. if (m_initialSkyboxTexNames[i].isEmpty())
  599. { m_initialSkyboxTexNames[i]=*oldTexName[i];
  600. m_currentSkyboxTexNames[i]=*oldTexName[i];
  601. }
  602. if (m_currentSkyboxTexNames[i] != *newTexName[i])
  603. { m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], *newTexName[i]);
  604. m_currentSkyboxTexNames[i]=*newTexName[i]; //update current state to new texture
  605. }
  606. }
  607. }
  608. }
  609. // ------------------------------------------------------------------------------------------------
  610. /** CRC */
  611. // ------------------------------------------------------------------------------------------------
  612. void W3DTerrainVisual::crc( Xfer *xfer )
  613. {
  614. // extend base class
  615. TerrainVisual::crc( xfer );
  616. } // end CRC
  617. // ------------------------------------------------------------------------------------------------
  618. /** Xfer
  619. * Version Info:
  620. * 1: Initial version */
  621. // ------------------------------------------------------------------------------------------------
  622. void W3DTerrainVisual::xfer( Xfer *xfer )
  623. {
  624. // version
  625. XferVersion currentVersion = 2;
  626. XferVersion version = currentVersion;
  627. xfer->xferVersion( &version, currentVersion );
  628. // extend base class
  629. TerrainVisual::xfer( xfer );
  630. // flag for whether or not the water grid is enabled
  631. Bool gridEnabled = m_isWaterGridRenderingEnabled;
  632. xfer->xferBool( &gridEnabled );
  633. if( gridEnabled != m_isWaterGridRenderingEnabled )
  634. {
  635. DEBUG_CRASH(( "W3DTerrainVisual::xfer - m_isWaterGridRenderingEnabled mismatch\n" ));
  636. throw SC_INVALID_DATA;
  637. } // end if
  638. // xfer grid data if enabled
  639. if( gridEnabled )
  640. xfer->xferSnapshot( m_waterRenderObject );
  641. /*
  642. {
  643. // grid width and height
  644. Int width = getGridWidth();
  645. Int height = getGridheight();
  646. xfer->xferInt( &width );
  647. xfer->xferInt( &height );
  648. if( width != getGridWidth() )
  649. {
  650. DEBUG_CRASH(( "W3DTerainVisual::xfer - grid width mismatch '%d' should be '%d'\n",
  651. width, getGridWidth() ));
  652. throw SC_INVALID_DATA;
  653. } // end if
  654. if( height != getGridHeight() )
  655. {
  656. DEBUG_CRASH(( "W3DTerainVisual::xfer - grid height mismatch '%d' should be '%d'\n",
  657. height, getGridHeight() ));
  658. throw SC_INVALID_DATA;
  659. } // end if
  660. // write data for each grid
  661. } // end if
  662. */
  663. // Write out the terrain height data.
  664. if (version >= 2) {
  665. UnsignedByte *data = m_terrainHeightMap->getDataPtr();
  666. Int len = m_terrainHeightMap->getXExtent()*m_terrainHeightMap->getYExtent();
  667. Int xferLen = len;
  668. xfer->xferInt(&xferLen);
  669. if (len!=xferLen) {
  670. DEBUG_CRASH(("Bad height map length."));
  671. if (len>xferLen) {
  672. len = xferLen;
  673. }
  674. }
  675. xfer->xferUser(data, len);
  676. if (xfer->getXferMode() == XFER_LOAD) {
  677. // Update the display height map.
  678. m_terrainRenderObject->staticLightingChanged();
  679. }
  680. }
  681. } // end xfer
  682. // ------------------------------------------------------------------------------------------------
  683. /** Load post process */
  684. // ------------------------------------------------------------------------------------------------
  685. void W3DTerrainVisual::loadPostProcess( void )
  686. {
  687. // extend base class
  688. TerrainVisual::loadPostProcess();
  689. } // end loadPostProcess