/*! * @file collision_tube.h * * collision tube collects all collisions from all entities * * The collision events are saved in the _collisionList vector in a fixed hirarchy: a collision is defined by the world entities * that collide. For each collision there is an entry in _collisionList. Each collision itself again contains collision events which are * defined as collisions between the boundibg volumes (BV) of the world entities. This could look like this: * * - Collision (WorldEntity_i <=> WorldEntity_j) * +- CollisionEvent( some BV <=> some other BV) * +- CollisionEvent( some BV <=> some other BV) * - Collision (WorldEntity_k <=> WorldEntity_l) * +- CollisionEvent( some BV <=> some other BV) * +- CollisionEvent( some BV <=> some other BV) * +- CollisionEvent( some BV <=> some other BV) * +- CollisionEvent( some BV <=> some other BV) * - ... etc ... * * * When the collisions are processed by the handleCollision() function each collision pair is checked for their reactions (since each * WorldEntity can define several reactions to a collision). After all the reactions are calculated and applied the collision object is * put back. */ #ifndef _COLLISION_TUBE_H #define _COLLISION_TUBE_H #include "base_object.h" #include "cr_engine.h" #include "world_entity.h" #include "vector.h" #include class Collision; class WorldEntity; class BoundingVolume; namespace CoRe { class CollisionReaction; //! A class containing all CollisionEvents (structured as defined in the file doxygen tags) class CollisionTube : public BaseObject { ObjectListDeclaration(CollisionTube); typedef std::vector::iterator CollisionIterator; typedef std::vector CollisionVector; /* Constructor/Deconstructor/Singleton Interface */ public: inline static CollisionTube* getInstance() { if( !singletonRef) singletonRef = new CollisionTube(); return singletonRef; } virtual ~CollisionTube(); private: CollisionTube(); CollisionTube(const CollisionTube& tube) {} static CollisionTube* singletonRef; //!< the singleton instance /* Collision Handling */ public: void registerCollisionEvent(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB); void registerCollisionEvent(CREngine::CollisionType type, WorldEntity* entity, WorldEntity* groundEntity, const Vector& normal, const Vector& position, bool bInWall = false); Collision* registerCollision(WorldEntity* entityA, WorldEntity* entityB); void reset(); /** @returns an iterator pointing to the beginning of the list */ CollisionIterator begin() { return this->_collisionList.begin(); } /** @returns an iterator pointing to the end of the list */ CollisionIterator end() { return this->_collisionList.end(); } private: CollisionVector _collisionList; //!< the list of collisions since the last processing /* Misc State Informations */ public: /** @returns true if at least one of both WorldEntities are subscribed for a collision reaction */ inline bool isReactive(const WorldEntity& entityA, const WorldEntity& entityB) const { return (entityA.isReactive(entityB) && entityB.isReactive(entityA)); } }; } #endif /* _COLLISION_TUBE_H */