Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 13, 2006, 3:57:44 PM (18 years ago)
Author:
patrick
Message:

added namspacing to collision reaction. now comes the harder part :D

File:
1 edited

Legend:

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

    r9869 r9889  
    2929#include "debug.h"
    3030
    31 
    32 ObjectListDefinition(CollisionHandle);
    33 
    34 /**
    35  * standard constructor
    36  * @todo this constructor is not jet implemented - do it
    37 */
    38 CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
     31namespace CoRe
    3932{
    40   this->registerObject(this, CollisionHandle::_objectList);
    41 
    42   this->owner = owner;
    43   this->type = type;
    44 
    45   this->bCollided = false;
    46   this->bDispatched = true;
    47 
    48   this->collisionReaction = NULL;
    49   this->bContinuousPoll = false;
    50   this->bStopOnFirstCollision = false;
    51 
    52 
    53   switch( type)
    54   {
    55     case CREngine::CR_PHYSICS_FULL_WALK:
    56       this->collisionReaction = new CRPhysicsFullWalk();
    57       this->bContinuousPoll = true;
    58       break;
    59     case CREngine::CR_PHYSICS_GROUND_WALK:
    60       this->collisionReaction = new CRPhysicsGroundWalk();
    61       this->bContinuousPoll = true;
    62       break;
    63     case CREngine::CR_OBJECT_DAMAGE:
    64       this->collisionReaction = new CRObjectDamage();
    65       this->bStopOnFirstCollision = true;
    66       break;
    67     default:
    68       break;
    69   };
     33
     34  ObjectListDefinition(CollisionHandle);
     35
     36  /**
     37   * standard constructor
     38   * @todo this constructor is not jet implemented - do it
     39  */
     40  CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
     41  {
     42    this->registerObject(this, CollisionHandle::_objectList);
     43
     44    this->owner = owner;
     45    this->type = type;
     46
     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    };
     72  }
     73
     74
     75  /**
     76   * standard deconstructor
     77  */
     78  CollisionHandle::~CollisionHandle ()
     79  {
     80    // delete what has to be deleted here
     81    if( this->collisionReaction != NULL)
     82      delete this->collisionReaction;
     83  }
     84
     85  /**
     86   * restores the CollisionHandle to its initial state
     87   */
     88  void CollisionHandle::reset()
     89  {
     90    this->flushCollisions();
     91  }
     92
     93
     94  /**
     95   * add more filter targets to this collision handle
     96   *  @param classID the classid to look for
     97   */
     98  void CollisionHandle::addTarget(const ClassID& target)
     99  {
     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;
     105
     106
     107    // add element
     108    this->targetList.push_back(target);
     109    PRINTF(5)("addTarget: %i \n", target.id());
     110  }
     111
     112
     113  /**
     114   * registers a new Collision Object
     115   *  @param entityA WorldEntity A of the collision
     116   *  @param entityB WorldEntity B of the collision
     117   * if a there is already a collision object with the same stats
     118   * registration will be skipped and the last collision object is returned
     119   */
     120  Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
     121  {
     122    //first get the collision object, multiple sources
     123    Collision* c;
     124    if( this->collisionList.empty() ||
     125        ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB ))
     126    {
     127      c = CREngine::getInstance()->popCollisionObject();
     128      c->collide(entityA, entityB);
     129      this->collisionList.push_back(c);
     130
     131      // now register it as a shared collision with the other collision entity
     132      CollisionHandle* ch = entityB->getCollisionHandle(this->type);
     133      if( ch != NULL)
     134        ch->registerSharedCollision(c);
     135    }
     136    else
     137      c = this->collisionList.back();
     138
     139    return c;
     140  }
     141
     142
     143  /**
     144   * register a Collision to the Collision handle.
     145   *  @param collision the collision object to register
     146   *
     147   * This is used for internal collision registration: sharing the collision objects between Collision Reactions
     148   * Therefore dispatching it only once
     149   */
     150  void CollisionHandle::registerSharedCollision(Collision* collision)
     151  {
     152    // fist check if we are listening for this Collision
     153    if( !this->filterCollision(collision))
     154      return;
     155
     156    // set the state to not dispatched
     157    this->bDispatched = false;
     158    this->bCollided = true;
     159    collision->setEntityBCollide(true);
     160
     161    this->collisionList.push_back(collision);
     162  }
     163
     164
     165  /**
     166   * this is the function to be called on a collision event for this handle
     167   *  @param collision the collision objects containing all collision informations
     168   */
     169  void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
     170  {
     171    if( !this->filterCollisionEvent(collisionEvent))
     172      return;
     173
     174    // set the state to not dispatched
     175    this->bDispatched = false;
     176    this->bCollided = true;
     177
     178    // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
     179    Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
     180    c->setEntityACollide(true);
     181
     182    c->registerCollisionEvent(collisionEvent);
     183    PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName());
     184  }
     185
     186
     187  /**
     188   * flushes the collision list
     189   */
     190  void CollisionHandle::flushCollisions()
     191  {
     192    this->collisionList.clear();
     193  }
     194
     195
     196  /**
     197   * handles the collisions and react according to algorithm
     198   */
     199  void CollisionHandle::handleCollisions()
     200  {
     201    // if continuous poll poll the reaction
     202    if( this->bContinuousPoll && !this->bCollided)
     203    {
     204      this->collisionReaction->update(this->owner);
     205      return;
     206    }
     207
     208    // collision reaction calculations (for every collision there will be a reaction)
     209    std::vector<Collision*>::iterator it = this->collisionList.begin();
     210    for(; it < this->collisionList.end(); it++)
     211    {
     212      if( !(*it)->isDispatched())
     213      {
     214        this->collisionReaction->reactToCollision(*it);
     215        (*it)->flushCollisionEvents();
     216      }
     217    }
     218
     219    // now set state to dispatched
     220    this->bDispatched = true;
     221    this->bCollided = false;
     222
     223    this->flushCollisions();
     224  }
     225
     226
     227  /**
     228   * filter out the CollisionEvents that are not wanted
     229   *  @param collisionEvent the collision event to filter
     230   */
     231  bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
     232  {
     233    std::vector<ClassID>::iterator it = this->targetList.begin();
     234    for(; it < this->targetList.end(); it++)
     235    {
     236      //     if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM))
     237      //     {
     238      //        PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it);
     239      //        if( collisionEvent->getEntityA() == this->owner) {
     240      //          PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
     241      //          collisionEvent->getEntityB()->getClassCName(), *it);
     242      //          if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
     243      //            PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     244      //            collisionEvent->getEntityB()->getClassCName(), *it);
     245      //             }
     246      //        }
     247      //        else {
     248      //          PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
     249      //          collisionEvent->getEntityB()->getClassCName(), *it);
     250      //          if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
     251      //            PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     252      //            collisionEvent->getEntityA()->getClassCName(), *it);
     253      //             }
     254      //        }
     255      //
     256      //     }
     257
     258      if( collisionEvent->getEntityA() == this->owner)
     259      {
     260        if( collisionEvent->getEntityB()->isA((*it)))
     261        {
     262          PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     263                    collisionEvent->getEntityB()->getClassCName(), (*it).id());
     264          return true;
     265        }
     266      }
     267      else
     268      {
     269        if( collisionEvent->getEntityA()->isA((*it)))
     270        {
     271          PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     272                    collisionEvent->getEntityA()->getClassCName(), (*it).id());
     273          return true;
     274        }
     275      }
     276    }
     277
     278    return false;
     279  }
     280
     281
     282  /**
     283   * filter Collisions that are not wanted to be reacted to
     284   *  @param collision the collision object to filter
     285   */
     286  bool CollisionHandle::filterCollision(Collision* collision)
     287  {
     288    std::vector<ClassID>::iterator it = this->targetList.begin();
     289    for(; it < this->targetList.end(); it++)
     290    {
     291
     292      //     if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM))
     293      //     {
     294      //       PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it);
     295      //       if( collision->getEntityA() == this->owner) {
     296      //         PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
     297      //         collision->getEntityB()->getClassCName(), *it);
     298      //         if( collision->getEntityB()->isA((ClassID)(*it))) {
     299      //           PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     300      //           collision->getEntityB()->getClassCName(), *it);
     301      //         }
     302      //       }
     303      //       else {
     304      //         PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
     305      //         collision->getEntityB()->getClassCName(), *it);
     306      //         if( collision->getEntityA()->isA((ClassID)(*it))) {
     307      //           PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
     308      //           collision->getEntityA()->getClassCName(), *it);
     309      //         }
     310      //       }
     311      //     }
     312
     313      if( collision->getEntityA() == this->owner)
     314      {
     315        if( collision->getEntityA()->isA(*it))
     316          return true;
     317      }
     318      else
     319      {
     320        if( collision->getEntityB()->isA(*it))
     321          return true;
     322      }
     323    }
     324
     325    return false;
     326  }
     327
     328
     329
    70330}
    71331
    72332
    73 /**
    74  * standard deconstructor
    75 */
    76 CollisionHandle::~CollisionHandle ()
    77 {
    78   // delete what has to be deleted here
    79   if( this->collisionReaction != NULL)
    80     delete this->collisionReaction;
    81 }
    82 
    83 /**
    84  * restores the CollisionHandle to its initial state
    85  */
    86 void CollisionHandle::reset()
    87 {
    88   this->flushCollisions();
    89 }
    90 
    91 
    92 /**
    93  * add more filter targets to this collision handle
    94  *  @param classID the classid to look for
    95  */
    96 void CollisionHandle::addTarget(const ClassID& target)
    97 {
    98   // make sure there is no dublicate
    99   std::vector<ClassID>::iterator it = this->targetList.begin();
    100   for( ; it < this->targetList.end(); it++)
    101     if( (*it) == target)
    102       return;
    103 
    104 
    105   // add element
    106   this->targetList.push_back(target);
    107    PRINTF(5)("addTarget: %i \n", target.id());
    108 }
    109 
    110 
    111 /**
    112  * registers a new Collision Object
    113  *  @param entityA WorldEntity A of the collision
    114  *  @param entityB WorldEntity B of the collision
    115  * if a there is already a collision object with the same stats
    116  * registration will be skipped and the last collision object is returned
    117  */
    118 Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
    119 {
    120   //first get the collision object, multiple sources
    121   Collision* c;
    122   if( this->collisionList.empty() ||
    123       ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) {
    124     c = CREngine::getInstance()->popCollisionObject();
    125     c->collide(entityA, entityB);
    126     this->collisionList.push_back(c);
    127 
    128     // now register it as a shared collision with the other collision entity
    129     CollisionHandle* ch = entityB->getCollisionHandle(this->type);
    130     if( ch != NULL)
    131       ch->registerSharedCollision(c);
    132   }
    133   else
    134     c = this->collisionList.back();
    135 
    136   return c;
    137 }
    138 
    139 
    140 /**
    141  * register a Collision to the Collision handle.
    142  *  @param collision the collision object to register
    143  *
    144  * This is used for internal collision registration: sharing the collision objects between Collision Reactions
    145  * Therefore dispatching it only once
    146  */
    147 void CollisionHandle::registerSharedCollision(Collision* collision)
    148 {
    149   // fist check if we are listening for this Collision
    150   if( !this->filterCollision(collision))
    151     return;
    152 
    153   // set the state to not dispatched
    154   this->bDispatched = false;
    155   this->bCollided = true;
    156   collision->setEntityBCollide(true);
    157 
    158   this->collisionList.push_back(collision);
    159 }
    160 
    161 
    162 /**
    163  * this is the function to be called on a collision event for this handle
    164  *  @param collision the collision objects containing all collision informations
    165  */
    166 void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
    167 {
    168   if( !this->filterCollisionEvent(collisionEvent))
    169     return;
    170 
    171   // set the state to not dispatched
    172   this->bDispatched = false;
    173   this->bCollided = true;
    174 
    175   // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
    176  Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
    177  c->setEntityACollide(true);
    178 
    179  c->registerCollisionEvent(collisionEvent);
    180  PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName());
    181 }
    182 
    183 
    184 /**
    185  * flushes the collision list
    186  */
    187 void CollisionHandle::flushCollisions()
    188 {
    189   this->collisionList.clear();
    190 }
    191 
    192 
    193 /**
    194  * handles the collisions and react according to algorithm
    195  */
    196 void CollisionHandle::handleCollisions()
    197 {
    198   // if continuous poll poll the reaction
    199   if( this->bContinuousPoll && !this->bCollided)
    200   {
    201     this->collisionReaction->update(this->owner);
    202     return;
    203   }
    204 
    205   // collision reaction calculations (for every collision there will be a reaction)
    206   std::vector<Collision*>::iterator it = this->collisionList.begin();
    207   for(; it < this->collisionList.end(); it++) {
    208     if( !(*it)->isDispatched())
    209     {
    210       this->collisionReaction->reactToCollision(*it);
    211       (*it)->flushCollisionEvents();
    212     }
    213   }
    214 
    215   // now set state to dispatched
    216   this->bDispatched = true;
    217   this->bCollided = false;
    218 
    219   this->flushCollisions();
    220 }
    221 
    222 
    223 /**
    224  * filter out the CollisionEvents that are not wanted
    225  *  @param collisionEvent the collision event to filter
    226  */
    227 bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
    228 {
    229   std::vector<ClassID>::iterator it = this->targetList.begin();
    230   for(; it < this->targetList.end(); it++)
    231   {
    232 //     if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM))
    233 //     {
    234 //        PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it);
    235 //        if( collisionEvent->getEntityA() == this->owner) {
    236 //          PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    237 //          collisionEvent->getEntityB()->getClassCName(), *it);
    238 //          if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
    239 //            PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    240 //            collisionEvent->getEntityB()->getClassCName(), *it);
    241 //             }
    242 //        }
    243 //        else {
    244 //          PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    245 //          collisionEvent->getEntityB()->getClassCName(), *it);
    246 //          if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
    247 //            PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    248 //            collisionEvent->getEntityA()->getClassCName(), *it);
    249 //             }
    250 //        }
    251 //
    252 //     }
    253 
    254     if( collisionEvent->getEntityA() == this->owner) {
    255       if( collisionEvent->getEntityB()->isA((*it))) {
    256         PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    257         collisionEvent->getEntityB()->getClassCName(), (*it).id());
    258         return true; }
    259     }
    260     else {
    261       if( collisionEvent->getEntityA()->isA((*it))) {
    262         PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    263         collisionEvent->getEntityA()->getClassCName(), (*it).id());
    264       return true; }
    265     }
    266   }
    267 
    268   return false;
    269 }
    270 
    271 
    272 /**
    273  * filter Collisions that are not wanted to be reacted to
    274  *  @param collision the collision object to filter
    275  */
    276 bool CollisionHandle::filterCollision(Collision* collision)
    277 {
    278   std::vector<ClassID>::iterator it = this->targetList.begin();
    279   for(; it < this->targetList.end(); it++)
    280   {
    281 
    282 //     if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM))
    283 //     {
    284 //       PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it);
    285 //       if( collision->getEntityA() == this->owner) {
    286 //         PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    287 //         collision->getEntityB()->getClassCName(), *it);
    288 //         if( collision->getEntityB()->isA((ClassID)(*it))) {
    289 //           PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    290 //           collision->getEntityB()->getClassCName(), *it);
    291 //         }
    292 //       }
    293 //       else {
    294 //         PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
    295 //         collision->getEntityB()->getClassCName(), *it);
    296 //         if( collision->getEntityA()->isA((ClassID)(*it))) {
    297 //           PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
    298 //           collision->getEntityA()->getClassCName(), *it);
    299 //         }
    300 //       }
    301 //     }
    302 
    303     if( collision->getEntityA() == this->owner) {
    304       if( collision->getEntityA()->isA(*it))
    305         return true; }
    306       else {
    307         if( collision->getEntityB()->isA(*it))
    308           return true; }
    309   }
    310 
    311   return false;
    312 }
    313 
    314 
    315 
    316 
    317 
    318 
    319 
     333
Note: See TracChangeset for help on using the changeset viewer.