Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/collision_reaction/collision_handle.cc @ 9990

Last change on this file since 9990 was 9869, checked in by bensch, 18 years ago

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 9.4 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
[7841]31
[9869]32ObjectListDefinition(CollisionHandle);
[7841]33
34/**
35 * standard constructor
36 * @todo this constructor is not jet implemented - do it
37*/
[7927]38CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
[7841]39{
[9869]40  this->registerObject(this, CollisionHandle::_objectList);
[7841]41
[7927]42  this->owner = owner;
43  this->type = type;
44
[8190]45  this->bCollided = false;
[8490]46  this->bDispatched = true;
[8190]47
[8490]48  this->collisionReaction = NULL;
49  this->bContinuousPoll = false;
50  this->bStopOnFirstCollision = false;
[8190]51
52
53  switch( type)
54  {
[9235]55    case CREngine::CR_PHYSICS_FULL_WALK:
56      this->collisionReaction = new CRPhysicsFullWalk();
[8490]57      this->bContinuousPoll = true;
58      break;
59    case CREngine::CR_PHYSICS_GROUND_WALK:
60      this->collisionReaction = new CRPhysicsGroundWalk();
61      this->bContinuousPoll = true;
62      break;
[8190]63    case CREngine::CR_OBJECT_DAMAGE:
64      this->collisionReaction = new CRObjectDamage();
[8490]65      this->bStopOnFirstCollision = true;
[8190]66      break;
67    default:
68      break;
69  };
[7841]70}
71
72
73/**
74 * standard deconstructor
75*/
76CollisionHandle::~CollisionHandle ()
77{
78  // delete what has to be deleted here
[8490]79  if( this->collisionReaction != NULL)
80    delete this->collisionReaction;
[7841]81}
[8190]82
83/**
84 * restores the CollisionHandle to its initial state
85 */
86void 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 */
[9869]96void CollisionHandle::addTarget(const ClassID& target)
[8190]97{
98  // make sure there is no dublicate
[9869]99  std::vector<ClassID>::iterator it = this->targetList.begin();
[8190]100  for( ; it < this->targetList.end(); it++)
101    if( (*it) == target)
102      return;
103
[9869]104
[8724]105  // add element
[9869]106  this->targetList.push_back(target);
107   PRINTF(5)("addTarget: %i \n", target.id());
[8190]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 */
118Collision* 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 */
147void 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 */
166void 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);
[9406]180 PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName());
[8190]181}
182
183
184/**
185 * flushes the collision list
186 */
187void CollisionHandle::flushCollisions()
188{
189  this->collisionList.clear();
190}
191
192
193/**
194 * handles the collisions and react according to algorithm
195 */
196void CollisionHandle::handleCollisions()
197{
[8490]198  // if continuous poll poll the reaction
199  if( this->bContinuousPoll && !this->bCollided)
200  {
201    this->collisionReaction->update(this->owner);
202    return;
203  }
204
[8190]205  // collision reaction calculations (for every collision there will be a reaction)
[9406]206  std::vector<Collision*>::iterator it = this->collisionList.begin();
[8190]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 */
227bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
228{
[9869]229  std::vector<ClassID>::iterator it = this->targetList.begin();
[8190]230  for(; it < this->targetList.end(); it++)
231  {
[9235]232//     if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM))
233//     {
[9406]234//        PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it);
[9235]235//        if( collisionEvent->getEntityA() == this->owner) {
[9406]236//          PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
237//          collisionEvent->getEntityB()->getClassCName(), *it);
[9235]238//          if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
[9406]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);
[9235]241//             }
242//        }
243//        else {
[9406]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);
[9235]246//          if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
[9406]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);
[9235]249//             }
250//        }
251//
252//     }
253
[8190]254    if( collisionEvent->getEntityA() == this->owner) {
[9869]255      if( collisionEvent->getEntityB()->isA((*it))) {
[9406]256        PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
[9869]257        collisionEvent->getEntityB()->getClassCName(), (*it).id());
[8190]258        return true; }
[8490]259    }
[8190]260    else {
[9869]261      if( collisionEvent->getEntityA()->isA((*it))) {
[9406]262        PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
[9869]263        collisionEvent->getEntityA()->getClassCName(), (*it).id());
[8490]264      return true; }
265    }
[8190]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 */
276bool CollisionHandle::filterCollision(Collision* collision)
277{
[9869]278  std::vector<ClassID>::iterator it = this->targetList.begin();
[8190]279  for(; it < this->targetList.end(); it++)
280  {
[9235]281
282//     if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM))
283//     {
[9406]284//       PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it);
[9235]285//       if( collision->getEntityA() == this->owner) {
[9406]286//         PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
287//         collision->getEntityB()->getClassCName(), *it);
[9235]288//         if( collision->getEntityB()->isA((ClassID)(*it))) {
[9406]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);
[9235]291//         }
292//       }
293//       else {
[9406]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);
[9235]296//         if( collision->getEntityA()->isA((ClassID)(*it))) {
[9406]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);
[9235]299//         }
300//       }
301//     }
302
[8190]303    if( collision->getEntityA() == this->owner) {
[9869]304      if( collision->getEntityA()->isA(*it))
[8190]305        return true; }
306      else {
[9869]307        if( collision->getEntityB()->isA(*it))
[8190]308          return true; }
309  }
310
311  return false;
312}
313
314
315
316
317
318
319
Note: See TracBrowser for help on using the repository browser.