/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION #include "collision.h" #include "collision_event.h" #include "collision_handle.h" #include "cr_defs.h" #include "cr_engine.h" #include "debug.h" ObjectListDefinition(CREngine); /** * standard constructor */ CREngine::CREngine () : BaseObject() { this->registerObject(this, CREngine::_objectList); this->setName("CREngine"); this->init(); } /** * the singleton reference to this class */ CREngine* CREngine::singletonRef = NULL; /** @brief standard deconstructor */ CREngine::~CREngine () { CREngine::singletonRef = NULL; if( this->collisionsUnused.size() != CR_MAX_COLLISIONS) PRINTF(0)("CollisionReaction Error: Collision cache size missmatch: %i of %i\n", this->collisionsUnused.size(), CR_MAX_COLLISIONS); if( this->collisionEventsUnused.size() != CR_MAX_COLLISION_EVENTS) PRINTF(0)("CollisionReaction Error: CollisionEvent cache size missmatch: %i of %i\n", this->collisionEventsUnused.size(), CR_MAX_COLLISION_EVENTS); this->reset(); std::vector::iterator it1 = this->collisionsUnused.begin(); for(; it1 < this->collisionsUnused.end(); it1++) delete *it1; std::vector::iterator it2 = this->collisionEventsUnused.begin(); for(; it2 < this->collisionEventsUnused.end(); it2++) delete *it2; this->collisionsUnused.clear(); this->collisionEventsUnused.clear(); } /** * inits the CREngine to a working state */ void CREngine::init() { // create a list of Collision events (precaching) for( int i = 0; i < CR_MAX_COLLISIONS; i++) this->collisionsUnused.push_back(new Collision()); for( int i = 0; i < CR_MAX_COLLISION_EVENTS; i++) this->collisionEventsUnused.push_back(new CollisionEvent()); } /** * flushes the CollisionHandles and restores the CREngine to the initial state */ void CREngine::reset() { // first clear all CollisionHandles std::vector::iterator it = this->collisionHandles.begin(); for(; it < this->collisionHandles.end(); it++) { (*it)->reset(); delete *it; } this->collisionHandles.clear(); } /** * subscribes a WorldEntity for a CollisionReaction * @param owner: the WE to subscribe * @param type: the type of collision reaction to perform * @return the newly created CollisionHandle */ CollisionHandle* CREngine::subscribeReaction(WorldEntity* owner, CRType type) { CollisionHandle* ch = new CollisionHandle(owner, type); this->collisionHandles.push_back(ch); return ch; } /** * unsubscribe reaction from the reaction list * @param collisionHandle the CollisionHandle to remove * @param returns true if worked collrectly */ bool CREngine::unsubscribeReaction(CollisionHandle* collisionHandle) { std::vector::iterator it; for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++) { if( *it == collisionHandle) { this->collisionHandles.erase(it); delete collisionHandle; return true; } } return false; } /** * processes the collisions by calling the EventHandlers */ void CREngine::handleCollisions() { std::vector::iterator it; for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++) { if( !(*it)->isDispatched() || (*it)->isContinuousPoll()) //does it have any collisions to report at all { (*it)->handleCollisions(); } } this->flushCollisions(); } /** * flushes all the collision lists and puts them to their initial state */ void CREngine::flushCollisions() { std::vector::iterator it1 = this->collisionsUsed.begin(); for(; it1 < this->collisionsUsed.end(); it1++) this->collisionsUnused.push_back(*it1); std::vector::iterator it2 = this->collisionEventsUsed.begin(); for(; it2 < this->collisionEventsUsed.end(); it2++) this->collisionEventsUnused.push_back(*it2); this->collisionsUsed.clear(); this->collisionEventsUsed.clear(); } void CREngine::debug() { }