Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/atmospheric_engine/src/lib/collision_reaction/collision_handle.cc @ 8478

Last change on this file since 8478 was 8478, checked in by amaechler, 18 years ago

at: soundloops broken, counter push

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