Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

bsp: collision detection doesn't work at all

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