terrFile.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _TERRFILE_H_
  23. #define _TERRFILE_H_
  24. #ifndef _TVECTOR_H_
  25. #include <core/util/tVector.h>
  26. #endif
  27. #ifndef _PATH_H_
  28. #include <core/util/path.h>
  29. #endif
  30. #ifndef _MATERIALLIST_H_
  31. #include "materials/materialList.h"
  32. #endif
  33. #ifndef _TERRMATERIAL_H_
  34. #include "terrain/terrMaterial.h"
  35. #endif
  36. class TerrainMaterial;
  37. class FileStream;
  38. class GBitmap;
  39. ///
  40. struct TerrainSquare
  41. {
  42. U16 minHeight;
  43. U16 maxHeight;
  44. U16 heightDeviance;
  45. U16 flags;
  46. enum
  47. {
  48. Split45 = BIT(0),
  49. Empty = BIT(1),
  50. HasEmpty = BIT(2),
  51. };
  52. };
  53. /// NOTE: The terrain uses 11.5 fixed point which gives
  54. /// us a height range from 0->2048 in 1/32 increments.
  55. typedef U16 TerrainHeight;
  56. ///
  57. class TerrainFile
  58. {
  59. protected:
  60. friend class TerrainBlock;
  61. /// The materials used to render the terrain.
  62. Vector<TerrainMaterial*> mMaterials;
  63. /// The dimensions of the layer and height maps.
  64. U32 mSize;
  65. /// The layer index at each height map sample.
  66. Vector<U8> mLayerMap;
  67. /// The fixed point height map.
  68. /// @see fixedToFloat
  69. Vector<U16> mHeightMap;
  70. /// The memory pool used by the grid map layers.
  71. Vector<TerrainSquare> mGridMapPool;
  72. ///
  73. U32 mGridLevels;
  74. /// The grid map layers used to accelerate collision
  75. /// queries for the height map data.
  76. Vector<TerrainSquare*> mGridMap;
  77. /// MaterialList used to map terrain materials to material instances for the
  78. /// sake of collision (physics, etc.).
  79. MaterialList mMaterialInstMapping;
  80. /// The file version.
  81. U32 mFileVersion;
  82. /// The dirty flag.
  83. bool mNeedsResaving;
  84. /// The full path and name of the TerrainFile
  85. Torque::Path mFilePath;
  86. /// The internal loading function.
  87. void _load( FileStream &stream );
  88. /// The legacy file loading code.
  89. void _loadLegacy( FileStream &stream );
  90. /// Used to populate the materail vector by finding the
  91. /// TerrainMaterial objects by name.
  92. void _resolveMaterials( const Vector<String> &materials );
  93. ///
  94. void _buildGridMap();
  95. ///
  96. void _initMaterialInstMapping();
  97. public:
  98. enum Constants
  99. {
  100. FILE_VERSION = 7
  101. };
  102. TerrainFile();
  103. virtual ~TerrainFile();
  104. ///
  105. static void create( String *inOutFilename,
  106. U32 newSize,
  107. const Vector<String> &materials );
  108. ///
  109. static TerrainFile* load( const Torque::Path &path );
  110. bool save( const char *filename );
  111. ///
  112. void import( const GBitmap &heightMap,
  113. F32 heightScale,
  114. const Vector<U8> &layerMap,
  115. const Vector<String> &materials,
  116. bool flipYAxis = true );
  117. /// Updates the terrain grid for the specified area.
  118. void updateGrid( const Point2I &minPt, const Point2I &maxPt );
  119. /// Performs multiple smoothing steps on the heightmap.
  120. void smooth( F32 factor, U32 steps, bool updateCollision );
  121. void setSize( U32 newResolution, bool clear );
  122. TerrainSquare* findSquare( U32 level, U32 x, U32 y ) const;
  123. BaseMatInstance* getMaterialMapping( U32 index ) const;
  124. StringTableEntry getMaterialName( U32 x, U32 y) const;
  125. void setLayerIndex( U32 x, U32 y, U8 index );
  126. U8 getLayerIndex( U32 x, U32 y ) const;
  127. bool isEmptyAt( U32 x, U32 y ) const { return getLayerIndex( x, y ) == U8_MAX; }
  128. void setHeight( U32 x, U32 y, U16 height );
  129. const U16* getHeightAddress( U32 x, U32 y ) const;
  130. U16 getHeight( U32 x, U32 y ) const;
  131. U16 getMaxHeight() const { return mGridMap[mGridLevels]->maxHeight; }
  132. /// Returns the constant heightmap vector.
  133. const Vector<U16>& getHeightMap() const { return mHeightMap; }
  134. /// Sets a new heightmap state.
  135. void setHeightMap( const Vector<U16> &heightmap, bool updateCollision );
  136. /// Check if the given point is valid within the (non-tiled) terrain file.
  137. bool isPointInTerrain( U32 x, U32 y ) const;
  138. };
  139. inline TerrainSquare* TerrainFile::findSquare( U32 level, U32 x, U32 y ) const
  140. {
  141. x %= mSize;
  142. y %= mSize;
  143. x >>= level;
  144. y >>= level;
  145. return mGridMap[level] + x + ( y << ( mGridLevels - level ) );
  146. }
  147. inline void TerrainFile::setHeight( U32 x, U32 y, U16 height )
  148. {
  149. x %= mSize;
  150. y %= mSize;
  151. mHeightMap[ x + ( y * mSize ) ] = height;
  152. }
  153. inline const U16* TerrainFile::getHeightAddress( U32 x, U32 y ) const
  154. {
  155. x %= mSize;
  156. y %= mSize;
  157. return &mHeightMap[ x + ( y * mSize ) ];
  158. }
  159. inline U16 TerrainFile::getHeight( U32 x, U32 y ) const
  160. {
  161. x %= mSize;
  162. y %= mSize;
  163. return mHeightMap[ x + ( y * mSize ) ];
  164. }
  165. inline U8 TerrainFile::getLayerIndex( U32 x, U32 y ) const
  166. {
  167. x %= mSize;
  168. y %= mSize;
  169. return mLayerMap[ x + ( y * mSize ) ];
  170. }
  171. inline void TerrainFile::setLayerIndex( U32 x, U32 y, U8 index )
  172. {
  173. x %= mSize;
  174. y %= mSize;
  175. mLayerMap[ x + ( y * mSize ) ] = index;
  176. }
  177. inline BaseMatInstance* TerrainFile::getMaterialMapping( U32 index ) const
  178. {
  179. if ( index < mMaterialInstMapping.size() )
  180. return mMaterialInstMapping.getMaterialInst( index );
  181. else
  182. return NULL;
  183. }
  184. inline StringTableEntry TerrainFile::getMaterialName( U32 x, U32 y) const
  185. {
  186. x %= mSize;
  187. y %= mSize;
  188. const U8 &index = mLayerMap[ x + ( y * mSize ) ];
  189. if ( index < mMaterials.size() )
  190. return mMaterials[ index ]->getInternalName();
  191. return StringTable->EmptyString();
  192. }
  193. /// Conversion from 11.5 fixed point to floating point.
  194. inline F32 fixedToFloat( U16 val )
  195. {
  196. return F32(val) * 0.03125f;
  197. }
  198. /// Conversion from floating point to 11.5 fixed point.
  199. inline U16 floatToFixed( F32 val )
  200. {
  201. return U16(val * 32.0 + 0.5f);
  202. }
  203. inline bool TerrainFile::isPointInTerrain( U32 x, U32 y ) const
  204. {
  205. if ( x < mSize && y < mSize)
  206. return true;
  207. return false;
  208. }
  209. #endif // _TERRFILE_H_