2
0

meshgeometry.h 11 KB

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