Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 7, 2006, 3:00:01 PM (19 years ago)
Author:
patrick
Message:

trunk: merged the cr branche to trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/collision_reaction/collision_handle.cc

    r7927 r8190  
    1717#include "collision_handle.h"
    1818
     19#include "world_entity.h"
     20
     21#include "collision.h"
     22#include "collision_event.h"
     23#include "collision_reaction.h"
     24
     25#include "cr_object_damage.h"
     26
    1927using namespace std;
    2028
     
    3139  this->type = type;
    3240
     41  this->bCollided = false;
     42  this->bDispatched = false;
     43
     44  if( this->type == CREngine::CR_PHYSICS_STEP_BACK)
     45    this->bContinuousPoll = false;
     46  else
     47    this->bContinuousPoll = true;
     48
     49  if( this->type == CREngine::CR_OBJECT_DAMAGE)
     50    this->bStopOnFirstCollision = true;
     51  else
     52   this->bStopOnFirstCollision = false;
     53
     54  switch( type)
     55  {
     56    case CREngine::CR_OBJECT_DAMAGE:
     57      this->collisionReaction = new CRObjectDamage();
     58      break;
     59    default:
     60      break;
     61  };
    3362}
    3463
     
    4170  // delete what has to be deleted here
    4271}
     72
     73/**
     74 * restores the CollisionHandle to its initial state
     75 */
     76void CollisionHandle::reset()
     77{
     78  this->flushCollisions();
     79}
     80
     81
     82/**
     83 * add more filter targets to this collision handle
     84 *  @param classID the classid to look for
     85 */
     86void CollisionHandle::addTarget(long target)
     87{
     88  // make sure there is no dublicate
     89  std::vector<long>::iterator it = this->targetList.begin();
     90  for( ; it < this->targetList.end(); it++)
     91    if( (*it) == target)
     92      return;
     93
     94  // add element
     95   PRINTF(0)("addTarget: %i \n", target);
     96   this->targetList.push_back(target);
     97}
     98
     99
     100/**
     101 * registers a new Collision Object
     102 *  @param entityA WorldEntity A of the collision
     103 *  @param entityB WorldEntity B of the collision
     104 * if a there is already a collision object with the same stats
     105 * registration will be skipped and the last collision object is returned
     106 */
     107Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
     108{
     109  //first get the collision object, multiple sources
     110  Collision* c;
     111  if( this->collisionList.empty() ||
     112      ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) {
     113    c = CREngine::getInstance()->popCollisionObject();
     114    c->collide(entityA, entityB);
     115    this->collisionList.push_back(c);
     116
     117    // now register it as a shared collision with the other collision entity
     118    CollisionHandle* ch = entityB->getCollisionHandle(this->type);
     119    if( ch != NULL)
     120      ch->registerSharedCollision(c);
     121  }
     122  else
     123    c = this->collisionList.back();
     124
     125  return c;
     126}
     127
     128
     129/**
     130 * register a Collision to the Collision handle.
     131 *  @param collision the collision object to register
     132 *
     133 * This is used for internal collision registration: sharing the collision objects between Collision Reactions
     134 * Therefore dispatching it only once
     135 */
     136void CollisionHandle::registerSharedCollision(Collision* collision)
     137{
     138  // fist check if we are listening for this Collision
     139  if( !this->filterCollision(collision))
     140    return;
     141
     142  // set the state to not dispatched
     143  this->bDispatched = false;
     144  this->bCollided = true;
     145  collision->setEntityBCollide(true);
     146
     147  this->collisionList.push_back(collision);
     148}
     149
     150
     151/**
     152 * this is the function to be called on a collision event for this handle
     153 *  @param collision the collision objects containing all collision informations
     154 */
     155void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
     156{
     157  if( !this->filterCollisionEvent(collisionEvent))
     158    return;
     159
     160  // set the state to not dispatched
     161  this->bDispatched = false;
     162  this->bCollided = true;
     163
     164  // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
     165 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
     166 c->setEntityACollide(true);
     167
     168 c->registerCollisionEvent(collisionEvent);
     169}
     170
     171
     172/**
     173 * flushes the collision list
     174 */
     175void CollisionHandle::flushCollisions()
     176{
     177  this->collisionList.clear();
     178}
     179
     180
     181/**
     182 * handles the collisions and react according to algorithm
     183 */
     184void CollisionHandle::handleCollisions()
     185{
     186  // collision reaction calculations (for every collision there will be a reaction)
     187  vector<Collision*>::iterator it = this->collisionList.begin();
     188  for(; it < this->collisionList.end(); it++) {
     189    if( !(*it)->isDispatched())
     190    {
     191      this->collisionReaction->reactToCollision(*it);
     192      (*it)->flushCollisionEvents();
     193    }
     194  }
     195
     196  // now set state to dispatched
     197  this->bDispatched = true;
     198  this->bCollided = false;
     199
     200  this->flushCollisions();
     201}
     202
     203
     204/**
     205 * filter out the CollisionEvents that are not wanted
     206 *  @param collisionEvent the collision event to filter
     207 */
     208bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
     209{
     210  vector<long>::iterator it = this->targetList.begin();
     211  for(; it < this->targetList.end(); it++)
     212  {
     213    if( collisionEvent->getEntityA() == this->owner) {
     214      if( collisionEvent->getEntityA()->isA((ClassID)(*it)))
     215        return true; }
     216    else {
     217      if( collisionEvent->getEntityB()->isA((ClassID)(*it)))
     218        return true; }
     219  }
     220
     221  return false;
     222}
     223
     224
     225/**
     226 * filter Collisions that are not wanted to be reacted to
     227 *  @param collision the collision object to filter
     228 */
     229bool CollisionHandle::filterCollision(Collision* collision)
     230{
     231  vector<long>::iterator it = this->targetList.begin();
     232  for(; it < this->targetList.end(); it++)
     233  {
     234    if( collision->getEntityA() == this->owner) {
     235      if( collision->getEntityA()->isA((ClassID)(*it)))
     236        return true; }
     237      else {
     238        if( collision->getEntityB()->isA((ClassID)(*it)))
     239          return true; }
     240  }
     241
     242  return false;
     243}
     244
     245
     246
     247
     248
     249
     250
Note: See TracChangeset for help on using the changeset viewer.