Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

cr: more bugs removed, more safty added

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