/*! * @file cr_engine.h * @brief The collision reaction engine, defining generic collision reactions to collision events * * some parts of this module are tuned for efficiency. They are probably not self-explenatory anymore :D * - Collision/ CollisionEvent objects recycling: This class contains a class of precached objects of these types * they are used for fast registration of collision events: These objects can be get by the interface functions and * are returned after one cycle automaticly by reseting the cached lists to its initial state. So do not wonder :D */ #ifndef _CR_ENGINE_ #define _CR_ENGINE_ #include "base_object.h" #include // FORWARD DECLARATION class CollisionHandle; class Collision; class CollisionEvent; class WorldEntity; //! A default singleton class. class CREngine : public BaseObject { public: typedef enum CRType { CR_PHYSICS_MOMENTUM = 0, //!< physical reaction: conservervation of momentum CR_PHYSICS_STEP_BACK, //!< physical reaction: just go to the last position without collisions CR_PHYSICS_GROUND_WALK, //!< physical reaction: stand on the ground, no movement: simulating simple normal force away from the gravity force CR_PHYSICS_FULL_WALK, //!< physical reaction: walking on the ground (inkl. hills etc) CR_PHYSICS_DAMAGE, //!< physical reaction: daling damage according to the object energy and their structural stability CR_OBJECT_DAMAGE, //!< object raction: deals damage according to the objects specific damage potential (like weapons, nukes, etc.) CR_OBJECT_PICKUP, //!< object rection: calling the objects pickup functions, let them handle the collision (once!) CR_VERTEX_TRAFO, //!< vertex trafo: transforming the vertex according to the damage CR_SPECIAL_CALLBACK, //!< special: call a callback function CR_NUMBER }; virtual ~CREngine(void); /** @returns a Pointer to the only object of this Class */ inline static CREngine* getInstance() { if (!singletonRef) singletonRef = new CREngine(); return singletonRef; }; void reset(); CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type); bool unsubscribeReaction(CollisionHandle* collisionHandle); void handleCollisions(); /** @returns an instance to a collision object. instead of creating new object this ones can be resycled */ inline Collision* popCollisionObject() { if( !this->collisionsUnused.empty()) { this->collisionsUsed.push_back(this->collisionsUnused.back()); this->collisionsUnused.pop_back(); return this->collisionsUsed.back(); } else return NULL; } /** @return an instanco of a CollisionEvent object. instead of creating a new object this ones can be used and resycled */ inline CollisionEvent* popCollisionEventObject() { if( !this->collisionEventsUnused.empty()) { this->collisionEventsUsed.push_back(this->collisionEventsUnused.back()); this->collisionEventsUnused.pop_back(); return this->collisionEventsUsed.back(); } else return NULL; } void debug(); private: CREngine(); void init(); void flushCollisions(); private: std::vector collisionHandles; //!< list with the collision handles std::vector collisionsUsed; //!< a list of used, cached collisions std::vector collisionsUnused; //!< a list of unused, cached collisions std::vector collisionEventsUsed; //!< a list of used, cached collision events std::vector collisionEventsUnused; //!< a list of unused, cached collision events static CREngine* singletonRef; //!< the reference to the CREngine object (singleton) }; #endif /* _CR_ENGINE_ */