meshgeometry.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 : WW3D *
  23. * *
  24. * $Archive:: /VSS_Sync/ww3d2/meshgeometry.h $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Vss_sync $*
  29. * *
  30. * $Modtime:: 8/29/01 7:29p $*
  31. * *
  32. * $Revision:: 10 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #ifndef MESHGEOMETRY_H
  38. #define MESHGEOMETRY_H
  39. #include "always.h"
  40. #include "refcount.h"
  41. #include "bittype.h"
  42. #include "simplevec.h"
  43. #include "sharebuf.h"
  44. #include "w3derr.h"
  45. #include "vector3.h"
  46. #include "vector3i.h"
  47. #include "vector4.h"
  48. #include "wwdebug.h"
  49. #include "multilist.h"
  50. #include "coltest.h"
  51. #include "inttest.h"
  52. class AABoxClass;
  53. class OBBoxClass;
  54. class SphereClass;
  55. class ChunkLoadClass;
  56. class AABTreeClass;
  57. /*
  58. ** The following two defines control two space-saving optimizations. In Renegade I've found
  59. ** that the plane equations are about 8% of the geometry space and vertex normals are about 10%
  60. ** so I'm trying to see if we can get by without them. The plane equations are mainly used
  61. ** by collision detection functions and those are culled pretty well. Anyway, collision is
  62. ** already so expensive that adding a cross product to it doesn't seem to matter.
  63. **
  64. ** NOTE: currently with optimizations enabled, memory gets trashed if you use OPTIMIZE_VNORM_RAM
  65. ** I suspect this is due to the way Dynamesh uses (abuses) MeshGeometryClass and haven't had
  66. ** time to track it down yet.
  67. */
  68. #define OPTIMIZE_PLANEEQ_RAM 1
  69. #define OPTIMIZE_VNORM_RAM 0
  70. /**
  71. ** MeshGeometryClass
  72. ** This class encapsulates the geometry data for a triangle mesh.
  73. */
  74. class MeshGeometryClass : public W3DMPO, public RefCountClass, public MultiListObjectClass
  75. {
  76. //W3DMPO_GLUE(MeshGeometryClass)
  77. public:
  78. MeshGeometryClass(void);
  79. MeshGeometryClass(const MeshGeometryClass & that);
  80. virtual ~MeshGeometryClass(void);
  81. MeshGeometryClass & operator = (const MeshGeometryClass & that);
  82. enum FlagsType
  83. {
  84. DIRTY_BOUNDS = 0x00000001,
  85. DIRTY_PLANES = 0x00000002,
  86. DIRTY_VNORMALS = 0x00000004,
  87. SORT = 0x00000010,
  88. DISABLE_BOUNDING_BOX = 0x00000020,
  89. DISABLE_BOUNDING_SPHERE = 0x00000040,
  90. DISABLE_PLANE_EQ = 0x00000080,
  91. TWO_SIDED = 0x00000100,
  92. ALIGNED = 0x00000200,
  93. SKIN = 0x00000400,
  94. ORIENTED = 0x00000800,
  95. CAST_SHADOW = 0x00001000,
  96. PRELIT_MASK = 0x0000E000,
  97. PRELIT_VERTEX = 0x00002000,
  98. PRELIT_LIGHTMAP_MULTI_PASS = 0x00004000,
  99. PRELIT_LIGHTMAP_MULTI_TEXTURE = 0x00008000,
  100. ALLOW_NPATCHES = 0x00010000,
  101. };
  102. void Reset_Geometry(int polycount,int vertcount);
  103. const char * Get_Name(void) const;
  104. void Set_Name(const char * newname);
  105. const char * Get_User_Text(void);
  106. void Set_User_Text(char * usertext);
  107. void Set_Flag(FlagsType flag,bool onoff) { if (onoff) { Flags |= flag; } else { Flags &= ~flag; } }
  108. int Get_Flag(FlagsType flag) { return Flags & flag; }
  109. void Set_Sort_Level(int level) { SortLevel = level; }
  110. int Get_Sort_Level(void) const { return SortLevel; }
  111. int Get_Polygon_Count(void) const { return PolyCount; }
  112. int Get_Vertex_Count(void) const { return VertexCount; }
  113. const Vector3i * Get_Polygon_Array(void) { return get_polys(); }
  114. Vector3 * Get_Vertex_Array(void) { WWASSERT(Vertex); return Vertex->Get_Array(); }
  115. const Vector3 * Get_Vertex_Normal_Array(void);
  116. const Vector4 * Get_Plane_Array(bool create = true);
  117. void Compute_Plane(int pidx,PlaneClass * set_plane) const;
  118. const uint32 * Get_Vertex_Shade_Index_Array(bool create = true) { return get_shade_indices(create); }
  119. const uint16 * Get_Vertex_Bone_Links(void) { return get_bone_links(); }
  120. uint8 * Get_Poly_Surface_Type_Array(void) { WWASSERT(PolySurfaceType); return PolySurfaceType->Get_Array(); }
  121. uint8 Get_Poly_Surface_Type(int poly_index) const;
  122. void Get_Bounding_Box(AABoxClass * set_box);
  123. void Get_Bounding_Sphere(SphereClass * set_sphere);
  124. // exposed culling support
  125. bool Has_Cull_Tree(void) { return CullTree != NULL; }
  126. void Generate_Rigid_APT(const Vector3 & view_dir, SimpleDynVecClass<uint32> & apt);
  127. void Generate_Rigid_APT(const OBBoxClass & local_box, SimpleDynVecClass<uint32> & apt);
  128. void Generate_Rigid_APT(const OBBoxClass & local_box, const Vector3 & view_dir, SimpleDynVecClass<uint32> & apt);
  129. void Generate_Skin_APT(const OBBoxClass & world_box, SimpleDynVecClass<uint32> & apt, const Vector3 *world_vertex_locs);
  130. // containment
  131. bool Contains(const Vector3 &point);
  132. // ray casting and intersection (takes a transform for the mesh). Note that unlike the MeshClass
  133. // functions with similar names, these work in object space.
  134. bool Cast_Ray(RayCollisionTestClass & raytest);
  135. bool Cast_AABox(AABoxCollisionTestClass & boxtest);
  136. bool Cast_OBBox(OBBoxCollisionTestClass & boxtest);
  137. bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest);
  138. // This function analyses the transform passed into it to call various optimized functions if
  139. // the transform is identity or a simple rotation about the z-axis. Otherwise it transforms
  140. // boxtest into object space, performs an oob cast and transforms the result back.
  141. bool Cast_World_Space_AABox(AABoxCollisionTestClass & boxtest, const Matrix3D &transform);
  142. // W3D File Format support. Note that derived classes have to override these functions completely
  143. // so that they can handle their extra chunks. Using these functions you could load mesh data out
  144. // of a W3D file while ignoring all materials, textures, etc.
  145. virtual WW3DErrorType Load_W3D(ChunkLoadClass & cload);
  146. void Scale(const Vector3 &sc);
  147. protected:
  148. // internal accessor functions that are not exposed to the user (non-const...)
  149. Vector3i * get_polys(void);
  150. Vector3 * get_vert_normals(void);
  151. uint32 * get_shade_indices(bool create = true);
  152. Vector4 * get_planes(bool create = true);
  153. uint16 * get_bone_links(bool create = true);
  154. // Utility functions (used by collision/intersection functions)
  155. int cast_semi_infinite_axis_aligned_ray(const Vector3 & start_point, int axis_dir, unsigned char & flags);
  156. bool cast_aabox_identity(AABoxCollisionTestClass & boxtest,const Vector3 & trans);
  157. bool cast_aabox_z90(AABoxCollisionTestClass & boxtest,const Vector3 & trans);
  158. bool cast_aabox_z180(AABoxCollisionTestClass & boxtest,const Vector3 & trans);
  159. bool cast_aabox_z270(AABoxCollisionTestClass & boxtest,const Vector3 & trans);
  160. bool intersect_obbox_brute_force(OBBoxIntersectionTestClass & localtest);
  161. bool cast_ray_brute_force(RayCollisionTestClass & raytest);
  162. bool cast_aabox_brute_force(AABoxCollisionTestClass & boxtest);
  163. bool cast_obbox_brute_force(OBBoxCollisionTestClass & boxtest);
  164. // functions to recompute dirty normals and bounding volumes.
  165. virtual void Compute_Plane_Equations(Vector4 * array);
  166. virtual void Compute_Vertex_Normals(Vector3 * array);
  167. virtual void Compute_Bounds(Vector3 * verts);
  168. void Generate_Culling_Tree(void);
  169. // W3D chunk reading
  170. WW3DErrorType read_chunks(ChunkLoadClass & cload);
  171. WW3DErrorType read_vertices(ChunkLoadClass & cload);
  172. WW3DErrorType read_vertex_normals(ChunkLoadClass & cload);
  173. WW3DErrorType read_triangles(ChunkLoadClass & cload);
  174. WW3DErrorType read_user_text(ChunkLoadClass & cload);
  175. WW3DErrorType read_vertex_influences(ChunkLoadClass & cload);
  176. WW3DErrorType read_vertex_shade_indices(ChunkLoadClass & cload);
  177. WW3DErrorType read_aabtree(ChunkLoadClass &cload);
  178. // General info
  179. ShareBufferClass<char> * MeshName;
  180. ShareBufferClass<char> * UserText;
  181. int Flags;
  182. char SortLevel;
  183. uint32 W3dAttributes;
  184. // Geometry
  185. int PolyCount;
  186. int VertexCount;
  187. ShareBufferClass<Vector3i> * Poly;
  188. ShareBufferClass<Vector3> * Vertex;
  189. ShareBufferClass<Vector3> * VertexNorm;
  190. ShareBufferClass<Vector4> * PlaneEq;
  191. ShareBufferClass<uint32> * VertexShadeIdx;
  192. ShareBufferClass<uint16> * VertexBoneLink;
  193. ShareBufferClass<uint8> * PolySurfaceType;
  194. Vector3 BoundBoxMin;
  195. Vector3 BoundBoxMax;
  196. Vector3 BoundSphereCenter;
  197. float BoundSphereRadius;
  198. AABTreeClass * CullTree;
  199. };
  200. /*
  201. ** Inline functions for MeshGeometryClass
  202. */
  203. inline Vector3i * MeshGeometryClass::get_polys(void)
  204. {
  205. WWASSERT(Poly);
  206. return Poly->Get_Array();
  207. }
  208. inline uint32 * MeshGeometryClass::get_shade_indices(bool create)
  209. {
  210. if (create && !VertexShadeIdx) {
  211. VertexShadeIdx = NEW_REF(ShareBufferClass<uint32>,(VertexCount, "MeshGeometryClass::VertexShadeIdx"));
  212. }
  213. if (VertexShadeIdx) {
  214. return VertexShadeIdx->Get_Array();
  215. }
  216. return NULL;
  217. }
  218. inline uint16 * MeshGeometryClass::get_bone_links(bool create)
  219. {
  220. if (create && !VertexBoneLink) {
  221. VertexBoneLink = NEW_REF(ShareBufferClass<uint16>,(VertexCount, "MeshGeometryClass::VertexBoneLink"));
  222. }
  223. if (VertexBoneLink) {
  224. return VertexBoneLink->Get_Array();
  225. }
  226. return NULL;
  227. }
  228. inline uint8 MeshGeometryClass::Get_Poly_Surface_Type(int poly_index) const
  229. {
  230. WWASSERT(PolySurfaceType);
  231. WWASSERT(poly_index >= 0 && poly_index < PolyCount);
  232. uint8 *type = PolySurfaceType->Get_Array();
  233. return type[poly_index];
  234. }
  235. #endif //MESHGEOMETRY_H