Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/coll_rect/src/lib/collision_reaction/collision_handle.cc @ 9890

Last change on this file since 9890 was 9890, checked in by patrick, 18 years ago

intruducing new container collision_tube. which serves as a central collision registration tube.

File size: 10.1 KB
RevLine 
[7841]1/*
[8495]2   orxonox - the future of 3D-vertical-scrollersf
[7841]3
4   Copyright (C) 2004 orx
5
6   This program 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 2, or (at your option)
9   any later version.
10
11   ### File Specific:
[7927]12   main-programmer: Patrick Boenzli
[7841]13*/
14
15#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
16
17#include "collision_handle.h"
18
[8190]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"
[8490]26#include "cr_physics_ground_walk.h"
[9235]27#include "cr_physics_full_walk.h"
[8190]28
[8362]29#include "debug.h"
30
[9889]31namespace CoRe
[7841]32{
33
[9889]34  ObjectListDefinition(CollisionHandle);
[7927]35
[9889]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);
[8190]43
[9889]44    this->owner = owner;
45    this->type = type;
[8190]46
[9889]47    this->bCollided = false;
48    this->bDispatched = true;
[8190]49
[9889]50    this->collisionReaction = NULL;
51    this->bContinuousPoll = false;
52    this->bStopOnFirstCollision = false;
[7841]53
54
[9889]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  }
[8190]73
74
[9889]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  }
[8190]84
[9889]85  /**
86   * restores the CollisionHandle to its initial state
87   */
88  void CollisionHandle::reset()
89  {
90    this->flushCollisions();
91  }
[8190]92
[9869]93
[9889]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;
[8190]105
106
[9889]107    // add element
108    this->targetList.push_back(target);
109    PRINTF(5)("addTarget: %i \n", target.id());
[8190]110  }
111
112
[9889]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);
[8190]130
[9889]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();
[8190]138
[9889]139    return c;
140  }
[8190]141
142
[9889]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;
[8190]155
[9889]156    // set the state to not dispatched
157    this->bDispatched = false;
158    this->bCollided = true;
159    collision->setEntityBCollide(true);
[8190]160
[9889]161    this->collisionList.push_back(collision);
162  }
[8190]163
164
[9889]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;
[8190]173
[9889]174    // set the state to not dispatched
175    this->bDispatched = false;
176    this->bCollided = true;
[8190]177
[9889]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);
[8190]181
[9889]182    c->registerCollisionEvent(collisionEvent);
183    PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName());
184  }
[8190]185
[9889]186
187  /**
188   * flushes the collision list
189   */
190  void CollisionHandle::flushCollisions()
[8490]191  {
[9889]192    this->collisionList.clear();
[8490]193  }
194
[9889]195
196  /**
197   * handles the collisions and react according to algorithm
198   */
199  void CollisionHandle::handleCollisions()
200  {
[9890]201    // if continuous poll the reaction
[9889]202    if( this->bContinuousPoll && !this->bCollided)
[8190]203    {
[9889]204      this->collisionReaction->update(this->owner);
205      return;
[8190]206    }
207
[9889]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    }
[8190]218
[9889]219    // now set state to dispatched
220    this->bDispatched = true;
221    this->bCollided = false;
[8190]222
[9889]223    this->flushCollisions();
224  }
[8190]225
[9889]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)
[8190]232  {
[9889]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      //     }
[9235]257
[9889]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      }
[8490]276    }
[9889]277
278    return false;
[8190]279  }
280
281
[9889]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)
[8190]287  {
[9889]288    std::vector<ClassID>::iterator it = this->targetList.begin();
289    for(; it < this->targetList.end(); it++)
290    {
[9235]291
[9889]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      //     }
[9235]312
[9889]313      if( collision->getEntityA() == this->owner)
314      {
315        if( collision->getEntityA()->isA(*it))
316          return true;
317      }
318      else
319      {
[9869]320        if( collision->getEntityB()->isA(*it))
[9889]321          return true;
322      }
323    }
324
325    return false;
[8190]326  }
327
328
329
[9889]330}
[8190]331
332
333
Note: See TracBrowser for help on using the repository browser.