Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 20, 2006, 1:09:03 AM (18 years ago)
Author:
patrick
Message:

more design, thinner interface

Location:
branches/coll_rect/src/lib/collision_reaction
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/coll_rect/src/lib/collision_reaction/collision_filter.cc

    r9895 r9896  
    2929#include "debug.h"
    3030
     31#include <vector>
     32
     33
    3134namespace CoRe
    3235{
     
    3841   * @todo this constructor is not jet implemented - do it
    3942  */
    40   CollisionFilter::CollisionFilter (WorldEntity* owner, CREngine::ReactionType type)
     43  CollisionFilter::CollisionFilter (WorldEntity* owner)
    4144  {
    4245    this->registerObject(this, CollisionFilter::_objectList);
    4346
    44     this->owner = owner;
    45     this->type = type;
     47    this->_owner = owner;
    4648
    47     this->bCollided = false;
    48     this->bDispatched = true;
    49 
    50     this->collisionReaction = NULL;
    51     this->bContinuousPoll = false;
    52     this->bStopOnFirstCollision = false;
    53 
    54 
    55     switch( type)
    56     {
    57         case CREngine::CR_PHYSICS_FULL_WALK:
    58         this->collisionReaction = new CRPhysicsFullWalk();
    59         this->bContinuousPoll = true;
    60         break;
    61         case CREngine::CR_PHYSICS_GROUND_WALK:
    62         this->collisionReaction = new CRPhysicsGroundWalk();
    63         this->bContinuousPoll = true;
    64         break;
    65         case CREngine::CR_OBJECT_DAMAGE:
    66         this->collisionReaction = new CRObjectDamage();
    67         this->bStopOnFirstCollision = true;
    68         break;
    69         default:
    70         break;
    71     };
     49    this->_bContinuousPoll = false;
     50    this->_bStopOnFirstCollision = false;
     51    this->_bReactive = false;
    7252  }
    7353
     
    7858  CollisionFilter::~CollisionFilter ()
    7959  {
    80     // delete what has to be deleted here
    81     if( this->collisionReaction != NULL)
    82       delete this->collisionReaction;
    83   }
    84 
    85   /**
    86    * restores the CollisionFilter to its initial state
    87    */
    88   void CollisionFilter::reset()
    89   {
    90     this->flushCollisions();
     60    this->unsubscribeReactions();
    9161  }
    9262
    9363
    9464  /**
    95    * add more filter targets to this collision handle
    96    *  @param classID the classid to look for
     65   * subscribe reaction
    9766   */
    98   void CollisionFilter::addTarget(const ClassID& target)
     67  void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1)
    9968  {
    100     // make sure there is no dublicate
    101     std::vector<ClassID>::iterator it = this->targetList.begin();
    102     for( ; it < this->targetList.end(); it++)
    103       if( (*it) == target)
    104         return;
     69    // check if its a valid type
     70    if( likely(this->validCRType( type)))
     71    {
     72      //check if this or any parent class isn't already registered
     73      std::vector<ClassID>::iterator it = this->_filters[type].begin();
     74      for(; it != this->_filters[type].end(); it++)
     75      {
     76        if( unlikely(*it == target1))
     77          return;
     78      }
    10579
    106 
    107     // add element
    108     this->targetList.push_back(target);
    109     PRINTF(5)("addTarget: %i \n", target.id());
     80      // so subscribe the reaction finaly
     81      this->_filters[type].push_back(target1);
     82      this->_bReactive = true;
     83    }
    11084  }
    11185
    11286
    11387  /**
    114    * handles the collisions and react according to algorithm
     88   * subscribe for a reaction
    11589   */
    116   void CollisionFilter::handleCollisions()
     90  void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2)
    11791  {
    118     // if continuous poll the reaction
    119     if( this->bContinuousPoll && !this->bCollided)
    120     {
    121       this->collisionReaction->update(this->owner);
    122       return;
    123     }
    124 
    125     // collision reaction calculations (for every collision there will be a reaction)
    126     std::vector<Collision*>::iterator it = this->collisionList.begin();
    127     for(; it < this->collisionList.end(); it++)
    128     {
    129       if( !(*it)->isDispatched())
    130       {
    131         this->collisionReaction->reactToCollision(*it);
    132         (*it)->flushCollisionEvents();
    133       }
    134     }
    135 
    136     // now set state to dispatched
    137     this->bDispatched = true;
    138     this->bCollided = false;
    139 
    140     this->flushCollisions();
     92    this->subscribeReaction(type, target1);
     93    this->subscribeReaction(type, target2);
    14194  }
    14295
    14396
    14497  /**
    145    * filter out the CollisionEvents that are not wanted
    146    *  @param collisionEvent the collision event to filter
     98   * subscribe for a reaction
    14799   */
    148   bool CollisionFilter::filterCollisionEvent(CollisionEvent* collisionEvent)
     100  void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2, const ClassID& target3)
    149101  {
    150     std::vector<ClassID>::iterator it = this->targetList.begin();
    151     for(; it < this->targetList.end(); it++)
    152     {
    153       //     if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM))
    154       //     {
    155       //        PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it);
    156       //        if( collisionEvent->getEntityA() == this->owner) {
    157       //          PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    158       //          collisionEvent->getEntityB()->getClassCName(), *it);
    159       //          if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
    160       //            PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    161       //            collisionEvent->getEntityB()->getClassCName(), *it);
    162       //             }
    163       //        }
    164       //        else {
    165       //          PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    166       //          collisionEvent->getEntityB()->getClassCName(), *it);
    167       //          if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
    168       //            PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    169       //            collisionEvent->getEntityA()->getClassCName(), *it);
    170       //             }
    171       //        }
    172       //
    173       //     }
     102    this->subscribeReaction(type, target1);
     103    this->subscribeReaction(type, target2);
     104    this->subscribeReaction(type, target3);
     105  }
    174106
    175       if( collisionEvent->getEntityA() == this->owner)
    176       {
    177         if( collisionEvent->getEntityB()->isA((*it)))
    178         {
    179           PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    180                     collisionEvent->getEntityB()->getClassCName(), (*it).id());
    181           return true;
    182         }
    183       }
    184       else
    185       {
    186         if( collisionEvent->getEntityA()->isA((*it)))
    187         {
    188           PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    189                     collisionEvent->getEntityA()->getClassCName(), (*it).id());
    190           return true;
    191         }
    192       }
    193     }
     107  /**
     108   * unsubscribe from a specific collision reaction
     109   */
     110  void CollisionFilter::unsubscribeReaction(CoRe::CREngine::ReactionType type)
     111  {
     112    if( likely(this->validCRType( type)))
     113      this->_filters[type].clear();
     114  }
    194115
    195     return false;
     116  /**
     117   * unsubscribe from all collision reactions
     118   */
     119  void CollisionFilter::unsubscribeReactions()
     120  {
     121    for(int i = 0; i < CREngine::CR_NUMBER; i++)
     122      this->_filters[i].clear();
    196123  }
    197124
    198125
     126
    199127  /**
    200    * filter Collisions that are not wanted to be reacted to
    201    *  @param collision the collision object to filter
     128   * tests if the owner WorldEntity is listening to collisions from another specif WorldEntity entity
     129   *  @param entity WorldEntity to test against
     130   *
     131   * This is the most important interface function of this class: it performs a check and returns true
     132   * if the WorldEntity entity is actualy responsive for a certain other WorldEntity
    202133   */
    203   bool CollisionFilter::filterCollision(Collision* collision)
     134  bool CollisionFilter::operator()(const WorldEntity* entity) const
    204135  {
    205     std::vector<ClassID>::iterator it = this->targetList.begin();
    206     for(; it < this->targetList.end(); it++)
     136    // if there are no installed criterions just ommit and
     137    if( this->bReactive())
     138      return false;
     139
     140    // goes through all registered filter criterions and looks for matches
     141    for( int i = 0; i < CREngine::CR_NUMBER; i++ )
    207142    {
    208 
    209       //     if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM))
    210       //     {
    211       //       PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it);
    212       //       if( collision->getEntityA() == this->owner) {
    213       //         PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    214       //         collision->getEntityB()->getClassCName(), *it);
    215       //         if( collision->getEntityB()->isA((ClassID)(*it))) {
    216       //           PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    217       //           collision->getEntityB()->getClassCName(), *it);
    218       //         }
    219       //       }
    220       //       else {
    221       //         PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    222       //         collision->getEntityB()->getClassCName(), *it);
    223       //         if( collision->getEntityA()->isA((ClassID)(*it))) {
    224       //           PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    225       //           collision->getEntityA()->getClassCName(), *it);
    226       //         }
    227       //       }
    228       //     }
    229 
    230       if( collision->getEntityA() == this->owner)
    231       {
    232         if( collision->getEntityA()->isA(*it))
     143      std::vector<ClassID>::const_iterator it = this->_filters[i].begin();
     144      for(; it != this->_filters[i].end(); i++ )
     145        if( unlikely(entity->isA(*it)))
    233146          return true;
    234       }
    235       else
    236       {
    237         if( collision->getEntityB()->isA(*it))
    238           return true;
    239       }
    240147    }
    241148
  • branches/coll_rect/src/lib/collision_reaction/collision_filter.h

    r9895 r9896  
    11/*!
    2  * @file collision_handle.h
    3  * @brief Definition of a collision handle: used for accessing per world entity collision events and reactions
     2 * @file collision_filter.h
     3 * @brief Definition of a collision filter: checks if a certain WorldEntity is responsive for another WorldEntity
     4 *
    45*/
    56
     
    2425
    2526
    26   //! A class for defining collision reactions and storing events
     27  /**
     28   * A class for defining collision reactions and storing events (functional object)
     29   *
     30   * This class basically checks if the owner of this filter (a WorldEntity) is responsive for a certain other WorldEntity.
     31   * The check is performed via the operator() (therefore it's a functional objects). For each CollisionReaction there is a list
     32   * of WorldEntities (their ClassIDs) to which it listens to.
     33   */
    2734  class CollisionFilter : public BaseObject
    2835  {
    2936    ObjectListDeclaration(CollisionFilter);
    3037
     38
     39    /* Constructor/Deconstructors */
    3140  public:
    32     CollisionFilter(WorldEntity* owner, CREngine::ReactionType type);
     41    CollisionFilter(WorldEntity* owner);
    3342    virtual ~CollisionFilter();
    3443
    35     void reset();
    36 
    37     void addTarget(const ClassID& target);
    38 
    39     /** @returns true if regiestered some new collision events in this tick frame */
    40     inline bool isCollided() const { return this->bCollided; }
    41     /** @returns true if this collision handle has already been dispatched */
    42     inline bool isDispatched() const { return this->bDispatched; }
    43     /** @returns true if this handle should be pulled also if there are no collisions */
    44     inline bool isContinuousPoll() const { return this->bContinuousPoll; }
    45     /** @returns the type */
    46     inline CREngine::ReactionType getType() const { return this->type; }
    47 
    48     void handleCollisions();
     44  private:
     45    CollisionFilter(const CollisionFilter& collisionFilter) {}
     46    WorldEntity*                  _owner;                   //!< the worldenity this reaction will be applied on
    4947
    5048
    51   private:
    52     void flushCollisions();
    53     bool filterCollisionEvent(CollisionEvent* collisionEvent);
    54     bool filterCollision(Collision* collision);
     49    /* Defines Operators */
     50    bool operator()(const WorldEntity* entity) const;
    5551
    5652
     53    /* Collision Reaction subscription unsubscription Block */
     54  public:
     55    void subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1);
     56    void subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2);
     57    void subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2, const ClassID& target3);
     58
     59    void unsubscribeReaction(CoRe::CREngine::ReactionType type);
     60    void unsubscribeReactions();
    5761
    5862  private:
    59     WorldEntity*                  owner;                   //!< the worldenity this reaction will be applied on
    60     CREngine::ReactionType              type;                    //!< the reaction type
     63    std::vector<ClassID>          _filters[CREngine::CR_NUMBER];  //!< an array of filter targets: for each collision type a list of filter objects
    6164
    62     bool                          bContinuousPoll;         //!< if this is true
    63     bool                          bDispatched;             //!< true if this handle has already been dispatched
    64     bool                          bStopOnFirstCollision;   //!< true if the cd of this object should be terminated after one match
    65     bool                          bCollided;               //!< true if the CollsionHandle has registered some new collisions
    6665
    67     std::vector<Collision*>       collisionList;           //!< a list full of collisions
    68     std::vector<ClassID>          targetList;              //!< a list of target classes for filtering @TODO TAKE SET INSTEAD OF VECTOR HERE
     66    /* Misc State Informations */
     67  public:
     68    /** @returns true if this handle should be pulled also if there are no collisions, can also be set with this function (reference)*/
     69    inline bool& bContinousPoll() { return this->_bContinuousPoll; }
     70    /** @returns true if this filter should be pulled always */
     71    inline bool bContinousPoll() const { return this->_bContinuousPoll; }
     72    /** @returns true if this @param type Collision Reaction type is a valid number */
     73    inline bool validCRType(const CREngine::ReactionType& type) const {return (type >= 0 && type < CREngine::CR_NUMBER); }
     74    /** @returns true if this filter is reactive i.e. at least one filter criterion installed */
     75    inline bool bReactive() const { return this->_bReactive; }
    6976
    70     CollisionReaction*            collisionReaction;       //!< reference to the collision reaction object
     77  private:
     78    bool                          _bContinuousPoll;         //!< if this is true
     79    bool                          _bStopOnFirstCollision;   //!< true if the cd of this object should be terminated after one match
     80    bool                          _bReactive;               //!< true if this class has at least one filter criterion == one target
    7181
    7282  };
  • branches/coll_rect/src/lib/collision_reaction/collision_tube.cc

    r9893 r9896  
    3333
    3434  ObjectListDefinition(CollisionTube);
     35
     36  CollisionTube* CollisionTube::instance = NULL;
     37
    3538
    3639  /**
  • branches/coll_rect/src/lib/collision_reaction/collision_tube.h

    r9893 r9896  
    4848    ObjectListDeclaration(CollisionTube);
    4949
     50  public:
     51    virtual ~CollisionTube();
    5052
    51   public:
    52     CollisionTube();
    53     virtual ~CollisionTube();
     53    inline static CollisionTube* getInstance() { if( CollisionTube::instance != NULL) CollisionTube::instance = new CollisionTube(); return CollisionTube::instance; }
    5454
    5555    /** @returns true if at least one of both WorldEntities are subscribed for a collision check */
     
    6666
    6767  private:
     68    /* private std constructor since this is a singleton class */
     69    CollisionTube();
    6870    /* private copy constructor so this object can't be passed as a */
    6971    CollisionTube(const CollisionTube& tube) {}
     
    7375    std::vector<Collision*>        _collisionList;      //!< the list of collisions since the last processing
    7476
     77    static CollisionTube*          instance;            //!< the singleton instance
    7578  };
    7679
Note: See TracChangeset for help on using the changeset viewer.