Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/bsp_model/src/lib/collision_reaction/collision_handle.cc @ 8420

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

bsp: better debug output

File size: 6.9 KB
Line 
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:
12   main-programmer: Patrick Boenzli
13*/
14
15#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
16
17#include "collision_handle.h"
18
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#include "cr_physics_ground_walk.h"
27
28using namespace std;
29
30
31/**
32 * standard constructor
33 * @todo this constructor is not jet implemented - do it
34*/
35CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
36{
37  this->setClassID(CL_COLLISION_HANDLE, "CollisionHandle");
38
39  this->owner = owner;
40  this->type = type;
41
42  this->bCollided = false;
43  this->bDispatched = true;
44
45  this->collisionReaction = NULL;
46  this->bContinuousPoll = false;
47  this->bStopOnFirstCollision = false;
48
49
50  switch( type)
51  {
52    case CREngine::CR_PHYSICS_STEP_BACK:
53//       this->collisionReaction = new CRPhysicsGroundWalk();
54      this->bContinuousPoll = true;
55      break;
56    case CREngine::CR_PHYSICS_GROUND_WALK:
57      this->collisionReaction = new CRPhysicsGroundWalk();
58      this->bContinuousPoll = true;
59      break;
60    case CREngine::CR_OBJECT_DAMAGE:
61      this->collisionReaction = new CRObjectDamage();
62      this->bStopOnFirstCollision = true;
63      break;
64    default:
65      break;
66  };
67}
68
69
70/**
71 * standard deconstructor
72*/
73CollisionHandle::~CollisionHandle ()
74{
75  // delete what has to be deleted here
76  if( this->collisionReaction != NULL)
77    delete this->collisionReaction;
78}
79
80/**
81 * restores the CollisionHandle to its initial state
82 */
83void CollisionHandle::reset()
84{
85  this->flushCollisions();
86}
87
88
89/**
90 * add more filter targets to this collision handle
91 *  @param classID the classid to look for
92 */
93void CollisionHandle::addTarget(long target)
94{
95  // make sure there is no dublicate
96  std::vector<long>::iterator it = this->targetList.begin();
97  for( ; it < this->targetList.end(); it++)
98    if( (*it) == target)
99      return;
100
101  // add element
102   PRINTF(0)("addTarget: %i \n", target);
103   this->targetList.push_back(target);
104}
105
106
107/**
108 * registers a new Collision Object
109 *  @param entityA WorldEntity A of the collision
110 *  @param entityB WorldEntity B of the collision
111 * if a there is already a collision object with the same stats
112 * registration will be skipped and the last collision object is returned
113 */
114Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
115{
116  //first get the collision object, multiple sources
117  Collision* c;
118  if( this->collisionList.empty() ||
119      ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) {
120    c = CREngine::getInstance()->popCollisionObject();
121    c->collide(entityA, entityB);
122    this->collisionList.push_back(c);
123
124    // now register it as a shared collision with the other collision entity
125    CollisionHandle* ch = entityB->getCollisionHandle(this->type);
126    if( ch != NULL)
127      ch->registerSharedCollision(c);
128  }
129  else
130    c = this->collisionList.back();
131
132  return c;
133}
134
135
136/**
137 * register a Collision to the Collision handle.
138 *  @param collision the collision object to register
139 *
140 * This is used for internal collision registration: sharing the collision objects between Collision Reactions
141 * Therefore dispatching it only once
142 */
143void CollisionHandle::registerSharedCollision(Collision* collision)
144{
145  // fist check if we are listening for this Collision
146  if( !this->filterCollision(collision))
147    return;
148
149  // set the state to not dispatched
150  this->bDispatched = false;
151  this->bCollided = true;
152  collision->setEntityBCollide(true);
153
154  this->collisionList.push_back(collision);
155}
156
157
158/**
159 * this is the function to be called on a collision event for this handle
160 *  @param collision the collision objects containing all collision informations
161 */
162void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
163{
164  if( !this->filterCollisionEvent(collisionEvent))
165    return;
166
167  // set the state to not dispatched
168  this->bDispatched = false;
169  this->bCollided = true;
170
171  // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
172 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
173 c->setEntityACollide(true);
174
175 c->registerCollisionEvent(collisionEvent);
176 PRINTF(0)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassName(), collisionEvent->getEntityB()->getClassName());
177}
178
179
180/**
181 * flushes the collision list
182 */
183void CollisionHandle::flushCollisions()
184{
185  this->collisionList.clear();
186}
187
188
189/**
190 * handles the collisions and react according to algorithm
191 */
192void CollisionHandle::handleCollisions()
193{
194  // if continuous poll poll the reaction
195  if( this->bContinuousPoll && !this->bCollided)
196  {
197    this->collisionReaction->update(this->owner);
198    return;
199  }
200
201  // collision reaction calculations (for every collision there will be a reaction)
202  vector<Collision*>::iterator it = this->collisionList.begin();
203  for(; it < this->collisionList.end(); it++) {
204    if( !(*it)->isDispatched())
205    {
206      this->collisionReaction->reactToCollision(*it);
207      (*it)->flushCollisionEvents();
208    }
209  }
210
211  // now set state to dispatched
212  this->bDispatched = true;
213  this->bCollided = false;
214
215  this->flushCollisions();
216}
217
218
219/**
220 * filter out the CollisionEvents that are not wanted
221 *  @param collisionEvent the collision event to filter
222 */
223bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
224{
225  vector<long>::iterator it = this->targetList.begin();
226  for(; it < this->targetList.end(); it++)
227  {
228    if( collisionEvent->getEntityA() == this->owner) {
229      if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
230        PRINTF(0)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassName(),
231                  collisionEvent->getEntityB()->getClassName(), *it);
232        return true; }
233    }
234    else {
235      if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
236        PRINTF(0)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassName(),
237                  collisionEvent->getEntityA()->getClassName(), *it);
238      return true; }
239    }
240  }
241
242  return false;
243}
244
245
246/**
247 * filter Collisions that are not wanted to be reacted to
248 *  @param collision the collision object to filter
249 */
250bool CollisionHandle::filterCollision(Collision* collision)
251{
252  vector<long>::iterator it = this->targetList.begin();
253  for(; it < this->targetList.end(); it++)
254  {
255    if( collision->getEntityA() == this->owner) {
256      if( collision->getEntityA()->isA((ClassID)(*it)))
257        return true; }
258      else {
259        if( collision->getEntityB()->isA((ClassID)(*it)))
260          return true; }
261  }
262
263  return false;
264}
265
266
267
268
269
270
271
Note: See TracBrowser for help on using the repository browser.