Terrain.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. //---------------------------------------------------------------------------
  2. //
  3. // Terrain.h -- File contains class definitions for the terrain class.
  4. //
  5. // MechCommander 2
  6. //
  7. //---------------------------------------------------------------------------//
  8. // Copyright (C) Microsoft Corporation. All rights reserved. //
  9. //===========================================================================//
  10. #ifndef TERRAIN_H
  11. #define TERRAIN_H
  12. //---------------------------------------------------------------------------
  13. // Include Files
  14. #ifndef MAPDATA_H
  15. #include "mapdata.h"
  16. #endif
  17. #ifndef TERRTXM_H
  18. #include "terrtxm.h"
  19. #endif
  20. #ifndef TERRTXM2_H
  21. #include "terrtxm2.h"
  22. #endif
  23. #ifndef BITLAG_H
  24. #include "bitflag.h"
  25. #endif
  26. #ifndef INIFILE_H
  27. #include "inifile.h"
  28. #endif
  29. #ifndef MATHFUNC_H
  30. #include "mathfunc.h"
  31. #endif
  32. #ifndef DQUAD_H
  33. #include "dquad.h"
  34. #endif
  35. #ifndef DVERTEX_H
  36. #include "dvertex.h"
  37. #endif
  38. #ifndef CLOUDS_H
  39. #include "clouds.h"
  40. #endif
  41. //---------------------------------------------------------------------------
  42. // Macro Definitions
  43. #ifndef NO_ERR
  44. #define NO_ERR 0
  45. #endif
  46. #define MAPCELL_DIM 3
  47. #define MAX_MAP_CELL_WIDTH 720
  48. #define TACMAP_SIZE 128.f
  49. //------------------------------------------------
  50. // Put back in Move code when Glenn moves it over.
  51. // 07/28/99 these numbers didn't correspond to clan/IS despite comment, so I chagned 'em.
  52. // These MUST be these numbers or the game will not mark LOS correctly!
  53. #define NOTEAM -1
  54. //#define TEAM1 0 //this is PLAYER TEAM -- Single Player
  55. #define TEAM2 1 //this is OPFOR TEAM -- Single Player
  56. #define TEAM3 2 // this is allies
  57. #define TEAM4 3
  58. #define TEAM5 4
  59. #define TEAM6 5
  60. #define TEAM7 6
  61. #define TEAM8 7
  62. //-------------------------------------------
  63. // 08/01/99 -- Must have generic alignments or Heidi goes WAY south!
  64. #define EDITOR_TEAMNONE -1 //Allied
  65. #define EDITOR_TEAM1 0 //Player
  66. #define EDITOR_TEAM2 1 //Enemy
  67. #define EDITOR_TEAM3 2
  68. #define EDITOR_TEAM4 3
  69. #define EDITOR_TEAM5 4
  70. #define EDITOR_TEAM6 5
  71. #define EDITOR_TEAM7 6
  72. #define EDITOR_TEAM8 7
  73. //---------------------------------------------------------------------------
  74. // Used by the object system to load the objects on the terrain.
  75. typedef struct _ObjBlockInfo
  76. {
  77. bool active;
  78. long numCollidableObjects;
  79. long numObjects; // includes collidable objects
  80. long firstHandle; // collidables, followed by non
  81. } ObjBlockInfo;
  82. //---------------------------------------------------------------------------
  83. //Everything goes through here now.
  84. // This will understand the original MC2 format and new format and will convert between
  85. class Terrain
  86. {
  87. //Data Members
  88. //-------------
  89. protected:
  90. unsigned long terrainHeapSize;
  91. long numberVertices;
  92. long numberQuads;
  93. VertexPtr vertexList;
  94. TerrainQuadPtr quadList;
  95. public:
  96. //For editor
  97. static long userMin;
  98. static long userMax;
  99. static unsigned long baseTerrain;
  100. static unsigned char fractalThreshold;
  101. static unsigned char fractalNoise;
  102. static long halfVerticesMapSide; //Half of the below value.
  103. static long realVerticesMapSide; //Number of vertices on each side of map.
  104. static const long verticesBlockSide; //Always 20.
  105. static long blocksMapSide; //Calced from above and
  106. static float worldUnitsMapSide; //Total world units map is across.
  107. static float oneOverWorldUnitsMapSide; //Inverse of the above.
  108. static long visibleVerticesPerSide; //How many should I process to be sure I got all I could see.
  109. static const float worldUnitsPerVertex; //How many world Units between each vertex. 128.0f in current universe.
  110. static const float worldUnitsPerCell; //How many world units between cells. 42.66666667f ALWAYS!!!!
  111. static const float halfWorldUnitsPerCell; //Above divided by two.
  112. static const float metersPerCell; //Number of meters per cell. 8.53333333f ALWAYS!!
  113. static const float oneOverWorldUnitsPerVertex; //Above numbers inverse.
  114. static const float oneOverWorldUnitsPerCell;
  115. static const float oneOverMetersPerCell;
  116. static const float oneOverVerticesBlockSide;
  117. static const float worldUnitsBlockSide; //Total world units each block of 20 vertices is. 2560.0f in current universe.
  118. static Stuff::Vector3D mapTopLeft3d; //Where does the terrain start.
  119. static MapDataPtr mapData; //Pointer to class that manages terrain mesh data.
  120. static TerrainTexturesPtr terrainTextures; //Pointer to class that manages terrain textures.
  121. static TerrainColorMapPtr terrainTextures2; //Pointer to class that manages the NEW color map terrain texture.
  122. static UserHeapPtr terrainHeap; //Heap used for terrain.
  123. // static ByteFlag *VisibleBits; //What can currently be seen
  124. static char *terrainName; //Name of terrain data file.
  125. static char *colorMapName; //Name of colormap, if different from terrainName.
  126. static float oneOverWorldUnitsPerElevationLevel;
  127. static float waterElevation; //Actual height of water in world units.
  128. static float frameAngle; //Used to animate the waves
  129. static float frameCos;
  130. static float frameCosAlpha;
  131. static DWORD alphaMiddle; //Used to alpha the water into the shore.
  132. static DWORD alphaEdge;
  133. static DWORD alphaDeep;
  134. static float waterFreq; //Used to animate waves.
  135. static float waterAmplitude;
  136. static long numObjBlocks; //Stores terrain object info.
  137. static ObjBlockInfo *objBlockInfo; //Dynamically allocate this please!!
  138. static bool *objVertexActive; //Stores whether or not this vertices objects need to be updated
  139. static float *tileRowToWorldCoord; //Arrays used to help change from tile and cell to actual world position.
  140. static float *tileColToWorldCoord; //TILE functions will be obsolete with new system.
  141. static float *cellToWorldCoord;
  142. static float *cellColToWorldCoord;
  143. static float *cellRowToWorldCoord;
  144. static bool recalcShadows; //Should we recalc the shadow map!
  145. static bool recalcLight; //Should we recalc the light data.
  146. static Clouds *cloudLayer;
  147. //Member Functions
  148. //-----------------
  149. public:
  150. void init (void);
  151. Terrain (void)
  152. {
  153. init();
  154. }
  155. void destroy (void);
  156. ~Terrain (void)
  157. {
  158. destroy();
  159. }
  160. long init (PacketFile* file, int whichPacket, unsigned long visibleVertices,
  161. volatile float& progress, float progressRange); // open an existing file
  162. long init( unsigned long verticesPerMapSide, PacketFile* file, unsigned long visibleVertices,
  163. volatile float& percent,
  164. float percentRange); // pass in null for a blank new map
  165. float getTerrainElevation (Stuff::Vector3D &position);
  166. short getTerrainType (Stuff::Vector3D &position);
  167. float getTerrainAngle (Stuff::Vector3D &position, Stuff::Vector3D* normal = NULL);
  168. Stuff::Vector3D getTerrainNormal (Stuff::Vector3D &position);
  169. float getTerrainLight (Stuff::Vector3D& position);
  170. bool isVisible (Stuff::Vector3D &looker, Stuff::Vector3D &looked_at);
  171. float getWaterElevation ()
  172. {
  173. return mapData->waterElevation();
  174. }
  175. void markSeen (Stuff::Vector3D &looker, byte who, float specialUnitExpand);
  176. void markRadiusSeen (Stuff::Vector3D &looker, float dist, byte who);
  177. long update (void);
  178. void render (void);
  179. void renderWater (void);
  180. void geometry (void);
  181. void drawTopView (void);
  182. static bool IsValidTerrainPosition (Stuff::Vector3D pos);
  183. static bool IsEditorSelectTerrainPosition (Stuff::Vector3D pos);
  184. static bool IsGameSelectTerrainPosition (Stuff::Vector3D pos);
  185. long save( PacketFile* fileName, int whichPacket, bool QuickSave = false);
  186. bool save( FitIniFile* fitFile ); // save stuff like water info
  187. bool load( FitIniFile* fitFile );
  188. // old overlay stuff
  189. void setOverlayTile (long block, long vertex, long offset);
  190. long getOverlayTile (long block, long vertex);
  191. // new overlay stuff
  192. void setOverlay( long tileR, long tileC, Overlays type, unsigned long Offset );
  193. void getOverlay( long tileR, long tileC, Overlays& type, unsigned long& Offset );
  194. void setTerrain( long tileR, long tileC, int terrainType );
  195. int getTerrain( long tileR, long tileC );
  196. unsigned long getTexture( long tileR, long tileC );
  197. float getTerrainElevation( long tileR, long tileC );
  198. void setVertexHeight( int vertexIndex, float value );
  199. float getVertexHeight( int vertexIndex );
  200. void calcWater (float waterDepth, float waterShallowDepth, float waterAlphaDepth);
  201. void updateAllObjects (void);
  202. void setObjBlockActive (long blockNum, bool active);
  203. void clearObjBlocksActive (void);
  204. inline void worldToTile( const Stuff::Vector3D& pos, long& tileR, long& tileC );
  205. inline void worldToCell( const Stuff::Vector3D& pos, long& cellR, long& cellC );
  206. inline void worldToTileCell (const Stuff::Vector3D& pos, long& tileR, long& tileC, long& cellR, long& cellC);
  207. inline void tileCellToWorld (long tileR, long tileC, long cellR, long cellC, Stuff::Vector3D& worldPos);
  208. inline void cellToWorld (long cellR, long cellC, Stuff::Vector3D& worldPos);
  209. inline void getCellPos( long cellR, long cellC, Stuff::Vector3D& cellPos );
  210. void initMapCellArrays(void);
  211. void unselectAll();
  212. void selectVerticesInRect( const Stuff::Vector4D& topLeft, const Stuff::Vector4D& bottomRight, bool bToggle );
  213. bool hasSelection();
  214. bool isVertexSelected( long tileR, long tileC );
  215. bool selectVertex( long tileR, long tileC, bool bSelect = true );
  216. float getHighestVertex( long& tileR, long& tileC );
  217. float getLowestVertex( long& tileR, long& tileC );
  218. static void setUserSettings( long min, long max, int terrainType );
  219. static void getUserSettings( long& min, long& max, int& terrainType );
  220. void recalcWater();
  221. void reCalcLight(bool doShadows = false);
  222. void clearShadows();
  223. long getWater (Stuff::Vector3D& worldPos);
  224. float getClipRange()
  225. {
  226. return 0.5 * worldUnitsPerVertex * (float)(visibleVerticesPerSide);
  227. }
  228. void setClipRange(float clipRange)
  229. {
  230. visibleVerticesPerSide = 2.0 * clipRange / worldUnitsPerVertex;
  231. }
  232. void purgeTransitions (void);
  233. TerrainQuadPtr getQuadList (void)
  234. {
  235. return(quadList);
  236. }
  237. VertexPtr getVertexList (void)
  238. {
  239. return(vertexList);
  240. }
  241. long getNumVertices (void)
  242. {
  243. return(numberVertices);
  244. }
  245. long getNumQuads (void)
  246. {
  247. return(numberQuads);
  248. }
  249. void setObjVertexActive (long vertexNum, bool active);
  250. void clearObjVerticesActive (void);
  251. void resetVisibleVertices(long maxVisibleVertices);
  252. void getColorMapName (FitIniFile *file);
  253. void setColorMapName (char *mapName);
  254. void saveColorMapName (FitIniFile *file);
  255. };
  256. typedef Terrain *TerrainPtr;
  257. extern TerrainPtr land;
  258. //---------------------------------------------------------------------------
  259. inline void Terrain::worldToTile( const Stuff::Vector3D& pos, long& tileR, long& tileC )
  260. {
  261. float tmpX = pos.x - land->mapTopLeft3d.x;
  262. float tmpY = land->mapTopLeft3d.y - pos.y;
  263. tileC = float2long(tmpX * oneOverWorldUnitsPerVertex);
  264. tileR = float2long(tmpY * oneOverWorldUnitsPerVertex);
  265. }
  266. //---------------------------------------------------------------------------
  267. inline void Terrain::worldToCell( const Stuff::Vector3D& pos, long& cellR, long& cellC )
  268. {
  269. cellC = float2long(( pos.x - land->mapTopLeft3d.x ) * (oneOverWorldUnitsPerVertex*3.0f));
  270. cellR = float2long(( land->mapTopLeft3d.y - pos.y ) * (oneOverWorldUnitsPerVertex*3.0f));
  271. }
  272. //---------------------------------------------------------------------------
  273. inline void Terrain::worldToTileCell( const Stuff::Vector3D& pos, long& tileR, long& tileC, long& cellR, long& cellC )
  274. {
  275. float tmpX = pos.x - land->mapTopLeft3d.x;
  276. float tmpY = land->mapTopLeft3d.y - pos.y;
  277. tileC = tmpX * oneOverWorldUnitsPerVertex;
  278. tileR = tmpY * oneOverWorldUnitsPerVertex;
  279. if ((tileC < 0) ||
  280. (tileR < 0) ||
  281. (tileC >= Terrain::realVerticesMapSide) ||
  282. (tileR >= Terrain::realVerticesMapSide))
  283. {
  284. #ifdef _DEBUG
  285. PAUSE(("called worldToTileCell with POS out of bounds? Result TC:%d TR:%d",tileC,tileR));
  286. #endif
  287. tileC = tileR = 0;
  288. }
  289. cellC = (pos.x - tileColToWorldCoord[tileC]) * oneOverWorldUnitsPerCell;
  290. cellR = (tileRowToWorldCoord[tileR] - pos.y) * oneOverWorldUnitsPerCell;
  291. }
  292. //---------------------------------------------------------------------------
  293. inline void Terrain::tileCellToWorld (long tileR, long tileC, long cellR, long cellC, Stuff::Vector3D& worldPos)
  294. {
  295. if ((tileC < 0) ||
  296. (tileR < 0) ||
  297. (tileC >= Terrain::realVerticesMapSide) ||
  298. (tileR >= Terrain::realVerticesMapSide) ||
  299. (cellC < 0) ||
  300. (cellR < 0) ||
  301. (cellC >= MAPCELL_DIM) ||
  302. (cellR >= MAPCELL_DIM))
  303. {
  304. #ifdef _DEBUG
  305. PAUSE(("called cellToWorld with tile or cell out of bounds. TC:%d TR:%d CR:%d CC:%d",tileC,tileR,cellR,cellC));
  306. #endif
  307. tileR = tileC = cellR = cellC = 0;
  308. }
  309. else
  310. {
  311. worldPos.x = tileColToWorldCoord[tileC] + cellToWorldCoord[cellC] + halfWorldUnitsPerCell;
  312. worldPos.y = tileRowToWorldCoord[tileR] - cellToWorldCoord[cellR] - halfWorldUnitsPerCell;
  313. worldPos.z = (float)0.0;
  314. }
  315. }
  316. //---------------------------------------------------------------------------
  317. inline void Terrain::cellToWorld (long cellR, long cellC, Stuff::Vector3D& worldPos)
  318. {
  319. if ((cellR < 0) ||
  320. (cellC < 0) ||
  321. (cellR >= (Terrain::realVerticesMapSide * MAPCELL_DIM)) ||
  322. (cellC >= (Terrain::realVerticesMapSide * MAPCELL_DIM)))
  323. {
  324. #ifdef _DEBUG
  325. PAUSE(("called cellToWorld with cell out of bounds. CellR:%d CellC:%d",cellR,cellC));
  326. #endif
  327. worldPos.x = worldPos.y = worldPos.z = 0.0f;
  328. }
  329. else
  330. {
  331. worldPos.x = cellColToWorldCoord[cellC] + halfWorldUnitsPerCell;
  332. worldPos.y = cellRowToWorldCoord[cellR] - halfWorldUnitsPerCell;
  333. worldPos.z = (float)0.0;
  334. }
  335. }
  336. //---------------------------------------------------------------------------
  337. inline void Terrain::getCellPos( long cellR, long cellC, Stuff::Vector3D& cellPos )
  338. {
  339. cellPos.x = (cellC * (worldUnitsPerVertex/3.)) + (worldUnitsPerVertex/6.);
  340. cellPos.y = (cellR * (worldUnitsPerVertex/3.)) + (worldUnitsPerVertex/6.);
  341. cellPos.x += land->mapTopLeft3d.x;
  342. cellPos.y = land->mapTopLeft3d.y - cellPos.y;
  343. cellPos.z = land->getTerrainElevation( cellPos );
  344. }
  345. //---------------------------------------------------------------------------
  346. #endif
  347. //---------------------------------------------------------------------------
  348. //
  349. // Edit Log
  350. //
  351. //---------------------------------------------------------------------------