/* orxonox - the future of 3D-vertical-scrollersf 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 */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION #include "collision_filter.h" #include "world_entity.h" #include "collision.h" #include "collision_event.h" #include "debug.h" #include namespace CoRe { ObjectListDefinition(CollisionFilter); /** * standard constructor * @todo this constructor is not jet implemented - do it */ CollisionFilter::CollisionFilter (WorldEntity* owner) { this->registerObject(this, CollisionFilter::_objectList); this->_owner = owner; this->_bContinuousPoll = false; this->_bStopOnFirstCollision = false; this->_bReactive = false; } /** * standard deconstructor */ CollisionFilter::~CollisionFilter () { this->unsubscribeReactions(); } /** * subscribe reaction */ void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1) { // check if its a valid type if( likely(this->validCRType( type))) { //check if this class isn't already registered TargetIterator it = this->_filters[type].begin(); for(; it != this->_filters[type].end(); it++) { if( unlikely(*it == target1)) return; } // so subscribe the reaction finally this->_filters[type].push_back(target1); this->_bReactive = true; } } /** * subscribe for a reaction */ void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2) { this->subscribeReaction(type, target1); this->subscribeReaction(type, target2); } /** * subscribe for a reaction */ void CollisionFilter::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2, const ClassID& target3) { this->subscribeReaction(type, target1); this->subscribeReaction(type, target2); this->subscribeReaction(type, target3); } /** * unsubscribe from a specific collision reaction */ void CollisionFilter::unsubscribeReaction(CoRe::CREngine::ReactionType type) { if( likely(this->validCRType( type))) this->_filters[type].clear(); for( int i = 0; i < CREngine::CR_NUMBER; i++) { if( this->_filters[i].size() > 0) { this->_bReactive = true; break; } } } /** * unsubscribe from all collision reactions */ void CollisionFilter::unsubscribeReactions() { for(int i = 0; i < CREngine::CR_NUMBER; i++) this->_filters[i].clear(); this->_bReactive = false; } /** * tests if the owner WorldEntity is listening to collisions from another specif WorldEntity entity * @param entity WorldEntity to test against * * This is the most important interface function of this class: it performs a check and returns true * if the WorldEntity entity is actualy responsive for a certain other WorldEntity */ bool CollisionFilter::operator()(const WorldEntity& entity) const { // PRINTF(0)("operator()(const WorldEntity& entity)\n"); // if there are no installed criterions just ommit and return if( !this->isReactive()) return false; // goes through all registered filter criterions and looks for matches for( int i = 0; i < CREngine::CR_NUMBER; i++ ) { TargetIteratorConst it = this->_filters[i].begin(); for(; it != this->_filters[i].end(); it++ ) { // PRINTF(0)("[%i] check %s is a %s?\n", i, entity.getClassName().c_str(), (*it).name().c_str()); if( unlikely(entity.isA(*it) ) ) return true; } } return false; } /** * tests if the owner WorldEntity is listening to collisions from another specif WorldEntity entity * @param entity WorldEntity to test against * * This is the most important interface function of this class: it performs a check and returns true * if the WorldEntity entity is actualy responsive for a certain other WorldEntity */ bool CollisionFilter::operator()(const WorldEntity& entity, const CREngine::ReactionType type) const { assert(&entity != NULL); // PRINTF(0)("operator()(const WorldEntity& entity, const CREngine::ReactionType type)\n"); // if there are no installed criterions just omit and return if( !this->isReactive()) return false; // goes through all registered filter criterions and looks for matches TargetIteratorConst it = this->_filters[type].begin(); for(; it != this->_filters[type].end(); it++ ) { // PRINTF(0)("size: %i - %s is a %s?\n", this->_filters[type].size(), entity.getClassName().c_str(), (*it).name().c_str()); if( entity.isA(*it)) return true; } return false; } } // namespace end