Clip.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code 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. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __CLIP_H__
  21. #define __CLIP_H__
  22. /*
  23. ===============================================================================
  24. Handles collision detection with the world and between physics objects.
  25. ===============================================================================
  26. */
  27. #define CLIPMODEL_ID_TO_JOINT_HANDLE( id ) ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) )
  28. #define JOINT_HANDLE_TO_CLIPMODEL_ID( id ) ( -1 - id )
  29. class idClip;
  30. class idClipModel;
  31. class idEntity;
  32. //===============================================================
  33. //
  34. // idClipModel
  35. //
  36. //===============================================================
  37. class idClipModel {
  38. friend class idClip;
  39. public:
  40. idClipModel( void );
  41. explicit idClipModel( const char *name );
  42. explicit idClipModel( const idTraceModel &trm );
  43. explicit idClipModel( const int renderModelHandle );
  44. explicit idClipModel( const idClipModel *model );
  45. ~idClipModel( void );
  46. bool LoadModel( const char *name );
  47. void LoadModel( const idTraceModel &trm );
  48. void LoadModel( const int renderModelHandle );
  49. void Save( idSaveGame *savefile ) const;
  50. void Restore( idRestoreGame *savefile );
  51. void Link( idClip &clp ); // must have been linked with an entity and id before
  52. void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
  53. void Unlink( void ); // unlink from sectors
  54. void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model
  55. void Translate( const idVec3 &translation ); // unlinks the clip model
  56. void Rotate( const idRotation &rotation ); // unlinks the clip model
  57. void Enable( void ); // enable for clipping
  58. void Disable( void ); // keep linked but disable for clipping
  59. void SetMaterial( const idMaterial *m );
  60. const idMaterial * GetMaterial( void ) const;
  61. void SetContents( int newContents ); // override contents
  62. int GetContents( void ) const;
  63. void SetEntity( idEntity *newEntity );
  64. idEntity * GetEntity( void ) const;
  65. void SetId( int newId );
  66. int GetId( void ) const;
  67. void SetOwner( idEntity *newOwner );
  68. idEntity * GetOwner( void ) const;
  69. const idBounds & GetBounds( void ) const;
  70. const idBounds & GetAbsBounds( void ) const;
  71. const idVec3 & GetOrigin( void ) const;
  72. const idMat3 & GetAxis( void ) const;
  73. bool IsTraceModel( void ) const; // returns true if this is a trace model
  74. bool IsRenderModel( void ) const; // returns true if this is a render model
  75. bool IsLinked( void ) const; // returns true if the clip model is linked
  76. bool IsEnabled( void ) const; // returns true if enabled for collision detection
  77. bool IsEqual( const idTraceModel &trm ) const;
  78. cmHandle_t Handle( void ) const; // returns handle used to collide vs this model
  79. const idTraceModel * GetTraceModel( void ) const;
  80. void GetMassProperties( const float density, float &mass, idVec3 &centerOfMass, idMat3 &inertiaTensor ) const;
  81. static cmHandle_t CheckModel( const char *name );
  82. static void ClearTraceModelCache( void );
  83. static int TraceModelCacheSize( void );
  84. static void SaveTraceModels( idSaveGame *savefile );
  85. static void RestoreTraceModels( idRestoreGame *savefile );
  86. private:
  87. bool enabled; // true if this clip model is used for clipping
  88. idEntity * entity; // entity using this clip model
  89. int id; // id for entities that use multiple clip models
  90. idEntity * owner; // owner of the entity that owns this clip model
  91. idVec3 origin; // origin of clip model
  92. idMat3 axis; // orientation of clip model
  93. idBounds bounds; // bounds
  94. idBounds absBounds; // absolute bounds
  95. const idMaterial * material; // material for trace models
  96. int contents; // all contents ored together
  97. cmHandle_t collisionModelHandle; // handle to collision model
  98. int traceModelIndex; // trace model used for collision detection
  99. int renderModelHandle; // render model def handle
  100. struct clipLink_s * clipLinks; // links into sectors
  101. int touchCount;
  102. void Init( void ); // initialize
  103. void Link_r( struct clipSector_s *node );
  104. static int AllocTraceModel( const idTraceModel &trm );
  105. static void FreeTraceModel( int traceModelIndex );
  106. static idTraceModel * GetCachedTraceModel( int traceModelIndex );
  107. static int GetTraceModelHashKey( const idTraceModel &trm );
  108. };
  109. ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
  110. Unlink();
  111. origin += translation;
  112. }
  113. ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
  114. Unlink();
  115. origin *= rotation;
  116. axis *= rotation.ToMat3();
  117. }
  118. ID_INLINE void idClipModel::Enable( void ) {
  119. enabled = true;
  120. }
  121. ID_INLINE void idClipModel::Disable( void ) {
  122. enabled = false;
  123. }
  124. ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) {
  125. material = m;
  126. }
  127. ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const {
  128. return material;
  129. }
  130. ID_INLINE void idClipModel::SetContents( int newContents ) {
  131. contents = newContents;
  132. }
  133. ID_INLINE int idClipModel::GetContents( void ) const {
  134. return contents;
  135. }
  136. ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
  137. entity = newEntity;
  138. }
  139. ID_INLINE idEntity *idClipModel::GetEntity( void ) const {
  140. return entity;
  141. }
  142. ID_INLINE void idClipModel::SetId( int newId ) {
  143. id = newId;
  144. }
  145. ID_INLINE int idClipModel::GetId( void ) const {
  146. return id;
  147. }
  148. ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
  149. owner = newOwner;
  150. }
  151. ID_INLINE idEntity *idClipModel::GetOwner( void ) const {
  152. return owner;
  153. }
  154. ID_INLINE const idBounds &idClipModel::GetBounds( void ) const {
  155. return bounds;
  156. }
  157. ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const {
  158. return absBounds;
  159. }
  160. ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const {
  161. return origin;
  162. }
  163. ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const {
  164. return axis;
  165. }
  166. ID_INLINE bool idClipModel::IsRenderModel( void ) const {
  167. return ( renderModelHandle != -1 );
  168. }
  169. ID_INLINE bool idClipModel::IsTraceModel( void ) const {
  170. return ( traceModelIndex != -1 );
  171. }
  172. ID_INLINE bool idClipModel::IsLinked( void ) const {
  173. return ( clipLinks != NULL );
  174. }
  175. ID_INLINE bool idClipModel::IsEnabled( void ) const {
  176. return enabled;
  177. }
  178. ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
  179. return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
  180. }
  181. ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const {
  182. if ( !IsTraceModel() ) {
  183. return NULL;
  184. }
  185. return idClipModel::GetCachedTraceModel( traceModelIndex );
  186. }
  187. //===============================================================
  188. //
  189. // idClip
  190. //
  191. //===============================================================
  192. class idClip {
  193. friend class idClipModel;
  194. public:
  195. idClip( void );
  196. void Init( void );
  197. void Shutdown( void );
  198. // clip versus the rest of the world
  199. bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
  200. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  201. bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
  202. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  203. bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
  204. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  205. int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
  206. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  207. int Contents( const idVec3 &start,
  208. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  209. // special case translations versus the rest of the world
  210. bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
  211. int contentMask, const idEntity *passEntity );
  212. bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
  213. int contentMask, const idEntity *passEntity );
  214. // clip versus a specific model
  215. void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
  216. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  217. cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  218. void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
  219. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  220. cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  221. int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
  222. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  223. cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  224. int ContentsModel( const idVec3 &start,
  225. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  226. cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  227. // clip versus all entities but not the world
  228. void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
  229. const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  230. // get a contact feature
  231. bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
  232. // get entities/clip models within or touching the given bounds
  233. int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
  234. int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
  235. const idBounds & GetWorldBounds( void ) const;
  236. idClipModel * DefaultClipModel( void );
  237. // stats and debug drawing
  238. void PrintStatistics( void );
  239. void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity );
  240. bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
  241. private:
  242. int numClipSectors;
  243. struct clipSector_s * clipSectors;
  244. idBounds worldBounds;
  245. idClipModel temporaryClipModel;
  246. idClipModel defaultClipModel;
  247. mutable int touchCount;
  248. // statistics
  249. int numTranslations;
  250. int numRotations;
  251. int numMotions;
  252. int numRenderModelTraces;
  253. int numContents;
  254. int numContacts;
  255. private:
  256. struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
  257. void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
  258. const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const;
  259. int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const;
  260. void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
  261. };
  262. ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
  263. Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
  264. return ( results.fraction < 1.0f );
  265. }
  266. ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
  267. temporaryClipModel.LoadModel( idTraceModel( bounds ) );
  268. Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
  269. return ( results.fraction < 1.0f );
  270. }
  271. ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const {
  272. return worldBounds;
  273. }
  274. ID_INLINE idClipModel *idClip::DefaultClipModel( void ) {
  275. return &defaultClipModel;
  276. }
  277. #endif /* !__CLIP_H__ */