Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cr/src/lib/collision_reaction/collision_handle.cc @ 8129

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

cr: finished cleaning up the code, collision reaction now integrated and should either work or throw a sigfault :D

File size: 5.9 KB
RevLine 
[7841]1/*
2   orxonox - the future of 3D-vertical-scrollers
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
[8106]19#include "world_entity.h"
[7932]20
[7964]21#include "collision.h"
22#include "collision_event.h"
[8129]23#include "collision_reaction.h"
[7932]24
[8129]25#include "cr_object_damage.h"
26
[7841]27using namespace std;
28
29
30/**
31 * standard constructor
32 * @todo this constructor is not jet implemented - do it
33*/
[7927]34CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
[7841]35{
[7927]36  this->setClassID(CL_COLLISION_HANDLE, "CollisionHandle");
[7841]37
[7927]38  this->owner = owner;
39  this->type = type;
[8043]40
41  this->bCollided = false;
42  this->bDispatched = false;
[8129]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  };
[7841]62}
63
64
65/**
66 * standard deconstructor
67*/
68CollisionHandle::~CollisionHandle ()
69{
70  // delete what has to be deleted here
71}
[7932]72
[7946]73/**
74 * restores the CollisionHandle to its initial state
75 */
76void CollisionHandle::reset()
77{
78  this->flushCollisions();
79}
[7932]80
[7946]81
[7932]82/**
83 * add more filter targets to this collision handle
84 *  @param classID the classid to look for
85 */
[7989]86void CollisionHandle::addTarget(long target)
[7932]87{
88  // make sure there is no dublicate
[7999]89  std::vector<long>::iterator it = this->targetList.begin();
90  for( ; it < this->targetList.end(); it++)
91    if( (*it) == target)
92      return;
[7932]93
94  // add element
[7999]95   PRINTF(0)("addTarget: %i \n", target);
96   this->targetList.push_back(target);
[7932]97}
[7933]98
99
100/**
[7966]101 * registers a new Collision Object
[8124]102 *  @param entityA WorldEntity A of the collision
103 *  @param entityB WorldEntity B of the collision
[7967]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
[7966]106 */
107Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
108{
[7967]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  else
115    c = this->collisionList.back();
[7966]116
117  this->collisionList.push_back(c);
[7967]118
[8106]119  // now register it as a shared collision with the other collision entity
120  CollisionHandle* ch = entityB->getCollisionHandle(this->type);
[8124]121  if( ch != NULL)
[8107]122    ch->registerSharedCollision(c);
[8106]123
[7967]124  return c;
[7966]125}
126
127
128/**
[8099]129 * register a Collision to the Collision handle.
[8125]130 *  @param collision the collision object to register
131 *
[8099]132 * This is used for internal collision registration: sharing the collision objects between Collision Reactions
133 * Therefore dispatching it only once
134 */
[8106]135void CollisionHandle::registerSharedCollision(Collision* collision)
[8099]136{
[8125]137  // fist check if we are listening for this Collision
138  if( !this->filterCollision(collision))
139    return;
140
[8106]141  // set the state to not dispatched
142  this->bDispatched = false;
[8126]143  this->bCollided = true;
[8110]144  collision->setEntityBCollide(true);
[8099]145
[8106]146  this->collisionList.push_back(collision);
[8099]147}
148
149
150/**
[7933]151 * this is the function to be called on a collision event for this handle
152 *  @param collision the collision objects containing all collision informations
153 */
[7964]154void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
[7933]155{
[8109]156  if( !this->filterCollisionEvent(collisionEvent))
157    return;
158
[8029]159  // set the state to not dispatched
160  this->bDispatched = false;
[8126]161  this->bCollided = true;
[8029]162
[8124]163  // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
[7967]164 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
[8110]165 c->setEntityACollide(true);
166
[7967]167 c->registerCollisionEvent(collisionEvent);
[7933]168}
169
[7966]170
[7945]171/**
172 * flushes the collision list
173 */
174void CollisionHandle::flushCollisions()
175{
176  this->collisionList.clear();
177}
[7933]178
[7945]179
180/**
181 * handles the collisions and react according to algorithm
182 */
183void CollisionHandle::handleCollisions()
184{
[7969]185  // collision reaction calculations (for every collision there will be a reaction)
186  vector<Collision*>::iterator it = this->collisionList.begin();
[8126]187  for(; it < this->collisionList.end(); it++) {
[8129]188    this->collisionReaction->reactToCollision(*it);
[7969]189  }
[7945]190
191  // now set state to dispatched
192  this->bDispatched = true;
[7947]193  this->bCollided = false;
[8126]194
[7945]195  this->flushCollisions();
196}
[8109]197
198
199/**
200 * filter out the CollisionEvents that are not wanted
201 *  @param collisionEvent the collision event to filter
202 */
203bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
204{
205  vector<long>::iterator it = this->targetList.begin();
206  for(; it < this->targetList.end(); it++)
[8125]207  {
208    if( collisionEvent->getEntityA() == this->owner) {
209      if( collisionEvent->getEntityA()->isA((ClassID)(*it)))
210        return true; }
211    else {
212      if( collisionEvent->getEntityB()->isA((ClassID)(*it)))
213        return true; }
214  }
[8109]215
[8124]216  return false;
[8109]217}
218
219
[8125]220/**
221 * filter Collisions that are not wanted to be reacted to
222 *  @param collision the collision object to filter
223 */
224bool CollisionHandle::filterCollision(Collision* collision)
225{
226  vector<long>::iterator it = this->targetList.begin();
227  for(; it < this->targetList.end(); it++)
228  {
229    if( collision->getEntityA() == this->owner) {
230      if( collision->getEntityA()->isA((ClassID)(*it)))
231        return true; }
232      else {
233        if( collision->getEntityB()->isA((ClassID)(*it)))
234          return true; }
235  }
[8109]236
[8125]237  return false;
238}
[8109]239
240
241
242
243
[8125]244
245
Note: See TracBrowser for help on using the repository browser.