Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/collision_reaction/cr_engine.cc @ 10240

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

merged the collision reaction branche back to trunk

File size: 6.3 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   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
17
18
19#include "cr_object_damage.h"
20#include "cr_physics_full_walk.h"
21#include "cr_physics_ground_walk.h"
22
23#include "collision.h"
24#include "collision_event.h"
25#include "collision_filter.h"
26#include "collision_tube.h"
27#include "cr_defs.h"
28
29#include "cr_engine.h"
30
31#include "debug.h"
32
33namespace CoRe
34{
35
36  ObjectListDefinition(CREngine);
37
38
39  /**
40   * standard constructor
41   */
42  CREngine::CREngine ()
43      : BaseObject()
44  {
45    this->registerObject(this, CREngine::_objectList);
46    this->setName("CREngine");
47
48    this->init();
49  }
50
51  /**
52   *  the singleton reference to this class
53   */
54  CREngine* CREngine::singletonRef = NULL;
55
56  /**
57     @brief standard deconstructor
58   */
59  CREngine::~CREngine ()
60  {
61    CREngine::singletonRef = NULL;
62
63    if( this->collisionsUnused.size() != CR_MAX_COLLISIONS)
64      PRINTF(0)("CollisionReaction Error: Collision cache size missmatch: %i of %i\n", this->collisionsUnused.size(), CR_MAX_COLLISIONS);
65    if( this->collisionEventsUnused.size() != CR_MAX_COLLISION_EVENTS)
66      PRINTF(0)("CollisionReaction Error: CollisionEvent cache size missmatch: %i of %i\n", this->collisionEventsUnused.size(), CR_MAX_COLLISION_EVENTS);
67
68    this->reset();
69
70    CollisionIterator it1 = this->collisionsUnused.begin();
71    for(; it1 < this->collisionsUnused.end(); it1++)
72      delete *it1;
73    CollisionEventIterator it2 = this->collisionEventsUnused.begin();
74    for(; it2 < this->collisionEventsUnused.end(); it2++)
75      delete *it2;
76
77    this->collisionsUnused.clear();
78    this->collisionEventsUnused.clear();
79  }
80
81
82  /**
83   * inits the CREngine to a working state
84   */
85  void CREngine::init()
86  {
87    // precaching:
88    // create a list of Collisions and CollisionEvents for fast object recycling purposes
89    for( int i = 0; i < CR_MAX_COLLISIONS; i++)
90      this->collisionsUnused.push_back(new Collision());
91    for( int i = 0; i < CR_MAX_COLLISION_EVENTS; i++)
92      this->collisionEventsUnused.push_back(new CollisionEvent());
93
94
95    // push the collision reaction object on the list in the right order
96
97    // physical reactions
98    this->_reactionList[CREngine::CR_PHYSICS_MOMENTUM]      = NULL;
99    this->_reactionList[CREngine::CR_PHYSICS_STEP_BACK]     = NULL;
100    this->_reactionList[CREngine::CR_PHYSICS_GROUND_WALK]   = new CRPhysicsGroundWalk();
101    this->_reactionList[CREngine::CR_PHYSICS_FULL_WALK]     = new CRPhysicsFullWalk();
102    this->_reactionList[CREngine::CR_PHYSICS_DAMAGE]        = NULL;
103    // object based reactions
104    this->_reactionList[CREngine::CR_OBJECT_DAMAGE]         = new CRObjectDamage();
105    this->_reactionList[CREngine::CR_OBJECT_PICKUP]         = NULL;
106    // misc reactions
107    this->_reactionList[CREngine::CR_VERTEX_TRAFO]          = NULL;
108    this->_reactionList[CREngine::CR_SPECIAL_CALLBACK]      = NULL;
109  }
110
111
112  /**
113   * @returns an instance to a collision object. instead of creating new object this ones can be resycled
114   */
115  Collision* CREngine::popCollisionObject()
116  {
117    if( !this->collisionsUnused.empty())
118    {
119      this->collisionsUsed.push_back(this->collisionsUnused.back());
120      this->collisionsUnused.pop_back();
121      return this->collisionsUsed.back();
122    }
123    else
124    {
125      PRINTF(0)("There is no Collision Object left in the precache table, fatal error will cause segfault, change CR_MAX_COLLISIONS\n");
126      assert(false);
127      return NULL;
128    }
129  }
130
131
132  /**
133   * @return an instanco of a CollisionEvent object. instead of creating a new object this ones can be used and resycled
134   */
135  CollisionEvent* CREngine::popCollisionEventObject()
136  {
137    if( !this->collisionEventsUnused.empty())
138    {
139      this->collisionEventsUsed.push_back(this->collisionEventsUnused.back());
140      this->collisionEventsUnused.pop_back();
141      return this->collisionEventsUsed.back();
142    }
143    else
144    {
145      PRINTF(0)("There is no Collision Object left in the precache table, fatal error will cause segfault, change CR_MAX_COLLISION_EVENTS\n");
146      assert(false);
147      return NULL;
148    }
149  }
150
151
152  /**
153   * handles all collisions in registered in this tube
154   */
155  void CREngine::handleCollisions()
156  {
157    // for all collisions:
158    CollisionIterator ci = CollisionTube::getInstance()->begin();
159    for(; ci < CollisionTube::getInstance()->end(); ci++)
160    {
161      for( int i = CREngine::CR_PHYSICS_MOMENTUM; i < CREngine::CR_NUMBER; i++)
162      {
163        if( _reactionList[i] == NULL)
164          continue;
165
166//         PRINTF(0)("CR CHECK: collision between: %s, %s\n", (*ci)->getEntityA()->getClassName().c_str(), (*ci)->getEntityB()->getClassName().c_str());
167
168        // check if entity A or B is subscibed for this event
169        bool aReact = (*ci)->getEntityA()->isReactive(*(*ci)->getEntityB(), (CREngine::ReactionType)i);
170        bool bReact = (*ci)->getEntityB()->isReactive(*(*ci)->getEntityA(), (CREngine::ReactionType)i);
171
172        // store this information
173        (*ci)->setEntityACollide(aReact);
174        (*ci)->setEntityBCollide(bReact);
175
176        // and execute the reaction
177        if(  aReact || bReact)
178        {
179          this->_reactionList[i]->reactToCollision(*ci);
180          //PRINTF(0)("executing reaction: %s, between %s - %s\n", this->_reactionList[i]->getClassName().c_str(), (*ci)->getEntityA()->getClassName().c_str(), (*ci)->getEntityB()->getClassName().c_str());
181        }
182      }
183      (*ci)->reset();
184    }
185
186    this->reset();
187  }
188
189
190  /**
191   * flushes all the collision lists and puts them to their initial state
192   */
193  void CREngine::reset()
194  {
195    CollisionIterator it1 = this->collisionsUsed.begin();
196    for(; it1 < this->collisionsUsed.end(); it1++)
197      this->collisionsUnused.push_back(*it1);
198
199    CollisionEventIterator it2 = this->collisionEventsUsed.begin();
200    for(; it2 < this->collisionEventsUsed.end(); it2++)
201      this->collisionEventsUnused.push_back(*it2);
202
203    this->collisionsUsed.clear();
204    this->collisionEventsUsed.clear();
205
206    CollisionTube::getInstance()->reset();
207  }
208
209
210  void CREngine::debug()
211  {
212  }
213
214}
Note: See TracBrowser for help on using the repository browser.