W3DTerrainVisual.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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 "Common/UnitTimings.h" //Contains the DO_UNIT_TIMINGS define jba.
  39. #include "Common/QuickTrig.h"
  40. #include "GameClient/Drawable.h"
  41. #include "GameClient/ClientRandomValue.h"
  42. #include "GameLogic/Object.h"
  43. #include "GameLogic/GameLogic.h"
  44. #include "W3DDevice/GameClient/W3DScene.h"
  45. #include "W3DDevice/GameClient/W3DTerrainVisual.h"
  46. #include "W3DDevice/GameClient/WorldHeightMap.h"
  47. #include "W3DDevice/GameClient/W3DWater.h"
  48. #include "W3DDevice/GameClient/W3DDisplay.h"
  49. #include "W3DDevice/GameClient/W3DDebugIcons.h"
  50. #include "W3DDevice/GameClient/W3DTerrainTracks.h"
  51. #include "W3DDevice/GameClient/W3DGranny.h"
  52. #include "W3DDevice/GameClient/W3DShadow.h"
  53. #include "W3DDevice/GameClient/heightmap.h"
  54. #include "W3DDevice/GameClient/FlatHeightmap.h"
  55. #include "W3DDevice/GameClient/W3DSmudge.h"
  56. #include "W3DDevice/GameClient/Module/W3DModelDraw.h"
  57. #include "WW3D2/Light.h"
  58. #include "WW3D2/RendObj.h"
  59. #include "WW3D2/ColType.h"
  60. #include "WW3D2/ColTest.h"
  61. #include "WW3D2/assetmgr.h"
  62. class TestSeismicFilter : public SeismicSimulationFilterBase
  63. {
  64. virtual SeismicSimStatusCode filterCallback( WorldHeightMapInterfaceClass *heightMap, const SeismicSimulationNode *node )
  65. {
  66. Int life = node->m_life;
  67. if ( heightMap == NULL )
  68. return SEISMIC_STATUS_INVALID;
  69. if ( life == 0 )
  70. return SEISMIC_STATUS_ACTIVE;
  71. if ( life < 15 )
  72. {
  73. // ADD HEIGHT BECAUSE THE EXPLOSION IS PUSHING DIRT UP
  74. Real magnitude = node->m_magnitude;
  75. Real offsScalar = magnitude / (Real)life; // real-life, get it?
  76. Int radius = node->m_radius;
  77. Int border = heightMap->getBorderSize();
  78. Int centerX = node->m_center.x + border ;
  79. Int centerY = node->m_center.y + border ;
  80. UnsignedInt workspaceWidth = radius*2;
  81. Real *workspace = NEW( Real[ sqr(workspaceWidth) ] );
  82. Real *workspaceEnd = workspace + sqr(workspaceWidth);
  83. for ( Real *t = workspace; t < workspaceEnd; ++t ) *t = 0.0f;// clear the workspace
  84. for (Int x = 0; x < radius; ++x)
  85. {
  86. for (Int y = 0; y < radius; ++y)
  87. {
  88. Real distance = sqrt( sqr(x) + sqr(y) );//Pythagoras
  89. if ( distance < radius )
  90. {
  91. Real distScalar = cos( ( distance / radius * (PI/2) ) );
  92. Real height = (offsScalar * distScalar);
  93. workspace[ (radius + x) + workspaceWidth * (radius + y) ] = height + heightMap->getBilinearSampleSeismicZVelocity( centerX + x, centerY + y ) ;//kaleidoscope
  94. if ( x != 0 ) // non-zero test prevents cross-shaped double stamp
  95. {
  96. workspace[ (radius - x) + workspaceWidth * (radius + y) ] = height + heightMap->getBilinearSampleSeismicZVelocity( centerX - x, centerY + y ) ;
  97. if ( y != 0 )
  98. workspace[ (radius - x) + workspaceWidth * (radius - y) ] = height + heightMap->getBilinearSampleSeismicZVelocity( centerX - x, centerY - y ) ;
  99. }
  100. if ( y != 0 )
  101. workspace[ (radius + x) + workspaceWidth * (radius - y) ] = height + heightMap->getBilinearSampleSeismicZVelocity( centerX + x, centerY - y ) ;
  102. }
  103. }
  104. }
  105. // stuff the values from the workspace into the heightmap's velocities
  106. for (x = 0; x < workspaceWidth; ++x)
  107. for (Int y = 0; y < workspaceWidth; ++y)
  108. heightMap->setSeismicZVelocity( centerX - radius + x, centerY - radius + y, workspace[ x + workspaceWidth * y ] );
  109. delete [] workspace;
  110. return SEISMIC_STATUS_ACTIVE;
  111. }
  112. else
  113. return SEISMIC_STATUS_ZERO_ENERGY;
  114. }
  115. virtual Real applyGravityCallback( Real velocityIn )
  116. {
  117. Real velocityOut = velocityIn;
  118. velocityOut -= 1.5f;
  119. return velocityOut;
  120. }
  121. };
  122. static TestSeismicFilter testSeismicFilter;
  123. //-------------------------------------------------------------------------------------------------
  124. //-------------------------------------------------------------------------------------------------
  125. W3DTerrainVisual::W3DTerrainVisual()
  126. {
  127. m_terrainRenderObject = NULL;
  128. m_waterRenderObject = NULL;
  129. TheWaterRenderObj = NULL;
  130. m_logicHeightMap = NULL;
  131. #ifdef DO_SEISMIC_SIMULATIONS
  132. m_clientHeightMap = NULL;
  133. #endif
  134. } // end W3DTerrainVisual
  135. //-------------------------------------------------------------------------------------------------
  136. //-------------------------------------------------------------------------------------------------
  137. W3DTerrainVisual::~W3DTerrainVisual()
  138. {
  139. // release our render object
  140. if (TheTerrainRenderObject == m_terrainRenderObject) {
  141. TheTerrainRenderObject = NULL;
  142. }
  143. if (TheTerrainTracksRenderObjClassSystem)
  144. {
  145. delete TheTerrainTracksRenderObjClassSystem;
  146. TheTerrainTracksRenderObjClassSystem=NULL;
  147. }
  148. #ifdef INCLUDE_GRANNY_IN_BUILD
  149. if (TheGrannyRenderObjSystem)
  150. {
  151. delete TheGrannyRenderObjSystem;
  152. TheGrannyRenderObjSystem=NULL;
  153. }
  154. #endif
  155. if (TheW3DShadowManager)
  156. {
  157. delete TheW3DShadowManager;
  158. TheW3DShadowManager=NULL;
  159. }
  160. if (TheSmudgeManager)
  161. {
  162. delete TheSmudgeManager;
  163. TheSmudgeManager=NULL;
  164. }
  165. REF_PTR_RELEASE( m_waterRenderObject );
  166. TheWaterRenderObj=NULL;
  167. REF_PTR_RELEASE( m_terrainRenderObject );
  168. REF_PTR_RELEASE( m_logicHeightMap );
  169. #ifdef DO_SEISMIC_SIMULATIONS
  170. REF_PTR_RELEASE( m_clientHeightMap );
  171. #endif
  172. } // end ~W3DTerrainVisual
  173. //-------------------------------------------------------------------------------------------------
  174. /** init */
  175. //-------------------------------------------------------------------------------------------------
  176. void W3DTerrainVisual::init( void )
  177. {
  178. // extend
  179. TerrainVisual::init();
  180. // create a new render object for W3D
  181. m_terrainRenderObject = NEW_REF( HeightMapRenderObjClass, () );
  182. m_terrainRenderObject->Set_Collision_Type( PICK_TYPE_TERRAIN );
  183. TheTerrainRenderObject = m_terrainRenderObject;
  184. // initialize track drawing system
  185. TheTerrainTracksRenderObjClassSystem = NEW TerrainTracksRenderObjClassSystem;
  186. TheTerrainTracksRenderObjClassSystem->init(W3DDisplay::m_3DScene);
  187. #ifdef INCLUDE_GRANNY_IN_BUILD
  188. // initialize Granny model drawing system
  189. TheGrannyRenderObjSystem = NEW GrannyRenderObjSystem;
  190. #endif
  191. // initialize object shadow drawing system
  192. TheW3DShadowManager = NEW W3DShadowManager;
  193. TheW3DShadowManager->init();
  194. // create a water plane render object
  195. TheWaterRenderObj=m_waterRenderObject = NEW_REF( WaterRenderObjClass, () );
  196. 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
  197. m_waterRenderObject->Set_Position(Vector3(TheGlobalData->m_waterPositionX,TheGlobalData->m_waterPositionY,TheGlobalData->m_waterPositionZ)); //place water in world
  198. // create smudge rendering system.
  199. TheSmudgeManager = NEW(W3DSmudgeManager);
  200. TheSmudgeManager->init();
  201. #ifdef DO_UNIT_TIMINGS
  202. #pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ")
  203. #else
  204. if (TheGlobalData->m_waterType == WaterRenderObjClass::WATER_TYPE_1_FB_REFLECTION)
  205. { // add water render object to the pre-pass scene (to be rendered before main scene)
  206. //W3DDisplay::m_prePass3DScene->Add_Render_Object( m_waterRenderObject);
  207. }
  208. else
  209. { // add water render object to the post-pass scene (to be rendered after main scene)
  210. W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject);
  211. }
  212. #endif
  213. if (TheGlobalData->m_useCloudPlane)
  214. m_waterRenderObject->toggleCloudLayer(true);
  215. else
  216. m_waterRenderObject->toggleCloudLayer(false);
  217. // set the vertex animated water properties
  218. Int waterSettingIndex = 0; // use index 0 settings by default
  219. TheTerrainVisual->setWaterGridHeightClamps( NULL,
  220. TheGlobalData->m_vertexWaterHeightClampLow[ waterSettingIndex ],
  221. TheGlobalData->m_vertexWaterHeightClampHi[ waterSettingIndex ] );
  222. TheTerrainVisual->setWaterTransform( NULL,
  223. TheGlobalData->m_vertexWaterAngle[ waterSettingIndex ],
  224. TheGlobalData->m_vertexWaterXPosition[ waterSettingIndex ],
  225. TheGlobalData->m_vertexWaterYPosition[ waterSettingIndex ],
  226. TheGlobalData->m_vertexWaterZPosition[ waterSettingIndex ] );
  227. TheTerrainVisual->setWaterGridResolution( NULL,
  228. TheGlobalData->m_vertexWaterXGridCells[ waterSettingIndex ],
  229. TheGlobalData->m_vertexWaterYGridCells[ waterSettingIndex ],
  230. TheGlobalData->m_vertexWaterGridSize[ waterSettingIndex ] );
  231. TheTerrainVisual->setWaterAttenuationFactors( NULL,
  232. TheGlobalData->m_vertexWaterAttenuationA[ waterSettingIndex ],
  233. TheGlobalData->m_vertexWaterAttenuationB[ waterSettingIndex ],
  234. TheGlobalData->m_vertexWaterAttenuationC[ waterSettingIndex ],
  235. TheGlobalData->m_vertexWaterAttenuationRange[ waterSettingIndex ] );
  236. m_isWaterGridRenderingEnabled = FALSE;
  237. #ifdef DO_SEISMIC_SIMULATIONS
  238. m_seismicSimulationList.clear();
  239. #endif
  240. } // end init
  241. //-------------------------------------------------------------------------------------------------
  242. /** reset */
  243. //-------------------------------------------------------------------------------------------------
  244. void W3DTerrainVisual::reset( void )
  245. {
  246. // extend
  247. TerrainVisual::reset();
  248. m_terrainRenderObject->reset();
  249. if (TheW3DShadowManager)
  250. TheW3DShadowManager->Reset();
  251. if (TheSmudgeManager)
  252. TheSmudgeManager->reset();
  253. if (TheTerrainTracksRenderObjClassSystem)
  254. TheTerrainTracksRenderObjClassSystem->Reset();
  255. // reset water render object if present
  256. if( m_waterRenderObject )
  257. {
  258. for (Int i=0; i<5; i++)
  259. {
  260. //check if this texture was ever changed from default
  261. if (m_currentSkyboxTexNames[i] != m_initialSkyboxTexNames[i])
  262. {
  263. m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], m_initialSkyboxTexNames[i]);
  264. m_currentSkyboxTexNames[i]=m_initialSkyboxTexNames[i]; //update current state to new texture
  265. }
  266. }
  267. m_waterRenderObject->reset();
  268. }
  269. #ifdef DO_SEISMIC_SIMULATIONS
  270. m_seismicSimulationList.clear();
  271. #endif
  272. } // end reset
  273. //-------------------------------------------------------------------------------------------------
  274. /** update */
  275. //-------------------------------------------------------------------------------------------------
  276. void W3DTerrainVisual::update( void )
  277. {
  278. // extend
  279. TerrainVisual::update();
  280. #ifdef DO_SEISMIC_SIMULATIONS
  281. handleSeismicSimulations();
  282. #endif
  283. // if we have a water render object, it has an update method
  284. if( m_waterRenderObject )
  285. m_waterRenderObject->update();
  286. } // end update
  287. #ifdef DO_SEISMIC_SIMULATIONS
  288. void W3DTerrainVisual::addSeismicSimulation( const SeismicSimulationNode& sim )
  289. {
  290. // HERE WOULD BE A GREAT PLACE FOR AN IDIOT TEST:
  291. // REJECT SIMULATION NODES THAT ARE OFF SCREEN!!!!!!!!!!
  292. // HERE WOULD BE A GREAT PLACE FOR AN IDIOT TEST:
  293. // REJECT SIMULATION NODES THAT ARE OFF SCREEN!!!!!!!!!!
  294. m_seismicSimulationList.push_back( sim );
  295. }
  296. void W3DTerrainVisual::handleSeismicSimulations( void )
  297. {
  298. if ( ! m_clientHeightMap || ! m_logicHeightMap || ! m_terrainRenderObject )
  299. return;
  300. if ( ! m_seismicSimulationList.empty() )
  301. {
  302. SeismicSimulationListIt it = m_seismicSimulationList.begin();
  303. m_clientHeightMap->clearSeismicUpdateFlags();
  304. while ( it != m_seismicSimulationList.end() )
  305. {
  306. SeismicSimulationNode *ssn = &*it;
  307. if ( ssn )
  308. {
  309. SeismicSimulationFilterBase::SeismicSimStatusCode code = ssn->handleFilterCallback( m_clientHeightMap );
  310. DEBUG_ASSERTCRASH( code != SeismicSimulationFilterBase::SEISMIC_STATUS_INVALID, ("Trouble in the Seismic simulator.") );
  311. switch ( code )
  312. {
  313. case SeismicSimulationFilterBase::SEISMIC_STATUS_ACTIVE:
  314. {
  315. break;
  316. }
  317. case SeismicSimulationFilterBase::SEISMIC_STATUS_ZERO_ENERGY:
  318. {
  319. break;
  320. }
  321. }
  322. Int border = m_clientHeightMap->getBorderSizeInline();
  323. // Now we apply some gravity to the dirt, so it falls back to its "original" height
  324. UnsignedInt fallCount = 0;
  325. for (Int x = border+ssn->m_region.lo.x; x < border+ssn->m_region.hi.x; ++x)
  326. {
  327. for (Int y = border+ssn->m_region.lo.y; y < border+ssn->m_region.hi.y; ++y)
  328. {
  329. if ( ! m_clientHeightMap->getSeismicUpdateFlag( x, y ) )
  330. {
  331. UnsignedByte heightOfOriginal = m_logicHeightMap->getHeight( x, y ); // LOGIC, YES DEFINITELY THE LOGIC
  332. Real oldSpeed = m_clientHeightMap->getSeismicZVelocity( x, y );
  333. Real newSpeed = ssn->applyGravity( oldSpeed );// - 0.5f;
  334. m_clientHeightMap->setSeismicZVelocity( x, y, newSpeed );
  335. Int heightToUse = m_clientHeightMap->getHeight( x, y ) + newSpeed ;
  336. if (heightToUse <= heightOfOriginal)
  337. {
  338. heightToUse = heightOfOriginal;
  339. m_clientHeightMap->setSeismicZVelocity( x, y, 0.0f ); //poof! the dirt hit ground level so stop "falling"
  340. }
  341. else
  342. {
  343. ++fallCount;
  344. if ( heightToUse > 255 )
  345. heightToUse = 255;
  346. }
  347. m_clientHeightMap->setRawHeight( x, y, heightToUse );
  348. m_clientHeightMap->setSeismicUpdateFlag( x, y, TRUE );
  349. }
  350. }
  351. }
  352. if ( fallCount == 0 )
  353. ssn->m_clean = TRUE;
  354. }
  355. ++it;
  356. }
  357. }
  358. }
  359. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  360. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  361. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  362. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  363. void W3DTerrainVisual::updateSeismicSimulations( void )
  364. {
  365. if (m_logicHeightMap==NULL)
  366. return;
  367. if (m_clientHeightMap==NULL)
  368. return;
  369. if (m_terrainRenderObject==NULL)
  370. return;
  371. if ( ! m_seismicSimulationList.empty() )
  372. {
  373. SeismicSimulationListIt it = m_seismicSimulationList.begin();
  374. // First we run through the list and do our business for each region
  375. while ( it != m_seismicSimulationList.end() )
  376. {
  377. SeismicSimulationNode *hur = &*it;
  378. if ( hur )
  379. {
  380. Int border = m_clientHeightMap->getBorderSizeInline();
  381. TheTerrainRenderObject->updateBlock(
  382. hur->m_region.lo.x + border,
  383. hur->m_region.lo.y + border,
  384. hur->m_region.hi.x + border,
  385. hur->m_region.hi.y + border,
  386. m_clientHeightMap,
  387. 0);
  388. }
  389. ++it;
  390. }
  391. // Then we check to see if these need to get erased from the list
  392. it = m_seismicSimulationList.begin();
  393. while ( it != m_seismicSimulationList.end() )
  394. {
  395. SeismicSimulationNode *hur = &*it;
  396. if ( hur->m_clean )
  397. {
  398. it = m_seismicSimulationList.erase( it );
  399. }
  400. else
  401. ++it;
  402. }
  403. }
  404. }
  405. #endif //#defined DO_SEISMIC_SIMULATIONS
  406. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  407. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  408. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  409. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  410. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  411. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  412. //-------------------------------------------------------------------------------------------------
  413. /** load method for W3D visual terrain */
  414. //-------------------------------------------------------------------------------------------------
  415. Bool W3DTerrainVisual::load( AsciiString filename )
  416. {
  417. #if 0
  418. // (gth) Testing exclusion list asset releasing
  419. DynamicVectorClass<StringClass> exclusion_list(8000);
  420. WW3DAssetManager::Get_Instance()->Create_Asset_List(exclusion_list);
  421. exclusion_list.Add(StringClass("avcomanche"));
  422. exclusion_list.Add(StringClass("avcomanche_d"));
  423. exclusion_list.Add(StringClass("ptdogwood08"));
  424. exclusion_list.Add(StringClass("ptdogwood01_b"));
  425. exclusion_list.Add(StringClass("ptpalm01"));
  426. exclusion_list.Add(StringClass("ptpalm01_b"));
  427. exclusion_list.Add(StringClass("avhummer"));
  428. exclusion_list.Add(StringClass("avhummer_d"));
  429. exclusion_list.Add(StringClass("avleopard"));
  430. exclusion_list.Add(StringClass("avleopard_d"));
  431. WW3DAssetManager::Get_Instance()->Free_Assets_With_Exclusion_List(exclusion_list);
  432. #endif
  433. // enhancing functionality specific for W3D terrain
  434. if( TerrainVisual::load( filename ) == FALSE )
  435. return FALSE; // failed
  436. // open the terrain file
  437. CachedFileInputStream fileStrm;
  438. if( !fileStrm.open(filename) )
  439. {
  440. REF_PTR_RELEASE( m_terrainRenderObject );
  441. return FALSE;
  442. } // end if
  443. if( m_terrainRenderObject == NULL )
  444. return FALSE;
  445. ChunkInputStream *pStrm = &fileStrm;
  446. // allocate new height map data to read from file
  447. REF_PTR_RELEASE( m_logicHeightMap );
  448. m_logicHeightMap = NEW WorldHeightMap(pStrm);
  449. #ifdef DO_SEISMIC_SIMULATIONS
  450. fileStrm.close();
  451. fileStrm.open(filename);
  452. pStrm = &fileStrm;
  453. REF_PTR_RELEASE( m_clientHeightMap );
  454. m_clientHeightMap = NEW WorldHeightMap( pStrm );
  455. #endif
  456. // Add any lights loaded by map.
  457. MapObject *pMapObj = MapObject::getFirstMapObject();
  458. while (pMapObj)
  459. {
  460. Dict *d = pMapObj->getProperties();
  461. if (pMapObj->isLight())
  462. {
  463. Coord3D loc = *pMapObj->getLocation();
  464. if (loc.z < 0) {
  465. Vector3 vec;
  466. loc.z = m_terrainRenderObject->getHeightMapHeight(loc.x, loc.y, NULL);
  467. loc.z += d->getReal(TheKey_lightHeightAboveTerrain);
  468. }
  469. // It is a light, and handled at the device level. jba.
  470. LightClass* lightP = NEW_REF(LightClass, (LightClass::POINT));
  471. RGBColor c;
  472. c.setFromInt(d->getInt(TheKey_lightAmbientColor));
  473. lightP->Set_Ambient( Vector3( c.red, c.green, c.blue ) );
  474. c.setFromInt(d->getInt(TheKey_lightDiffuseColor));
  475. lightP->Set_Diffuse( Vector3( c.red, c.green, c.blue) );
  476. lightP->Set_Position(Vector3(loc.x, loc.y, loc.z));
  477. lightP->Set_Far_Attenuation_Range(d->getReal(TheKey_lightInnerRadius), d->getReal(TheKey_lightOuterRadius));
  478. W3DDisplay::m_3DScene->Add_Render_Object(lightP);
  479. REF_PTR_RELEASE( lightP );
  480. }
  481. pMapObj = pMapObj->getNext();
  482. }
  483. RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator();
  484. // apply the heightmap to the terrain render object
  485. #ifdef DO_SEISMIC_SIMULATIONS
  486. m_terrainRenderObject->initHeightData( m_clientHeightMap->getDrawWidth(),
  487. m_clientHeightMap->getDrawHeight(),
  488. m_clientHeightMap,
  489. it);
  490. #else
  491. m_terrainRenderObject->initHeightData( m_logicHeightMap->getDrawWidth(),
  492. m_logicHeightMap->getDrawHeight(),
  493. m_logicHeightMap,
  494. it);
  495. #endif
  496. if (it) {
  497. W3DDisplay::m_3DScene->destroyLightsIterator(it);
  498. it = NULL;
  499. }
  500. // add our terrain render object to the scene
  501. W3DDisplay::m_3DScene->Add_Render_Object( m_terrainRenderObject );
  502. #if defined _DEBUG || defined _INTERNAL
  503. // Icon drawing utility object for pathfinding.
  504. W3DDebugIcons *icons = NEW W3DDebugIcons;
  505. W3DDisplay::m_3DScene->Add_Render_Object( icons );
  506. icons->Release_Ref(); // belongs to scene.
  507. #endif
  508. #ifdef DO_UNIT_TIMINGS
  509. #pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ")
  510. #else
  511. if (m_waterRenderObject)
  512. {
  513. W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject);
  514. m_waterRenderObject->enableWaterGrid(false);
  515. m_waterRenderObject->updateMapOverrides();
  516. }
  517. #endif
  518. pMapObj = MapObject::getFirstMapObject();
  519. while (pMapObj)
  520. {
  521. Dict *d = pMapObj->getProperties();
  522. if (pMapObj->isScorch()) {
  523. const Coord3D *pos = pMapObj->getLocation();
  524. Vector3 loc(pos->x, pos->y, pos->z);
  525. Real radius = d->getReal(TheKey_objectRadius);
  526. Scorches type = (Scorches)d->getInt(TheKey_scorchType);
  527. m_terrainRenderObject->addScorch(loc, radius, type);
  528. }
  529. pMapObj = pMapObj->getNext();
  530. }
  531. // reset water render object if present
  532. if( m_waterRenderObject )
  533. {
  534. m_waterRenderObject->load();
  535. }
  536. return TRUE; // success
  537. } // end load
  538. // ------------------------------------------------------------------------------------------------
  539. // ------------------------------------------------------------------------------------------------
  540. void W3DTerrainVisual::enableWaterGrid( Bool enable )
  541. {
  542. //Get default water type
  543. m_isWaterGridRenderingEnabled = enable;
  544. // make the changes in the water render object
  545. if( m_waterRenderObject )
  546. m_waterRenderObject->enableWaterGrid( enable );
  547. } // end enableWaterGrid
  548. //-------------------------------------------------------------------------------------------------
  549. /** intersect the ray with the terrain, if a hit occurs TRUE is returned
  550. * and the result point on the terrain is returned in "result" */
  551. //-------------------------------------------------------------------------------------------------
  552. Bool W3DTerrainVisual::intersectTerrain( Coord3D *rayStart,
  553. Coord3D *rayEnd,
  554. Coord3D *result )
  555. {
  556. Bool hit = FALSE;
  557. // sanity
  558. if( rayStart == NULL || rayEnd == NULL )
  559. return hit;
  560. if( m_terrainRenderObject )
  561. {
  562. CastResultStruct res;
  563. LineSegClass lineSeg( Vector3( rayStart->x, rayStart->y, rayStart->z ),
  564. Vector3( rayEnd->x, rayEnd->y, rayEnd->z ) );
  565. RayCollisionTestClass rayTest( lineSeg, &res );
  566. hit = m_terrainRenderObject->Cast_Ray( rayTest );
  567. if( hit && result )
  568. {
  569. Vector3 point = rayTest.Result->ContactPoint;
  570. result->x = point.X;
  571. result->y = point.Y;
  572. result->z = point.Z;
  573. } // end if
  574. } // end if
  575. // return hit result
  576. return hit;
  577. } // end intersectTerrain
  578. //-------------------------------------------------------------------------------------------------
  579. //-------------------------------------------------------------------------------------------------
  580. void W3DTerrainVisual::getTerrainColorAt( Real x, Real y, RGBColor *pColor )
  581. {
  582. #ifdef DO_SEISMIC_SIMULATIONS
  583. if( m_clientHeightMap )
  584. m_clientHeightMap->getTerrainColorAt( x, y, pColor );
  585. #else
  586. if( m_logicHeightMap )
  587. m_logicHeightMap->getTerrainColorAt( x, y, pColor );
  588. #endif
  589. } // end getTerrainColorAt
  590. //-------------------------------------------------------------------------------------------------
  591. //-------------------------------------------------------------------------------------------------
  592. TerrainType *W3DTerrainVisual::getTerrainTile( Real x, Real y )
  593. {
  594. TerrainType *tile = NULL;
  595. #ifdef DO_SEISMIC_SIMULATIONS
  596. if( m_clientHeightMap )
  597. {
  598. AsciiString tileName = m_clientHeightMap->getTerrainNameAt( x, y );
  599. tile = TheTerrainTypes->findTerrain( tileName );
  600. } // end if
  601. #else
  602. if( m_logicHeightMap )
  603. {
  604. AsciiString tileName = m_logicHeightMap->getTerrainNameAt( x, y );
  605. tile = TheTerrainTypes->findTerrain( tileName );
  606. } // end if
  607. #endif
  608. return tile;
  609. } // end getTerrainTile
  610. // ------------------------------------------------------------------------------------------------
  611. /** set min/max height values allowed in water grid pointed to by waterTable */
  612. // ------------------------------------------------------------------------------------------------
  613. void W3DTerrainVisual::setWaterGridHeightClamps( const WaterHandle *waterTable,
  614. Real minZ, Real maxZ )
  615. {
  616. if( m_waterRenderObject )
  617. m_waterRenderObject->setGridHeightClamps( minZ, maxZ );
  618. } // end setWaterGridHeightClamps
  619. // ------------------------------------------------------------------------------------------------
  620. /** adjust fallof parameters for grid change method */
  621. // ------------------------------------------------------------------------------------------------
  622. void W3DTerrainVisual::setWaterAttenuationFactors( const WaterHandle *waterTable,
  623. Real a, Real b, Real c, Real range )
  624. {
  625. if( m_waterRenderObject )
  626. m_waterRenderObject->setGridChangeAttenuationFactors( a, b, c, range );
  627. } // end setWaterAttenuationFactors
  628. // ------------------------------------------------------------------------------------------------
  629. /** set the water table position and orientation in world space */
  630. // ------------------------------------------------------------------------------------------------
  631. void W3DTerrainVisual::setWaterTransform( const WaterHandle *waterTable,
  632. Real angle, Real x, Real y, Real z )
  633. {
  634. if( m_waterRenderObject )
  635. m_waterRenderObject->setGridTransform( angle, x, y, z );
  636. } // end setWaterTransform
  637. // ------------------------------------------------------------------------------------------------
  638. /** set water table transform by matrix */
  639. // ------------------------------------------------------------------------------------------------
  640. void W3DTerrainVisual::setWaterTransform( const Matrix3D *transform )
  641. {
  642. if( m_waterRenderObject )
  643. m_waterRenderObject->setGridTransform( transform );
  644. } // end setWaterTransform
  645. // ------------------------------------------------------------------------------------------------
  646. /** get the water transform matrix */
  647. // ------------------------------------------------------------------------------------------------
  648. void W3DTerrainVisual::getWaterTransform( const WaterHandle *waterTable, Matrix3D *transform )
  649. {
  650. if( m_waterRenderObject )
  651. m_waterRenderObject->getGridTransform( transform );
  652. } // end getWaterTransform
  653. // ------------------------------------------------------------------------------------------------
  654. /** water grid resolution spacing */
  655. // ------------------------------------------------------------------------------------------------
  656. void W3DTerrainVisual::setWaterGridResolution( const WaterHandle *waterTable,
  657. Real gridCellsX, Real gridCellsY, Real cellSize )
  658. {
  659. if( m_waterRenderObject )
  660. m_waterRenderObject->setGridResolution( gridCellsX, gridCellsY, cellSize );
  661. } // end setWaterGridResolution
  662. // ------------------------------------------------------------------------------------------------
  663. /** get water grid resolution spacing */
  664. // ------------------------------------------------------------------------------------------------
  665. void W3DTerrainVisual::getWaterGridResolution( const WaterHandle *waterTable,
  666. Real *gridCellsX, Real *gridCellsY, Real *cellSize )
  667. {
  668. if( m_waterRenderObject )
  669. m_waterRenderObject->getGridResolution( gridCellsX, gridCellsY, cellSize );
  670. } // end getWaterGridResolution
  671. // ------------------------------------------------------------------------------------------------
  672. /** adjust the water grid in world coords by the delta */
  673. // ------------------------------------------------------------------------------------------------
  674. void W3DTerrainVisual::changeWaterHeight( Real x, Real y, Real delta )
  675. {
  676. if( m_waterRenderObject )
  677. m_waterRenderObject->changeGridHeight( x, y, delta );
  678. } // end changeWaterHeight
  679. // ------------------------------------------------------------------------------------------------
  680. // ------------------------------------------------------------------------------------------------
  681. void W3DTerrainVisual::addWaterVelocity( Real worldX, Real worldY,
  682. Real velocity, Real preferredHeight )
  683. {
  684. if( m_waterRenderObject )
  685. m_waterRenderObject->addVelocity( worldX, worldY, velocity, preferredHeight );
  686. } // end addWaterVelocity
  687. // ------------------------------------------------------------------------------------------------
  688. // ------------------------------------------------------------------------------------------------
  689. Bool W3DTerrainVisual::getWaterGridHeight( Real worldX, Real worldY, Real *height)
  690. {
  691. Real gridX, gridY;
  692. if (m_isWaterGridRenderingEnabled && m_waterRenderObject &&
  693. m_waterRenderObject->worldToGridSpace(worldX, worldY, gridX, gridY))
  694. { //point falls within grid, return correct height
  695. m_waterRenderObject->getGridVertexHeight(REAL_TO_INT(gridX),REAL_TO_INT(gridY),height);
  696. return TRUE;
  697. }
  698. return FALSE;
  699. }
  700. // ------------------------------------------------------------------------------------------------
  701. // ------------------------------------------------------------------------------------------------
  702. void W3DTerrainVisual::setRawMapHeight(const ICoord2D *gridPos, Int height)
  703. {
  704. // This method writes to the m_logicHeightMap member,
  705. // since m_logicHeightMap is the true, golden standard to which m_clientHeightMap
  706. // interpolates during or after its Seismic simulation displaces it..
  707. // THIS IS TRUE ONLY WHEN DO_SEISMIC_SIMULATIONS is defined M Lorenzen, 8/23/03
  708. if (m_logicHeightMap)
  709. {
  710. Int x = gridPos->x+m_logicHeightMap->getBorderSizeInline();
  711. Int y = gridPos->y+m_logicHeightMap->getBorderSizeInline();
  712. //if (m_logicHeightMap->getHeight(x,y) != height) //ML changed to prevent scissoring with roads
  713. if (m_logicHeightMap->getHeight(x,y) > height)
  714. {
  715. m_logicHeightMap->setRawHeight(x, y, height);
  716. m_terrainRenderObject->staticLightingChanged(); // OOH! this could benefit from the new Seismic update code
  717. #ifdef DO_SEISMIC_SIMULATIONS
  718. if ( m_clientHeightMap )
  719. {
  720. if ( height < m_clientHeightMap->getHeight( x,y ) )
  721. m_clientHeightMap->setRawHeight( x, y, height ); // if the client map is heigher than this height, it will fall down to it anyway!
  722. }
  723. #endif
  724. }
  725. }
  726. }
  727. // ------------------------------------------------------------------------------------------------
  728. // ------------------------------------------------------------------------------------------------
  729. Int W3DTerrainVisual::getRawMapHeight(const ICoord2D *gridPos)
  730. {
  731. if (m_logicHeightMap)
  732. {
  733. Int x = gridPos->x+m_logicHeightMap->getBorderSizeInline();
  734. Int y = gridPos->y+m_logicHeightMap->getBorderSizeInline();
  735. //if (m_logicHeightMap->getHeight(x,y) != height) //ML changed to prevent scissoring with roads
  736. return m_logicHeightMap->getHeight(x,y) ;
  737. }
  738. return 0;
  739. }
  740. // ------------------------------------------------------------------------------------------------
  741. // ------------------------------------------------------------------------------------------------
  742. void W3DTerrainVisual::addFactionBibDrawable(Drawable *factionBuilding, Bool highlight, Real extra)
  743. {
  744. #ifdef DO_SEISMIC_SIMULATIONS
  745. if (m_clientHeightMap)
  746. #else
  747. if (m_logicHeightMap)
  748. #endif
  749. {
  750. const Matrix3D * mtx = factionBuilding->getTransformMatrix();
  751. Vector3 corners[4];
  752. Coord3D pos;
  753. pos.set(0,0,0);
  754. Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth();
  755. Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra;
  756. const GeometryInfo info = factionBuilding->getTemplate()->getTemplateGeometryInfo();
  757. Real sizeX = info.getMajorRadius();
  758. Real sizeY = info.getMinorRadius();
  759. if (info.getGeomType() != GEOMETRY_BOX) {
  760. sizeY = sizeX;
  761. }
  762. corners[0].Set(pos.x, pos.y, pos.z);
  763. corners[0].X -= sizeX+extraWidth;
  764. corners[0].Y -= sizeY+extraWidth;
  765. corners[1].Set(pos.x, pos.y, pos.z);
  766. corners[1].X += sizeX+exitWidth+extraWidth;
  767. corners[1].Y -= sizeY+extraWidth;
  768. corners[2].Set(pos.x, pos.y, pos.z);
  769. corners[2].X += sizeX+exitWidth+extraWidth;
  770. corners[2].Y += sizeY+extraWidth;
  771. corners[3].Set(pos.x, pos.y, pos.z);
  772. corners[3].X -= sizeX+extraWidth;
  773. corners[3].Y += sizeY+extraWidth;
  774. mtx->Transform_Vector(*mtx, corners[0], &corners[0]);
  775. mtx->Transform_Vector(*mtx, corners[1], &corners[1]);
  776. mtx->Transform_Vector(*mtx, corners[2], &corners[2]);
  777. mtx->Transform_Vector(*mtx, corners[3], &corners[3]);
  778. m_terrainRenderObject->addTerrainBibDrawable(corners, factionBuilding->getID(), highlight);
  779. }
  780. }
  781. // ------------------------------------------------------------------------------------------------
  782. // ------------------------------------------------------------------------------------------------
  783. void W3DTerrainVisual::addFactionBib(Object *factionBuilding, Bool highlight, Real extra)
  784. {
  785. #ifdef DO_SEISMIC_SIMULATIONS
  786. if (m_clientHeightMap)
  787. #else
  788. if (m_logicHeightMap)
  789. #endif
  790. {
  791. const Matrix3D * mtx = factionBuilding->getTransformMatrix();
  792. Vector3 corners[4];
  793. Coord3D pos;
  794. pos.set(0,0,0);
  795. Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth();
  796. Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra;
  797. const GeometryInfo info = factionBuilding->getGeometryInfo();
  798. Real sizeX = info.getMajorRadius();
  799. Real sizeY = info.getMinorRadius();
  800. if (info.getGeomType() != GEOMETRY_BOX) {
  801. sizeY = sizeX;
  802. }
  803. corners[0].Set(pos.x, pos.y, pos.z);
  804. corners[0].X -= sizeX+extraWidth;
  805. corners[0].Y -= sizeY+extraWidth;
  806. corners[1].Set(pos.x, pos.y, pos.z);
  807. corners[1].X += sizeX+exitWidth+extraWidth;
  808. corners[1].Y -= sizeY+extraWidth;
  809. corners[2].Set(pos.x, pos.y, pos.z);
  810. corners[2].X += sizeX+exitWidth+extraWidth;
  811. corners[2].Y += sizeY+extraWidth;
  812. corners[3].Set(pos.x, pos.y, pos.z);
  813. corners[3].X -= sizeX+extraWidth;
  814. corners[3].Y += sizeY+extraWidth;
  815. mtx->Transform_Vector(*mtx, corners[0], &corners[0]);
  816. mtx->Transform_Vector(*mtx, corners[1], &corners[1]);
  817. mtx->Transform_Vector(*mtx, corners[2], &corners[2]);
  818. mtx->Transform_Vector(*mtx, corners[3], &corners[3]);
  819. m_terrainRenderObject->addTerrainBib(corners, factionBuilding->getID(), highlight);
  820. }
  821. }
  822. // ------------------------------------------------------------------------------------------------
  823. // ------------------------------------------------------------------------------------------------
  824. void W3DTerrainVisual::removeFactionBibDrawable(Drawable *factionBuilding)
  825. {
  826. if (m_terrainRenderObject) {
  827. m_terrainRenderObject->removeTerrainBibDrawable(factionBuilding->getID());
  828. }
  829. }
  830. // ------------------------------------------------------------------------------------------------
  831. // ------------------------------------------------------------------------------------------------
  832. void W3DTerrainVisual::removeFactionBib(Object *factionBuilding)
  833. {
  834. if (m_terrainRenderObject) {
  835. m_terrainRenderObject->removeTerrainBib(factionBuilding->getID());
  836. }
  837. }
  838. // ------------------------------------------------------------------------------------------------
  839. // ------------------------------------------------------------------------------------------------
  840. void W3DTerrainVisual::removeAllBibs(void)
  841. {
  842. if (m_terrainRenderObject) {
  843. m_terrainRenderObject->removeAllTerrainBibs();
  844. }
  845. }
  846. // ------------------------------------------------------------------------------------------------
  847. // ------------------------------------------------------------------------------------------------
  848. void W3DTerrainVisual::removeBibHighlighting(void)
  849. {
  850. if (m_terrainRenderObject) {
  851. m_terrainRenderObject->removeTerrainBibHighlighting();
  852. }
  853. }
  854. // ------------------------------------------------------------------------------------------------
  855. // ------------------------------------------------------------------------------------------------
  856. void W3DTerrainVisual::removeTreesAndPropsForConstruction(const Coord3D* pos,
  857. const GeometryInfo& geom,
  858. Real angle)
  859. {
  860. if (m_terrainRenderObject) {
  861. m_terrainRenderObject->removeTreesAndPropsForConstruction(pos, geom, angle);
  862. }
  863. }
  864. // ------------------------------------------------------------------------------------------------
  865. // ------------------------------------------------------------------------------------------------
  866. void W3DTerrainVisual::addProp(const ThingTemplate *tTemplate, const Coord3D *pos, Real angle)
  867. {
  868. ModelConditionFlags state;
  869. state.clear();
  870. if (TheGlobalData->m_weather == WEATHER_SNOWY)
  871. {
  872. state.set(MODELCONDITION_SNOW);
  873. }
  874. if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT)
  875. {
  876. state.set(MODELCONDITION_NIGHT);
  877. }
  878. AsciiString modelName;
  879. Real scale = tTemplate->getAssetScale();
  880. const ModuleInfo& mi = tTemplate->getDrawModuleInfo();
  881. if (mi.getCount() > 0)
  882. {
  883. const ModuleData* mdd = mi.getNthData(0);
  884. const W3DModelDrawModuleData* md = mdd ? mdd->getAsW3DModelDrawModuleData() : NULL;
  885. if (md)
  886. {
  887. modelName = md->getBestModelNameForWB(state);
  888. }
  889. }
  890. if (m_terrainRenderObject && modelName.isNotEmpty()) {
  891. m_terrainRenderObject->addProp(1, *pos, angle, scale, modelName);
  892. }
  893. }
  894. // ------------------------------------------------------------------------------------------------
  895. // ------------------------------------------------------------------------------------------------
  896. void W3DTerrainVisual::setTerrainTracksDetail(void)
  897. {
  898. if (TheTerrainTracksRenderObjClassSystem)
  899. TheTerrainTracksRenderObjClassSystem->setDetail();
  900. }
  901. // ------------------------------------------------------------------------------------------------
  902. // ------------------------------------------------------------------------------------------------
  903. void W3DTerrainVisual::setShoreLineDetail(void)
  904. {
  905. if (m_terrainRenderObject)
  906. m_terrainRenderObject->setShoreLineDetail();
  907. }
  908. // ------------------------------------------------------------------------------------------------
  909. // ------------------------------------------------------------------------------------------------
  910. /// Replace the skybox texture
  911. void W3DTerrainVisual::replaceSkyboxTextures(const AsciiString *oldTexName[5], const AsciiString *newTexName[5])
  912. {
  913. if (m_waterRenderObject)
  914. {
  915. for (Int i=0; i<5; i++)
  916. {
  917. //check if this texture was never changed before and is still using the default art.
  918. if (m_initialSkyboxTexNames[i].isEmpty())
  919. { m_initialSkyboxTexNames[i]=*oldTexName[i];
  920. m_currentSkyboxTexNames[i]=*oldTexName[i];
  921. }
  922. if (m_currentSkyboxTexNames[i] != *newTexName[i])
  923. { m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], *newTexName[i]);
  924. m_currentSkyboxTexNames[i]=*newTexName[i]; //update current state to new texture
  925. }
  926. }
  927. }
  928. }
  929. // ------------------------------------------------------------------------------------------------
  930. /** CRC */
  931. // ------------------------------------------------------------------------------------------------
  932. void W3DTerrainVisual::crc( Xfer *xfer )
  933. {
  934. // extend base class
  935. TerrainVisual::crc( xfer );
  936. } // end CRC
  937. // ------------------------------------------------------------------------------------------------
  938. /** Xfer
  939. * Version Info:
  940. * 1: Initial version
  941. * 2: Add height map heights.
  942. * 3: Add client side trees & props. jba.
  943. */
  944. // ------------------------------------------------------------------------------------------------
  945. void W3DTerrainVisual::xfer( Xfer *xfer )
  946. {
  947. // version
  948. XferVersion currentVersion = 3;
  949. XferVersion version = currentVersion;
  950. xfer->xferVersion( &version, currentVersion );
  951. // extend base class
  952. TerrainVisual::xfer( xfer );
  953. // flag for whether or not the water grid is enabled
  954. Bool gridEnabled = m_isWaterGridRenderingEnabled;
  955. xfer->xferBool( &gridEnabled );
  956. if( gridEnabled != m_isWaterGridRenderingEnabled )
  957. {
  958. DEBUG_CRASH(( "W3DTerrainVisual::xfer - m_isWaterGridRenderingEnabled mismatch\n" ));
  959. throw SC_INVALID_DATA;
  960. } // end if
  961. // xfer grid data if enabled
  962. if( gridEnabled )
  963. xfer->xferSnapshot( m_waterRenderObject );
  964. /*
  965. {
  966. // grid width and height
  967. Int width = getGridWidth();
  968. Int height = getGridheight();
  969. xfer->xferInt( &width );
  970. xfer->xferInt( &height );
  971. if( width != getGridWidth() )
  972. {
  973. DEBUG_CRASH(( "W3DTerainVisual::xfer - grid width mismatch '%d' should be '%d'\n",
  974. width, getGridWidth() ));
  975. throw SC_INVALID_DATA;
  976. } // end if
  977. if( height != getGridHeight() )
  978. {
  979. DEBUG_CRASH(( "W3DTerainVisual::xfer - grid height mismatch '%d' should be '%d'\n",
  980. height, getGridHeight() ));
  981. throw SC_INVALID_DATA;
  982. } // end if
  983. // write data for each grid
  984. } // end if
  985. */
  986. // Write out the terrain height data.
  987. if (version >= 2) {
  988. UnsignedByte *data = m_logicHeightMap->getDataPtr();
  989. Int len = m_logicHeightMap->getXExtent()*m_logicHeightMap->getYExtent();
  990. Int xferLen = len;
  991. xfer->xferInt(&xferLen);
  992. if (len!=xferLen) {
  993. DEBUG_CRASH(("Bad height map length."));
  994. if (len>xferLen) {
  995. len = xferLen;
  996. }
  997. }
  998. xfer->xferUser(data, len);
  999. if (xfer->getXferMode() == XFER_LOAD)
  1000. {
  1001. // Update the display height map.
  1002. m_terrainRenderObject->staticLightingChanged();
  1003. }
  1004. }
  1005. if (version >= 3) {
  1006. xfer->xferSnapshot(m_terrainRenderObject);
  1007. }
  1008. // XFER //
  1009. // X R //
  1010. // X R //
  1011. // XFER //
  1012. ///// /USE CLIENT HEIGHT MAPCLIENT HEIGHT MAP
  1013. // // /USE CLIENT HEIGHT MAPCLIENT HEIGHT MAP
  1014. // ////USE CLIENT HEIGHT MAPCLIENT HEIGHT MAP----------------------------
  1015. // // /USE CLIENT HEIGHT MAPCLIENT HEIGHT MAP ^
  1016. ///// /USE CLIENT HEIGHT MAPCLIENT HEIGHT MAP 0
  1017. // XFER //
  1018. // X R //
  1019. // X R //
  1020. // XFER //
  1021. } // end xfer
  1022. // ------------------------------------------------------------------------------------------------
  1023. /** Load post process */
  1024. // ------------------------------------------------------------------------------------------------
  1025. void W3DTerrainVisual::loadPostProcess( void )
  1026. {
  1027. // extend base class
  1028. TerrainVisual::loadPostProcess();
  1029. } // end loadPostProcess