home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / game / physics / Clip.h < prev    next >
C/C++ Source or Header  |  2005-11-14  |  15KB  |  407 lines

  1.  
  2. #ifndef __CLIP_H__
  3. #define __CLIP_H__
  4.  
  5. // RAVEN BEGIN
  6. // ddynerman: SD's clip sector code
  7. const int CLIPSECTOR_DEPTH                = 6;
  8. const int CLIPSECTOR_WIDTH                = 1 << CLIPSECTOR_DEPTH;
  9. // RAVEN END
  10.  
  11. /*
  12. ===============================================================================
  13.  
  14.   Handles collision detection with the world and between physics objects.
  15.  
  16. ===============================================================================
  17. */
  18.  
  19. #define CLIPMODEL_ID_TO_JOINT_HANDLE( id )    ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) )
  20. #define JOINT_HANDLE_TO_CLIPMODEL_ID( id )    ( -1 - id )
  21.  
  22. class idClip;
  23. class idClipModel;
  24. class idEntity;
  25.  
  26.  
  27. //===============================================================
  28. //
  29. //    idClipModel
  30. //
  31. //===============================================================
  32.  
  33. class idClipModel {
  34.  
  35.     friend class idClip;
  36.  
  37. public:
  38.                             idClipModel( void );
  39.                             explicit idClipModel( const char *name );
  40.                             explicit idClipModel( const idTraceModel &trm, const idMaterial *material = NULL );
  41.                             explicit idClipModel( const int renderModelHandle );
  42.                             explicit idClipModel( const idClipModel *model );
  43.                             ~idClipModel( void );
  44. // RAVEN BEGIN
  45. // ddynerman: SD's clip sector code
  46.     void                    UpdateDynamicContents( void );
  47. // RAVEN END
  48.  
  49.     bool                    LoadModel( const char *name );
  50.     void                    LoadModel( const idTraceModel &trm, const idMaterial *material );
  51.     void                    LoadModel( const int renderModelHandle );
  52.  
  53.     void                    Save( idSaveGame *savefile ) const;
  54.     void                    Restore( idRestoreGame *savefile );
  55. // RAVEN BEGIN
  56. // ddynerman: multiple clip worlds
  57.     void                    Link( void );                // must have been linked with an entity and id before
  58.     void                    Link( idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
  59. // RAVEN END
  60.     void                    Unlink( void );                        // unlink from sectors
  61.     void                    SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis );    // unlinks the clip model
  62.     void                    Translate( const idVec3 &translation );                            // unlinks the clip model
  63.     void                    Rotate( const idRotation &rotation );                            // unlinks the clip model
  64.     void                    Enable( void );                        // enable for clipping
  65.     void                    Disable( void );                    // keep linked but disable for clipping
  66.     void                    SetContents( int newContents );        // override contents
  67.     int                        GetContents( void ) const;
  68.     void                    SetEntity( idEntity *newEntity );
  69.     idEntity *                GetEntity( void ) const;
  70.     void                    SetId( int newId );
  71.     int                        GetId( void ) const;
  72.     void                    SetOwner( idEntity *newOwner );
  73.     idEntity *                GetOwner( void ) const;
  74.     const idBounds &        GetBounds( void ) const;
  75.     const idBounds &        GetAbsBounds( void ) const;
  76.     const idVec3 &            GetOrigin( void ) const;
  77.     const idMat3 &            GetAxis( void ) const;
  78.     bool                    IsTraceModel( void ) const;            // returns true if this is a trace model
  79.     bool                    IsRenderModel( void ) const;        // returns true if this is a render model
  80.     bool                    IsLinked( void ) const;                // returns true if the clip model is linked
  81.     bool                    IsEnabled( void ) const;            // returns true if enabled for collision detection
  82.     bool                    IsEqual( const idTraceModel &trm ) const;
  83.     idCollisionModel *        GetCollisionModel( void ) const;    // returns handle used to collide vs this model
  84.     const idTraceModel *    GetTraceModel( void ) const;
  85.     void                    GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const;
  86.  
  87.     static void                ClearTraceModelCache( void );
  88.     static int                TraceModelCacheSize( void );
  89.     static void                SaveTraceModels( idSaveGame *savefile );
  90.     static void                RestoreTraceModels( idRestoreGame *savefile );
  91.  
  92. private:
  93.     bool                    enabled;                // true if this clip model is used for clipping
  94. // RAVEN BEGIN
  95.     bool                    checked;                // Splash's clip model code
  96. // RAVEN END
  97.     idEntity *                entity;                    // entity using this clip model
  98.     int                        id;                        // id for entities that use multiple clip models
  99.     idEntity *                owner;                    // owner of the entity that owns this clip model
  100.     idVec3                    origin;                    // origin of clip model
  101.     idMat3                    axis;                    // orientation of clip model
  102.     idBounds                bounds;                    // bounds
  103.     idBounds                absBounds;                // absolute bounds
  104.     int                        contents;                // all contents ored together
  105.     idCollisionModel *        collisionModel;            // handle to collision model
  106.     int                        traceModelIndex;        // trace model used for collision detection
  107.     int                        renderModelHandle;        // render model def handle
  108.  
  109.     struct clipLink_s *        clipLinks;                // links into sectors
  110.     int                        touchCount;
  111.  
  112.     void                    Init( void );            // initialize
  113.     void                    FreeModel( void );
  114.     void                    Link_r( struct clipSector_s *node );
  115.  
  116.     static void                CacheCollisionModels( void );
  117.     static int                AllocTraceModel( const idTraceModel &trm, const idMaterial *material );
  118.     static void                FreeTraceModel( int traceModelIndex );
  119.     static int                CopyTraceModel( const int traceModelIndex );
  120.     static idTraceModel *    GetCachedTraceModel( int traceModelIndex );
  121.     static idCollisionModel*GetCachedCollisionModel( int traceModelIndex );
  122.     static int                GetTraceModelHashKey( const idTraceModel &trm );
  123. };
  124.  
  125.  
  126. ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
  127.     Unlink();
  128.     origin += translation;
  129. }
  130.  
  131. ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
  132.     Unlink();
  133.     origin *= rotation;
  134.     axis *= rotation.ToMat3();
  135. }
  136.  
  137. ID_INLINE void idClipModel::Enable( void ) {
  138.     enabled = true;
  139. }
  140.  
  141. ID_INLINE void idClipModel::Disable( void ) {
  142.     enabled = false;
  143. }
  144.  
  145. ID_INLINE void idClipModel::SetContents( int newContents ) {
  146.     contents = newContents;
  147. // RAVEN BEGIN
  148. // ddynerman: SD's clip sector code
  149.     UpdateDynamicContents();
  150. // RAVEN END
  151. }
  152.  
  153. ID_INLINE int idClipModel::GetContents( void ) const {
  154.     return contents;
  155. }
  156.  
  157. ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
  158.     entity = newEntity;
  159. }
  160.  
  161. ID_INLINE idEntity *idClipModel::GetEntity( void ) const {
  162.     return entity;
  163. }
  164.  
  165. ID_INLINE void idClipModel::SetId( int newId ) {
  166.     id = newId;
  167. }
  168.  
  169. ID_INLINE int idClipModel::GetId( void ) const {
  170.     return id;
  171. }
  172.  
  173. ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
  174.     owner = newOwner;
  175. }
  176.  
  177. ID_INLINE idEntity *idClipModel::GetOwner( void ) const {
  178.     return owner;
  179. }
  180.  
  181. ID_INLINE const idBounds &idClipModel::GetBounds( void ) const {
  182.     return bounds;
  183. }
  184.  
  185. ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const {
  186.     return absBounds;
  187. }
  188.  
  189. ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const {
  190.     return origin;
  191. }
  192.  
  193. ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const {
  194.     return axis;
  195. }
  196.  
  197. ID_INLINE bool idClipModel::IsRenderModel( void ) const {
  198.     return ( renderModelHandle != -1 );
  199. }
  200.  
  201. ID_INLINE bool idClipModel::IsTraceModel( void ) const {
  202.     return ( traceModelIndex != -1 );
  203. }
  204.  
  205. ID_INLINE bool idClipModel::IsLinked( void ) const {
  206.     return ( clipLinks != NULL );
  207. }
  208.  
  209. ID_INLINE bool idClipModel::IsEnabled( void ) const {
  210.     return enabled;
  211. }
  212.  
  213. ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
  214.     return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
  215. }
  216.  
  217. ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const {
  218.     if ( !IsTraceModel() ) {
  219.         return NULL;
  220.     }
  221.     return idClipModel::GetCachedTraceModel( traceModelIndex );
  222. }
  223.  
  224.  
  225. //===============================================================
  226. //
  227. //    idClip
  228. //
  229. //===============================================================
  230.  
  231. class idClip {
  232.  
  233.     friend class idClipModel;
  234.  
  235. public:
  236.                             idClip( void );
  237.  
  238.     void                    Init( void );
  239.     void                    Shutdown( void );
  240.  
  241.     // clip versus the rest of the world
  242. // RAVEN BEGIN
  243. // nmckenzie: we have cases where both a guy and his target need to be ignored by a translation
  244.     bool                    Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
  245.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, const idEntity *passEntity2 = 0 );
  246. // RAVEN END
  247.     bool                    Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
  248.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  249.     bool                    Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
  250.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  251.     int                        Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
  252.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
  253. // RAVEN BEGIN
  254. // AReis: Added ability to get the entity that was touched as well.
  255.     int                        Contents( const idVec3 &start, 
  256.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, idEntity **touchedEntity = NULL );
  257. // RAVEN END
  258.  
  259.     // special case translations versus the rest of the world
  260.     bool                    TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
  261.                                 int contentMask, const idEntity *passEntity );
  262.     bool                    TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
  263.                                 int contentMask, const idEntity *passEntity );
  264.  
  265.     // clip versus a specific model
  266.     void                    TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
  267.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  268.                                 idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  269.     void                    RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
  270.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  271.                                 idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  272.     int                        ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
  273.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  274.                                 idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  275.     int                        ContentsModel( const idVec3 &start,
  276.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
  277.                                 idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
  278.  
  279.     // clip versus all entities but not the world
  280. // RAVEN BEGIN
  281. // nmckenzie: had to add a second pass entity so we can safely ignore both a guy and his target in some cases
  282.     void                    TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
  283.                                 const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, const idEntity *passEntity2 = 0 );
  284. // RAVEN END
  285.  
  286.     // get a contact feature
  287.     bool                    GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
  288.  
  289.     // get entities/clip models within or touching the given bounds
  290.     int                        EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
  291.     int                        ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
  292.  
  293. // RAVEN BEGIN
  294. // ddynerman: another helper function, useful in MP
  295.     int                        PlayersTouchingBounds( const idBounds &bounds, int contentMask, idPlayer **entityList, int maxCount ) const;
  296. // RAVEN END
  297.  
  298.     const idBounds &        GetWorldBounds( void ) const;
  299.     idCollisionModel *        GetWorldCollisionModel( void ) const { return world; }
  300.  
  301. // RAVEN BEGIN
  302. // ddynerman: change to static
  303.     static idClipModel *    DefaultClipModel( void );
  304.     static void                FreeDefaultClipModel( void );
  305. // RAVEN END
  306.  
  307.                             // stats and debug drawing
  308.     void                    PrintStatistics( void );
  309.     void                    DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity, const idTypeInfo* type = NULL );
  310.     bool                    DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
  311.  
  312. // RAVEN BEGIN
  313. // rjohnson: added debug hud support
  314.     void                    DebugHudStatistics( void );
  315.     void                    ClearStatistics( void );
  316. // RAVEN END
  317.  
  318. // RAVEN BEGIN
  319. // ddynerman: SD's clip sector code
  320.     void                    CoordsForBounds( int* coords, idBounds& bounds ) const;
  321.     void                    DrawClipSectors( void ) const;
  322.     void                    DrawAreaClipSectors( float range ) const;    
  323.     static void                UpdateDynamicContents( struct clipSector_s* sector );
  324.     static void                UpdateDynamicContents( idClipModel* clipModel );
  325. // RAVEN END
  326.  
  327. private:
  328. // RAVEN BEGIN
  329. // ddynerman: SD's clip sector code
  330.     idVec3                    nodeScale;
  331.     idVec3                    nodeOffset;
  332.     idVec3                    nodeOffsetVisual;
  333. // ddynerman: change to static
  334.     static idClipModel        defaultClipModel;
  335. // RAVEN END
  336.     struct clipSector_s *    clipSectors;
  337.     idCollisionModel *        world;
  338.     idBounds                worldBounds;
  339.     idClipModel                temporaryClipModel;
  340.  
  341.     mutable int                touchCount;
  342.                             // statistics
  343.     int                        numTranslations;
  344.     int                        numRotations;
  345.     int                        numMotions;
  346.     int                        numRenderModelTraces;
  347.     int                        numContents;
  348.     int                        numContacts;
  349.  
  350. private:
  351.     struct clipSector_s *    CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
  352.     void                    ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
  353.     const idTraceModel *    TraceModelForClipModel( const idClipModel *mdl ) const;
  354. // RAVEN BEGIN
  355. // nmckenzie: had to add a second pass entity so we can safely ignore both a guy and his target in some cases
  356.     int                        GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList, const idEntity *passEntity2 = 0 ) const;
  357. // RAVEN END
  358.     void                    TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
  359. // RAVEN BEGIN
  360. // ddynerman: SD's clip sector code
  361.     void                    GetClipSectorsStaticContents( void );
  362. // RAVEN END
  363. };
  364.  
  365.  
  366. ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
  367.     Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
  368.     return ( results.fraction < 1.0f );
  369. }
  370.  
  371. ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
  372.     temporaryClipModel.LoadModel( idTraceModel( bounds ), NULL );
  373.     Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
  374.     return ( results.fraction < 1.0f );
  375. }
  376.  
  377. ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const {
  378.     return worldBounds;
  379. }
  380.  
  381. // RAVEN BEGIN
  382. // ddynerman: SD's clip sector code
  383. ID_INLINE void idClip::CoordsForBounds( int* coords, idBounds& bounds ) const {
  384.     float fCoords[ 4 ];
  385.  
  386.     fCoords[ 0 ] = ( bounds[ 0 ].x - nodeOffset.x ) * nodeScale.x;
  387.     fCoords[ 1 ] = ( bounds[ 0 ].y - nodeOffset.y ) * nodeScale.y;
  388.     fCoords[ 2 ] = ( bounds[ 1 ].x - nodeOffset.x ) * nodeScale.x;
  389.     fCoords[ 3 ] = ( bounds[ 1 ].y - nodeOffset.y ) * nodeScale.y;
  390.  
  391.     int i;
  392.     for( i = 0; i < 4; i++ ) {
  393.  
  394.         coords[ i ] = idMath::FtoiFast( fCoords[ i ] );
  395.  
  396.         if( coords[ i ] < 0 ) {
  397.             coords[ i ] = 0;
  398.         } else if( coords[ i ] > CLIPSECTOR_WIDTH - 1 ) {
  399.             coords[ i ] = CLIPSECTOR_WIDTH - 1;
  400.         }
  401.     }
  402.     coords[ 2 ]++; coords[ 3 ]++;
  403. }
  404. // RAVEN END
  405.  
  406. #endif /* !__CLIP_H__ */
  407.