renegadeterrainpatch.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. ** Command & Conquer Renegade(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : wwphys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/renegadeterrainpatch.h $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 3/12/02 2:34p $*
  29. * *
  30. * $Revision:: 5 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef __RENEGADETERRAINPATCH_H
  39. #define __RENEGADETERRAINPATCH_H
  40. #include "rendobj.h"
  41. #include "vector.h"
  42. #include "shader.h"
  43. #include "coltest.h"
  44. #include "castres.h"
  45. #include "tri.h"
  46. #include "renegadeterrainmaterialpass.h"
  47. #include "terrainmaterial.h"
  48. //////////////////////////////////////////////////////////////////////
  49. // Forward declarations
  50. //////////////////////////////////////////////////////////////////////
  51. class VertexMaterialClass;
  52. class MaterialPassClass;
  53. //////////////////////////////////////////////////////////////////////
  54. //
  55. // RenegadeTerrainPatchClass
  56. //
  57. //////////////////////////////////////////////////////////////////////
  58. class RenegadeTerrainPatchClass : public RenderObjClass
  59. {
  60. public:
  61. ///////////////////////////////////////////////////////////////////
  62. // Public constructors/destructors
  63. ///////////////////////////////////////////////////////////////////
  64. RenegadeTerrainPatchClass (void);
  65. RenegadeTerrainPatchClass (const RenegadeTerrainPatchClass &src);
  66. virtual ~RenegadeTerrainPatchClass (void);
  67. ///////////////////////////////////////////////////////////////////
  68. // Public operators
  69. ///////////////////////////////////////////////////////////////////
  70. const RenegadeTerrainPatchClass & operator= (const RenegadeTerrainPatchClass &src);
  71. ///////////////////////////////////////////////////////////////////
  72. // Public methods
  73. ///////////////////////////////////////////////////////////////////
  74. //
  75. // Creation
  76. //
  77. void Allocate (int points_x, int points_y, float meters_per_point);
  78. //
  79. // Vertex access
  80. //
  81. void Set_Vertex_Pos (int x, int y, const Vector3 &pos);
  82. void Set_Vertex_Normal (int x, int y, const Vector3 &normal) { GridNormals[Grid_Index (x, y)] = normal; AreBuffersDirty = true; }
  83. //
  84. // Quad access
  85. //
  86. void Set_Quad_Flags (int quad_index, uint8 flags) { QuadFlags[quad_index] = flags; }
  87. //
  88. // UV access
  89. //
  90. void Update_UVs (void);
  91. void Update_Vertex_Render_Lists (void);
  92. //
  93. // Informational
  94. //
  95. void Set_Bounding_Box_Min (const Vector3 &box_min) { BoundingBoxMin = box_min; }
  96. void Set_Bounding_Box_Max (const Vector3 &box_max) { BoundingBoxMax = box_max; }
  97. //
  98. // Save/load support
  99. //
  100. bool Save (ChunkSaveClass &csave);
  101. bool Load (ChunkLoadClass &cload);
  102. void Load_Variables (ChunkLoadClass &cload);
  103. void Load_Materials (ChunkLoadClass &cload);
  104. const PersistFactoryClass & Get_Factory (void) const;
  105. //
  106. // Inherited
  107. //
  108. RenderObjClass * Clone (void) const { return new RenegadeTerrainPatchClass (*this); }
  109. int Class_ID (void) const { return CLASSID_RENEGADE_TERRAIN; }
  110. void Render (RenderInfoClass &rinfo);
  111. void Get_Obj_Space_Bounding_Sphere (SphereClass &sphere) const;
  112. void Get_Obj_Space_Bounding_Box (AABoxClass &box) const;
  113. //
  114. // Inherited collision detection
  115. //
  116. bool Cast_Ray (RayCollisionTestClass &raytest);
  117. bool Cast_AABox (AABoxCollisionTestClass &boxtest);
  118. bool Cast_OBBox (OBBoxCollisionTestClass &boxtest);
  119. bool Intersect_AABox (AABoxIntersectionTestClass &boxtest);
  120. bool Intersect_OBBox (OBBoxIntersectionTestClass &boxtest);
  121. //
  122. // Material access
  123. //
  124. int Add_Material (TerrainMaterialClass *material);
  125. void Reset_Material_Passes (void);
  126. RenegadeTerrainMaterialPassClass * Get_Material_Pass (int index, TerrainMaterialClass *material);
  127. int Get_Material_Count (void) { return MaterialPassList.Count (); }
  128. RenegadeTerrainMaterialPassClass * Peek_Material_Pass (int index) { return MaterialPassList[index]; }
  129. //
  130. // Access to internal mesh data
  131. //
  132. int Get_Vertex_Count (void) const { return GridPointCount; }
  133. Vector3 * Get_Vertex_Array (void) const { return Grid; }
  134. Vector3 * Get_Vertex_Normal_Array (void) const { return GridNormals; }
  135. //
  136. // Lighting support
  137. //
  138. bool Is_Prelit (void) const { return IsPreLit; }
  139. void Set_Is_Prelit (bool onoff) { IsPreLit = onoff; }
  140. void Set_Vertex_Color (int index, const Vector3 &color) { VertexColors[index] = color; AreBuffersDirty = true; }
  141. const Vector3 & Get_Vertex_Color (int index) { return VertexColors[index]; }
  142. protected:
  143. ///////////////////////////////////////////////////////////////////
  144. // Protected methods
  145. ///////////////////////////////////////////////////////////////////
  146. //
  147. // Index utility functions
  148. //
  149. int Grid_Index (int x, int y) { return (y * GridPointsX) + x; }
  150. int Get_Quad_Index_X (float x_pos, bool clamp = true);
  151. int Get_Quad_Index_Y (float y_pos, bool clamp = true);
  152. float Get_Grid_Line_Pos_X (int grid_line_index);
  153. float Get_Grid_Line_Pos_Y (int grid_line_index);
  154. bool Is_Valid_Quad (int x, int y);
  155. //
  156. // Matrix utility functions
  157. //
  158. void Get_Inverse_Transform (Matrix3D &tm);
  159. //
  160. // Misc initialization and cleanup routines
  161. //
  162. void Free_Grid (void);
  163. void Free_Materials (void);
  164. void Initialize_Material (void);
  165. void Initialize (void);
  166. void Allocate_Grid (void);
  167. //
  168. // Rendering
  169. //
  170. void Render_By_Texture (int texture_index, int pass_type);
  171. void Submit_Rendering_Buffers (int texture_index, int pass_type);
  172. void Update_Rendering_Buffers (void);
  173. void Free_Rendering_Buffers (void);
  174. void Build_Rendering_Buffers (int texture_index, int pass_type);
  175. void Render_Procedural_Material_Pass(MaterialPassClass * matpass);
  176. //
  177. // Ray casting
  178. //
  179. bool Cast_Vertical_Ray (RayCollisionTestClass &raytest);
  180. bool Cast_Non_Vertical_Ray (RayCollisionTestClass &raytest);
  181. bool Brute_Force_Cast_Ray (RayCollisionTestClass &raytest);
  182. bool Collide_Quad (const LineSegClass &line_seg, int cell_x, int cell_y, CastResultStruct &result);
  183. ///////////////////////////////////////////////////////////////////
  184. // Protected data types
  185. ///////////////////////////////////////////////////////////////////
  186. enum
  187. {
  188. QF_NORMAL = 0,
  189. QF_HIDDEN = 1,
  190. } QUAD_FLAGS;
  191. ///////////////////////////////////////////////////////////////////
  192. // Protected member data
  193. ///////////////////////////////////////////////////////////////////
  194. Vector3 * Grid;
  195. Vector3 * GridNormals;
  196. Vector3 * VertexColors;
  197. uint8 * QuadFlags;
  198. int GridPointsX;
  199. int GridPointsY;
  200. int GridPointCount;
  201. float Density;
  202. VertexMaterialClass * BaseMaterial;
  203. ShaderClass BaseShader;
  204. VertexMaterialClass * LayerMaterial;
  205. ShaderClass LayerShader;
  206. Vector3 BoundingBoxMin;
  207. Vector3 BoundingBoxMax;
  208. bool AreBuffersDirty;
  209. bool IsPreLit;
  210. DynamicVectorClass<RenegadeTerrainMaterialPassClass *> MaterialPassList;
  211. };
  212. //////////////////////////////////////////////////////////////////////
  213. // Collide_Quad
  214. //////////////////////////////////////////////////////////////////////
  215. WWINLINE bool
  216. RenegadeTerrainPatchClass::Collide_Quad
  217. (
  218. const LineSegClass & line_seg,
  219. int cell_x,
  220. int cell_y,
  221. CastResultStruct & result
  222. )
  223. {
  224. bool retval = false;
  225. //
  226. // Calculate the four indices into the grid that define the four
  227. // corners of the quad we're testing.
  228. //
  229. int start_index = Grid_Index (cell_x, cell_y);
  230. int v0_index = start_index;
  231. int v1_index = start_index + 1;
  232. int v2_index = start_index + GridPointsX + 1;
  233. int v3_index = start_index + GridPointsX;
  234. float min_pz = WWMath::Min (line_seg.Get_P0 ().Z, line_seg.Get_P1 ().Z);
  235. float max_pz = WWMath::Max (line_seg.Get_P0 ().Z, line_seg.Get_P1 ().Z);
  236. if ( Grid[v0_index].Z < min_pz &&
  237. Grid[v1_index].Z < min_pz &&
  238. Grid[v2_index].Z < min_pz &&
  239. Grid[v3_index].Z < min_pz)
  240. {
  241. return false;
  242. }
  243. if ( Grid[v0_index].Z > max_pz &&
  244. Grid[v1_index].Z > max_pz &&
  245. Grid[v2_index].Z > max_pz &&
  246. Grid[v3_index].Z > max_pz)
  247. {
  248. return false;
  249. }
  250. //
  251. // Compose the two triangles for the collision check
  252. //
  253. TriClass tri1;
  254. TriClass tri2;
  255. Vector3 norm1 (0, 0, 0);
  256. Vector3 norm2 (0, 0, 0);
  257. tri1.N = &norm1;
  258. tri2.N = &norm2;
  259. tri1.V[0] = &Grid[v0_index];
  260. tri1.V[1] = &Grid[v2_index];
  261. tri1.V[2] = &Grid[v3_index];
  262. tri2.V[0] = &Grid[v2_index];
  263. tri2.V[1] = &Grid[v0_index];
  264. tri2.V[2] = &Grid[v1_index];
  265. tri1.Compute_Normal ();
  266. tri2.Compute_Normal ();
  267. //
  268. // Test the two polygons that form this quad to see if the ray hit
  269. //
  270. retval = CollisionMath::Collide (line_seg, tri1, &result);
  271. retval |= CollisionMath::Collide (line_seg, tri2, &result);
  272. //
  273. // Determine which surface type was hit
  274. //
  275. if (retval && MaterialPassList.Count () > 0) {
  276. int best_pass = 0;
  277. float best_alpha = 0;
  278. for (int index = 0; index < MaterialPassList.Count (); index ++) {
  279. float alpha = MaterialPassList[index]->VertexAlpha[v0_index];
  280. if (alpha > best_alpha && alpha != 1.0F) {
  281. best_alpha = alpha;
  282. best_pass = index;
  283. }
  284. }
  285. if (MaterialPassList[best_pass]->Material != NULL) {
  286. result.SurfaceType = MaterialPassList[best_pass]->Material->Get_Surface_Type ();
  287. }
  288. }
  289. return retval;
  290. }
  291. //////////////////////////////////////////////////////////////////////
  292. // Set_Vertex_Pos
  293. //////////////////////////////////////////////////////////////////////
  294. WWINLINE void
  295. RenegadeTerrainPatchClass::Set_Vertex_Pos (int x, int y, const Vector3 &pos)
  296. {
  297. //
  298. // Update the vertex position
  299. //
  300. Grid[Grid_Index (x, y)] = pos;
  301. //
  302. // Do we need to update the bounding volume of the patch?
  303. //
  304. if (pos.Z > BoundingBoxMax.Z) {
  305. BoundingBoxMax.Z = pos.Z;
  306. }
  307. if (pos.Z < BoundingBoxMin.Z) {
  308. BoundingBoxMin.Z = pos.Z;
  309. }
  310. Invalidate_Cached_Bounding_Volumes ();
  311. AreBuffersDirty = true;
  312. return ;
  313. }
  314. //////////////////////////////////////////////////////////////////////
  315. // Get_Quad_Index_X
  316. //////////////////////////////////////////////////////////////////////
  317. WWINLINE int
  318. RenegadeTerrainPatchClass::Get_Quad_Index_X (float x_pos, bool clamp)
  319. {
  320. int quad_x = WWMath::Float_To_Int_Floor ((x_pos - BoundingBoxMin.X) / Density);
  321. //
  322. // Clamp the index to the range of existing quad cells
  323. //
  324. if (clamp) {
  325. quad_x = WWMath::Clamp_Int (quad_x, 0, GridPointsX - 2);
  326. }
  327. return quad_x;
  328. }
  329. //////////////////////////////////////////////////////////////////////
  330. // Get_Quad_Index_Y
  331. //////////////////////////////////////////////////////////////////////
  332. WWINLINE int
  333. RenegadeTerrainPatchClass::Get_Quad_Index_Y (float y_pos, bool clamp)
  334. {
  335. int quad_y = WWMath::Float_To_Int_Floor ((y_pos - BoundingBoxMin.Y) / Density);
  336. //
  337. // Clamp the index to the range of existing quad cells
  338. //
  339. if (clamp) {
  340. quad_y = WWMath::Clamp_Int (quad_y, 0, GridPointsY - 2);
  341. }
  342. return quad_y;
  343. }
  344. //////////////////////////////////////////////////////////////////////
  345. // Get_Grid_Line_Pos_X
  346. //////////////////////////////////////////////////////////////////////
  347. WWINLINE float
  348. RenegadeTerrainPatchClass::Get_Grid_Line_Pos_X (int grid_line_index)
  349. {
  350. return BoundingBoxMin.X + (grid_line_index * Density);
  351. }
  352. //////////////////////////////////////////////////////////////////////
  353. // Get_Grid_Line_Pos_Y
  354. //////////////////////////////////////////////////////////////////////
  355. WWINLINE float
  356. RenegadeTerrainPatchClass::Get_Grid_Line_Pos_Y (int grid_line_index)
  357. {
  358. return BoundingBoxMin.Y + (grid_line_index * Density);
  359. }
  360. //////////////////////////////////////////////////////////////////////
  361. // Get_Inverse_Transform
  362. //////////////////////////////////////////////////////////////////////
  363. WWINLINE void
  364. RenegadeTerrainPatchClass::Get_Inverse_Transform (Matrix3D &tm)
  365. {
  366. Get_Transform ().Get_Orthogonal_Inverse (tm);
  367. return ;
  368. }
  369. //////////////////////////////////////////////////////////////////////
  370. // Is_Valid_Quad
  371. //////////////////////////////////////////////////////////////////////
  372. WWINLINE bool
  373. RenegadeTerrainPatchClass::Is_Valid_Quad (int x, int y)
  374. {
  375. bool retval = false;
  376. //
  377. // Simply check to see if the coordinates are inside the patch
  378. //
  379. if ( x >= 0 && x < (GridPointsX - 1) &&
  380. y >= 0 && y < (GridPointsY - 1))
  381. {
  382. retval = true;
  383. }
  384. return retval;
  385. }
  386. #endif //__RENEGADETERRAINPATCH_H