Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8372 was 8362, checked in by bensch, 18 years ago

orxonox/trunk: removed stupid included in base_object.h
this should lead to faster compile-times

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