| [7819] | 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 |  | 
|---|
| [8190] | 18 |  | 
|---|
| [10013] | 19 | #include "cr_object_damage.h" | 
|---|
 | 20 | #include "cr_physics_full_walk.h" | 
|---|
 | 21 | #include "cr_physics_ground_walk.h" | 
|---|
| [8190] | 22 |  | 
|---|
 | 23 | #include "collision.h" | 
|---|
 | 24 | #include "collision_event.h" | 
|---|
| [10013] | 25 | #include "collision_filter.h" | 
|---|
 | 26 | #include "collision_tube.h" | 
|---|
| [8190] | 27 | #include "cr_defs.h" | 
|---|
 | 28 |  | 
|---|
| [7819] | 29 | #include "cr_engine.h" | 
|---|
 | 30 |  | 
|---|
| [8362] | 31 | #include "debug.h" | 
|---|
 | 32 |  | 
|---|
| [10013] | 33 | namespace CoRe | 
|---|
 | 34 | { | 
|---|
| [7819] | 35 |  | 
|---|
| [10013] | 36 |   ObjectListDefinition(CREngine); | 
|---|
| [7819] | 37 |  | 
|---|
 | 38 |  | 
|---|
| [10013] | 39 |   /** | 
|---|
 | 40 |    * standard constructor | 
|---|
 | 41 |    */ | 
|---|
 | 42 |   CREngine::CREngine () | 
|---|
 | 43 |       : BaseObject() | 
|---|
 | 44 |   { | 
|---|
 | 45 |     this->registerObject(this, CREngine::_objectList); | 
|---|
 | 46 |     this->setName("CREngine"); | 
|---|
| [7819] | 47 |  | 
|---|
| [10013] | 48 |     this->init(); | 
|---|
 | 49 |   } | 
|---|
| [7819] | 50 |  | 
|---|
| [10013] | 51 |   /** | 
|---|
 | 52 |    *  the singleton reference to this class | 
|---|
 | 53 |    */ | 
|---|
 | 54 |   CREngine* CREngine::singletonRef = NULL; | 
|---|
| [8190] | 55 |  | 
|---|
| [10013] | 56 |   /** | 
|---|
 | 57 |      @brief standard deconstructor | 
|---|
 | 58 |    */ | 
|---|
 | 59 |   CREngine::~CREngine () | 
|---|
 | 60 |   { | 
|---|
 | 61 |     CREngine::singletonRef = NULL; | 
|---|
| [8190] | 62 |  | 
|---|
| [10013] | 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); | 
|---|
| [8190] | 67 |  | 
|---|
| [10013] | 68 |     this->reset(); | 
|---|
| [8190] | 69 |  | 
|---|
| [10013] | 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; | 
|---|
| [7841] | 76 |  | 
|---|
| [10013] | 77 |     this->collisionsUnused.clear(); | 
|---|
 | 78 |     this->collisionEventsUnused.clear(); | 
|---|
 | 79 |   } | 
|---|
| [7841] | 80 |  | 
|---|
 | 81 |  | 
|---|
| [10013] | 82 |   /** | 
|---|
 | 83 |    * inits the CREngine to a working state | 
|---|
 | 84 |    */ | 
|---|
 | 85 |   void CREngine::init() | 
|---|
| [8190] | 86 |   { | 
|---|
| [10013] | 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()); | 
|---|
| [8190] | 93 |  | 
|---|
 | 94 |  | 
|---|
| [10013] | 95 |     // push the collision reaction object on the list in the right order | 
|---|
| [8190] | 96 |  | 
|---|
| [10013] | 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 |   } | 
|---|
| [7927] | 110 |  | 
|---|
| [7841] | 111 |  | 
|---|
| [10013] | 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 |   } | 
|---|
| [7841] | 130 |  | 
|---|
| [10013] | 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(); | 
|---|
| [8190] | 142 |     } | 
|---|
| [10013] | 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 |     } | 
|---|
| [8190] | 149 |   } | 
|---|
| [7841] | 150 |  | 
|---|
| [7865] | 151 |  | 
|---|
| [10013] | 152 |   /** | 
|---|
 | 153 |    * handles all collisions in registered in this tube | 
|---|
 | 154 |    */ | 
|---|
 | 155 |   void CREngine::handleCollisions() | 
|---|
| [8190] | 156 |   { | 
|---|
| [10013] | 157 |     // for all collisions: | 
|---|
 | 158 |     CollisionIterator ci = CollisionTube::getInstance()->begin(); | 
|---|
 | 159 |     for(; ci < CollisionTube::getInstance()->end(); ci++) | 
|---|
| [8190] | 160 |     { | 
|---|
| [10013] | 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(); | 
|---|
| [8190] | 184 |     } | 
|---|
| [10013] | 185 |  | 
|---|
 | 186 |     this->reset(); | 
|---|
| [8190] | 187 |   } | 
|---|
 | 188 |  | 
|---|
 | 189 |  | 
|---|
| [10013] | 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); | 
|---|
| [8190] | 198 |  | 
|---|
| [10013] | 199 |     CollisionEventIterator it2 = this->collisionEventsUsed.begin(); | 
|---|
 | 200 |     for(; it2 < this->collisionEventsUsed.end(); it2++) | 
|---|
 | 201 |       this->collisionEventsUnused.push_back(*it2); | 
|---|
| [8190] | 202 |  | 
|---|
| [10013] | 203 |     this->collisionsUsed.clear(); | 
|---|
 | 204 |     this->collisionEventsUsed.clear(); | 
|---|
| [8190] | 205 |  | 
|---|
| [10013] | 206 |     CollisionTube::getInstance()->reset(); | 
|---|
 | 207 |   } | 
|---|
| [8190] | 208 |  | 
|---|
 | 209 |  | 
|---|
| [10013] | 210 |   void CREngine::debug() | 
|---|
 | 211 |   { | 
|---|
 | 212 |   } | 
|---|
 | 213 |  | 
|---|
| [8190] | 214 | } | 
|---|