Changeset 8190 in orxonox.OLD for trunk/src/lib/collision_reaction
- Timestamp:
- Jun 7, 2006, 3:00:01 PM (19 years ago)
- Location:
- trunk/src/lib/collision_reaction
- Files:
-
- 5 edited
- 9 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/collision_reaction/Makefile.am
r7927 r8190 5 5 6 6 libORXcr_a_SOURCES = cr_engine.cc \ 7 collision_handle.cc 7 collision.cc \ 8 collision_event.cc \ 9 collision_handle.cc \ 10 collision_reaction.cc \ 11 cr_object_damage.cc 8 12 9 13 10 14 11 15 noinst_HEADERS = cr_engine.h \ 12 collision_handle.h 16 collision.h \ 17 collision_event.h \ 18 collision_handle.h \ 19 cr_defs.h \ 20 collision_reaction.h \ 21 cr_object_damage.h 13 22 -
trunk/src/lib/collision_reaction/collision_handle.cc
r7927 r8190 17 17 #include "collision_handle.h" 18 18 19 #include "world_entity.h" 20 21 #include "collision.h" 22 #include "collision_event.h" 23 #include "collision_reaction.h" 24 25 #include "cr_object_damage.h" 26 19 27 using namespace std; 20 28 … … 31 39 this->type = type; 32 40 41 this->bCollided = false; 42 this->bDispatched = false; 43 44 if( this->type == CREngine::CR_PHYSICS_STEP_BACK) 45 this->bContinuousPoll = false; 46 else 47 this->bContinuousPoll = true; 48 49 if( this->type == CREngine::CR_OBJECT_DAMAGE) 50 this->bStopOnFirstCollision = true; 51 else 52 this->bStopOnFirstCollision = false; 53 54 switch( type) 55 { 56 case CREngine::CR_OBJECT_DAMAGE: 57 this->collisionReaction = new CRObjectDamage(); 58 break; 59 default: 60 break; 61 }; 33 62 } 34 63 … … 41 70 // delete what has to be deleted here 42 71 } 72 73 /** 74 * restores the CollisionHandle to its initial state 75 */ 76 void CollisionHandle::reset() 77 { 78 this->flushCollisions(); 79 } 80 81 82 /** 83 * add more filter targets to this collision handle 84 * @param classID the classid to look for 85 */ 86 void CollisionHandle::addTarget(long target) 87 { 88 // make sure there is no dublicate 89 std::vector<long>::iterator it = this->targetList.begin(); 90 for( ; it < this->targetList.end(); it++) 91 if( (*it) == target) 92 return; 93 94 // add element 95 PRINTF(0)("addTarget: %i \n", target); 96 this->targetList.push_back(target); 97 } 98 99 100 /** 101 * registers a new Collision Object 102 * @param entityA WorldEntity A of the collision 103 * @param entityB WorldEntity B of the collision 104 * if a there is already a collision object with the same stats 105 * registration will be skipped and the last collision object is returned 106 */ 107 Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB) 108 { 109 //first get the collision object, multiple sources 110 Collision* c; 111 if( this->collisionList.empty() || 112 ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) { 113 c = CREngine::getInstance()->popCollisionObject(); 114 c->collide(entityA, entityB); 115 this->collisionList.push_back(c); 116 117 // now register it as a shared collision with the other collision entity 118 CollisionHandle* ch = entityB->getCollisionHandle(this->type); 119 if( ch != NULL) 120 ch->registerSharedCollision(c); 121 } 122 else 123 c = this->collisionList.back(); 124 125 return c; 126 } 127 128 129 /** 130 * register a Collision to the Collision handle. 131 * @param collision the collision object to register 132 * 133 * This is used for internal collision registration: sharing the collision objects between Collision Reactions 134 * Therefore dispatching it only once 135 */ 136 void CollisionHandle::registerSharedCollision(Collision* collision) 137 { 138 // fist check if we are listening for this Collision 139 if( !this->filterCollision(collision)) 140 return; 141 142 // set the state to not dispatched 143 this->bDispatched = false; 144 this->bCollided = true; 145 collision->setEntityBCollide(true); 146 147 this->collisionList.push_back(collision); 148 } 149 150 151 /** 152 * this is the function to be called on a collision event for this handle 153 * @param collision the collision objects containing all collision informations 154 */ 155 void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent) 156 { 157 if( !this->filterCollisionEvent(collisionEvent)) 158 return; 159 160 // set the state to not dispatched 161 this->bDispatched = false; 162 this->bCollided = true; 163 164 // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object 165 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB()); 166 c->setEntityACollide(true); 167 168 c->registerCollisionEvent(collisionEvent); 169 } 170 171 172 /** 173 * flushes the collision list 174 */ 175 void CollisionHandle::flushCollisions() 176 { 177 this->collisionList.clear(); 178 } 179 180 181 /** 182 * handles the collisions and react according to algorithm 183 */ 184 void CollisionHandle::handleCollisions() 185 { 186 // collision reaction calculations (for every collision there will be a reaction) 187 vector<Collision*>::iterator it = this->collisionList.begin(); 188 for(; it < this->collisionList.end(); it++) { 189 if( !(*it)->isDispatched()) 190 { 191 this->collisionReaction->reactToCollision(*it); 192 (*it)->flushCollisionEvents(); 193 } 194 } 195 196 // now set state to dispatched 197 this->bDispatched = true; 198 this->bCollided = false; 199 200 this->flushCollisions(); 201 } 202 203 204 /** 205 * filter out the CollisionEvents that are not wanted 206 * @param collisionEvent the collision event to filter 207 */ 208 bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent) 209 { 210 vector<long>::iterator it = this->targetList.begin(); 211 for(; it < this->targetList.end(); it++) 212 { 213 if( collisionEvent->getEntityA() == this->owner) { 214 if( collisionEvent->getEntityA()->isA((ClassID)(*it))) 215 return true; } 216 else { 217 if( collisionEvent->getEntityB()->isA((ClassID)(*it))) 218 return true; } 219 } 220 221 return false; 222 } 223 224 225 /** 226 * filter Collisions that are not wanted to be reacted to 227 * @param collision the collision object to filter 228 */ 229 bool CollisionHandle::filterCollision(Collision* collision) 230 { 231 vector<long>::iterator it = this->targetList.begin(); 232 for(; it < this->targetList.end(); it++) 233 { 234 if( collision->getEntityA() == this->owner) { 235 if( collision->getEntityA()->isA((ClassID)(*it))) 236 return true; } 237 else { 238 if( collision->getEntityB()->isA((ClassID)(*it))) 239 return true; } 240 } 241 242 return false; 243 } 244 245 246 247 248 249 250 -
trunk/src/lib/collision_reaction/collision_handle.h
r7927 r8190 11 11 12 12 #include <vector> 13 #include <list> 13 14 14 15 15 16 class Collision; 16 17 class WorldEntity; 18 class CollisionReaction; 17 19 18 // struct CRType;19 20 20 21 21 22 //! A class for defining collision reactions and storing events 22 class CollisionHandle : public BaseObject { 23 class CollisionHandle : public BaseObject 24 { 23 25 24 public: 25 CollisionHandle(WorldEntity* owner, CREngine::CRType type); 26 virtual ~CollisionHandle(); 26 public: 27 CollisionHandle(WorldEntity* owner, CREngine::CRType type); 28 virtual ~CollisionHandle(); 29 30 void reset(); 31 32 void addTarget(long target); 33 Collision* registerCollision(WorldEntity* entityA, WorldEntity* entityB); 34 void registerSharedCollision(Collision* collision); 35 void registerCollisionEvent(CollisionEvent* collisionEvent); 36 37 /** @returns true if regiestered some new collision events in this tick frame */ 38 inline bool isCollided() const { return this->bCollided; } 39 /** @returns true if this collision handle has already been dispatched */ 40 inline bool isDispatched() const { return this->bDispatched; } 41 /** @returns true if this handle should be pulled also if there are no collisions */ 42 inline bool isContinuousPoll() const { return this->bContinuousPoll; } 43 44 void handleCollisions(); 27 45 28 46 29 void addTarget(); 30 31 void registerCollision(Collision* collision); 32 33 void handleCollisions(); 47 private: 48 void flushCollisions(); 49 bool filterCollisionEvent(CollisionEvent* collisionEvent); 50 bool filterCollision(Collision* collision); 34 51 35 52 36 private:37 WorldEntity* owner; //!< the worldenity this reaction will be applied on38 CREngine::CRType type; //!< the reaction type39 53 40 bool bDispatched; //!< true if this handle has already been dispatched 41 bool bStopOnFirstCollision; //!< true if the cd of this object should be terminated after one match 54 private: 55 WorldEntity* owner; //!< the worldenity this reaction will be applied on 56 CREngine::CRType type; //!< the reaction type 42 57 43 std::vector<Collision*> collisionList; //!< a list full of collisions 44 std::vector<long> targetList; //!< a list of target classes for filtering 58 bool bContinuousPoll; //!< if this is true 59 bool bDispatched; //!< true if this handle has already been dispatched 60 bool bStopOnFirstCollision; //!< true if the cd of this object should be terminated after one match 61 bool bCollided; //!< true if the CollsionHandle has registered some new collisions 62 63 std::vector<Collision*> collisionList; //!< a list full of collisions 64 std::vector<long> targetList; //!< a list of target classes for filtering 65 66 CollisionReaction* collisionReaction; //!< reference to the collision reaction object 45 67 46 68 }; -
trunk/src/lib/collision_reaction/cr_engine.cc
r7927 r8190 16 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION 17 17 18 19 20 #include "collision.h" 21 #include "collision_event.h" 22 #include "collision_handle.h" 23 #include "cr_defs.h" 24 18 25 #include "cr_engine.h" 19 26 … … 25 32 */ 26 33 CREngine::CREngine () 34 : BaseObject() 27 35 { 28 36 this->setClassID(CL_CR_ENGINE, "CREngine"); 29 37 this->setName("CREngine"); 30 38 39 this->init(); 31 40 } 32 41 … … 42 51 { 43 52 CREngine::singletonRef = NULL; 53 54 if( this->collisionsUnused.size() != CR_MAX_COLLISIONS) 55 PRINTF(0)("CollisionReaction Error: Collision cache size missmatch: %i of %i\n", this->collisionsUnused.size(), CR_MAX_COLLISIONS); 56 if( this->collisionEventsUnused.size() != CR_MAX_COLLISION_EVENTS) 57 PRINTF(0)("CollisionReaction Error: CollisionEvent cache size missmatch: %i of %i\n", this->collisionEventsUnused.size(), CR_MAX_COLLISION_EVENTS); 58 59 this->reset(); 60 61 vector<Collision*>::iterator it1 = this->collisionsUnused.begin(); 62 for(; it1 < this->collisionsUnused.end(); it1++) 63 delete *it1; 64 vector<CollisionEvent*>::iterator it2 = this->collisionEventsUnused.begin(); 65 for(; it2 < this->collisionEventsUnused.end(); it2++) 66 delete *it2; 67 68 this->collisionsUnused.clear(); 69 this->collisionEventsUnused.clear(); 70 } 71 72 /** 73 * inits the CREngine to a working state 74 */ 75 void CREngine::init() 76 { 77 // create a list of Collision events (precaching) 78 for( int i = 0; i < CR_MAX_COLLISIONS; i++) 79 this->collisionsUnused.push_back(new Collision()); 80 for( int i = 0; i < CR_MAX_COLLISION_EVENTS; i++) 81 this->collisionEventsUnused.push_back(new CollisionEvent()); 44 82 } 45 83 46 84 85 /** 86 * flushes the CollisionHandles and restores the CREngine to the initial state 87 */ 88 void CREngine::reset() 89 { 90 // first clear all CollisionHandles 47 91 92 vector<CollisionHandle*>::iterator it = this->collisionHandles.begin(); 93 for(; it < this->collisionHandles.end(); it++) 94 { 95 (*it)->reset(); 96 delete *it; 97 } 48 98 49 CollisionHandle* CREngine::subscribeReaction(WorldEntity* owner, CRType type, int nrOfTargets, ...) 50 { 51 52 va_list itemlist; 53 va_start (itemlist, type); 54 // for (int i = 0; i < nrOfTargets; i++) 55 // this->targetList.push_back(va_arg(itemlist, int)); 56 va_end(itemlist); 99 this->collisionHandles.clear(); 57 100 } 58 101 59 102 103 /** 104 * subscribes a WorldEntity for a CollisionReaction 105 * @param owner: the WE to subscribe 106 * @param type: the type of collision reaction to perform 107 * @return the newly created CollisionHandle 108 */ 109 CollisionHandle* CREngine::subscribeReaction(WorldEntity* owner, CRType type) 110 { 111 CollisionHandle* ch = new CollisionHandle(owner, type); 112 this->collisionHandles.push_back(ch); 113 114 return ch; 115 } 60 116 61 117 118 /** 119 * unsubscribe reaction from the reaction list 120 * @param collisionHandle the CollisionHandle to remove 121 * @param returns true if worked collrectly 122 */ 123 bool CREngine::unsubscribeReaction(CollisionHandle* collisionHandle) 124 { 125 std::vector<CollisionHandle*>::iterator it; 126 for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++) 127 { 128 if( *it == collisionHandle) 129 { 130 this->collisionHandles.erase(it); 131 delete collisionHandle; 132 return true; 133 } 134 } 135 return false; 136 } 137 138 139 /** 140 * processes the collisions by calling the EventHandlers 141 */ 142 void CREngine::handleCollisions() 143 { 144 std::vector<CollisionHandle*>::iterator it; 145 for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++) 146 { 147 if( (*it)->isCollided() || (*it)->isContinuousPoll()) //does it have any collisions to report at all 148 { 149 (*it)->handleCollisions(); 150 } 151 } 152 this->flushCollisions(); 153 } 154 155 156 /** 157 * flushes all the collision lists and puts them to their initial state 158 */ 159 void CREngine::flushCollisions() 160 { 161 vector<Collision*>::iterator it1 = this->collisionsUsed.begin(); 162 for(; it1 < this->collisionsUsed.end(); it1++) 163 this->collisionsUnused.push_back(*it1); 164 165 vector<CollisionEvent*>::iterator it2 = this->collisionEventsUsed.begin(); 166 for(; it2 < this->collisionEventsUsed.end(); it2++) 167 this->collisionEventsUnused.push_back(*it2); 168 169 this->collisionsUsed.clear(); 170 this->collisionEventsUsed.clear(); 171 } 172 173 174 void CREngine::debug() 175 { 176 177 } 178 -
trunk/src/lib/collision_reaction/cr_engine.h
r8145 r8190 2 2 * @file cr_engine.h 3 3 * @brief The collision reaction engine, defining generic collision reactions to collision events 4 */ 4 * 5 * some parts of this module are tuned for efficiency. They are probably not self-explenatory anymore :D 6 * - Collision/ CollisionEvent objects recycling: This class contains a class of precached objects of these types 7 * they are used for fast registration of collision events: These objects can be get by the interface functions and 8 * are returned after one cycle automaticly by reseting the cached lists to its initial state. So do not wonder :D 9 */ 5 10 6 11 #ifndef _CR_ENGINE_ … … 8 13 9 14 #include "base_object.h" 10 #include <stdarg.h> 15 11 16 #include <vector> 12 17 … … 14 19 class CollisionHandle; 15 20 class Collision; 21 class CollisionEvent; 16 22 class WorldEntity; 17 23 … … 22 28 public: 23 29 typedef enum CRType { 24 CR_PHYSICS_MOMENTUM = 0, 25 CR_PHYSICS_GROUND, 26 CR_PHYSICS_GROUND_WALK, 30 CR_PHYSICS_MOMENTUM = 0, //!< physical reaction: conservervation of momentum 31 CR_PHYSICS_STEP_BACK, //!< physical reaction: just go to the last position without collisions 32 CR_PHYSICS_GROUND, //!< physical reaction: stand on the ground, no movement: simulating simple normal force away from the gravity force 33 CR_PHYSICS_GROUND_WALK, //!< physical reaction: walking on the ground (inkl. hills etc) 34 CR_PHYSICS_DAMAGE, //!< physical reaction: daling damage according to the object energy and their structural stability 27 35 28 CR_OBJECT_DAMAGE, 29 CR_OBJECT_PICKUP, 36 CR_OBJECT_DAMAGE, //!< object raction: deals damage according to the objects specific damage potential (like weapons, nukes, etc.) 37 CR_OBJECT_PICKUP, //!< object rection: calling the objects pickup functions, let them handle the collision (once!) 30 38 31 CR_VERTEX_TRAFO, 39 CR_VERTEX_TRAFO, //!< vertex trafo: transforming the vertex according to the damage 32 40 33 CR_SPECIAL_CALLBACK, 41 CR_SPECIAL_CALLBACK, //!< special: call a callback function 34 42 35 43 CR_NUMBER … … 39 47 40 48 /** @returns a Pointer to the only object of this Class */ 41 inline static CREngine* getInstance(void) { if (!singletonRef) singletonRef = new CREngine(); return singletonRef; }; 49 inline static CREngine* getInstance() { if (!singletonRef) singletonRef = new CREngine(); return singletonRef; }; 50 51 void reset(); 42 52 43 53 44 CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type , int nrOfTargets, ...);54 CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type); 45 55 46 bool unsubscribeReaction(WorldEntity* worldEntity);47 56 bool unsubscribeReaction(CollisionHandle* collisionHandle); 48 49 57 50 58 void handleCollisions(); 51 59 52 60 /** @returns an instance to a collision object. instead of creating new object this ones can be resycled */ 53 inline Collision* getCollisionObject() { /* return the first element of the cache list*/ } 54 /** @param collision: returns the Collision object back to the cache list */ 55 inline void putCollisionObject(Collision* collision) { this->cachedCollisions.push_back(collision); } 61 inline Collision* popCollisionObject() { 62 if( !this->collisionsUnused.empty()) { 63 this->collisionsUsed.push_back(this->collisionsUnused.back()); this->collisionsUnused.pop_back(); return this->collisionsUsed.back(); } else return NULL; } 64 65 66 /** @return an instanco of a CollisionEvent object. instead of creating a new object this ones can be used and resycled */ 67 inline CollisionEvent* popCollisionEventObject() { 68 if( !this->collisionEventsUnused.empty()) { 69 this->collisionEventsUsed.push_back(this->collisionEventsUnused.back()); this->collisionEventsUnused.pop_back(); return this->collisionEventsUsed.back(); } else return NULL; } 70 71 void debug(); 56 72 57 73 58 74 private: 59 CREngine(void); 75 CREngine(); 76 void init(); 77 78 void flushCollisions(); 60 79 61 80 62 81 private: 63 82 std::vector<CollisionHandle*> collisionHandles; //!< list with the collision handles 64 std::vector<Collision*> cachedCollisions; //!< a list of unused, cached collision events 83 84 std::vector<Collision*> collisionsUsed; //!< a list of used, cached collisions 85 std::vector<Collision*> collisionsUnused; //!< a list of unused, cached collisions 86 87 std::vector<CollisionEvent*> collisionEventsUsed; //!< a list of used, cached collision events 88 std::vector<CollisionEvent*> collisionEventsUnused; //!< a list of unused, cached collision events 65 89 66 90 static CREngine* singletonRef; //!< the reference to the CREngine object (singleton)
Note: See TracChangeset
for help on using the changeset viewer.