Changeset 9889 in orxonox.OLD for branches/coll_rect/src/lib/collision_reaction/collision_handle.cc
- Timestamp:
- Oct 13, 2006, 3:57:44 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/coll_rect/src/lib/collision_reaction/collision_handle.cc
r9869 r9889 29 29 #include "debug.h" 30 30 31 32 ObjectListDefinition(CollisionHandle); 33 34 /** 35 * standard constructor 36 * @todo this constructor is not jet implemented - do it 37 */ 38 CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type) 31 namespace CoRe 39 32 { 40 this->registerObject(this, CollisionHandle::_objectList); 41 42 this->owner = owner; 43 this->type = type; 44 45 this->bCollided = false; 46 this->bDispatched = true; 47 48 this->collisionReaction = NULL; 49 this->bContinuousPoll = false; 50 this->bStopOnFirstCollision = false; 51 52 53 switch( type) 54 { 55 case CREngine::CR_PHYSICS_FULL_WALK: 56 this->collisionReaction = new CRPhysicsFullWalk(); 57 this->bContinuousPoll = true; 58 break; 59 case CREngine::CR_PHYSICS_GROUND_WALK: 60 this->collisionReaction = new CRPhysicsGroundWalk(); 61 this->bContinuousPoll = true; 62 break; 63 case CREngine::CR_OBJECT_DAMAGE: 64 this->collisionReaction = new CRObjectDamage(); 65 this->bStopOnFirstCollision = true; 66 break; 67 default: 68 break; 69 }; 33 34 ObjectListDefinition(CollisionHandle); 35 36 /** 37 * standard constructor 38 * @todo this constructor is not jet implemented - do it 39 */ 40 CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type) 41 { 42 this->registerObject(this, CollisionHandle::_objectList); 43 44 this->owner = owner; 45 this->type = type; 46 47 this->bCollided = false; 48 this->bDispatched = true; 49 50 this->collisionReaction = NULL; 51 this->bContinuousPoll = false; 52 this->bStopOnFirstCollision = false; 53 54 55 switch( type) 56 { 57 case CREngine::CR_PHYSICS_FULL_WALK: 58 this->collisionReaction = new CRPhysicsFullWalk(); 59 this->bContinuousPoll = true; 60 break; 61 case CREngine::CR_PHYSICS_GROUND_WALK: 62 this->collisionReaction = new CRPhysicsGroundWalk(); 63 this->bContinuousPoll = true; 64 break; 65 case CREngine::CR_OBJECT_DAMAGE: 66 this->collisionReaction = new CRObjectDamage(); 67 this->bStopOnFirstCollision = true; 68 break; 69 default: 70 break; 71 }; 72 } 73 74 75 /** 76 * standard deconstructor 77 */ 78 CollisionHandle::~CollisionHandle () 79 { 80 // delete what has to be deleted here 81 if( this->collisionReaction != NULL) 82 delete this->collisionReaction; 83 } 84 85 /** 86 * restores the CollisionHandle to its initial state 87 */ 88 void CollisionHandle::reset() 89 { 90 this->flushCollisions(); 91 } 92 93 94 /** 95 * add more filter targets to this collision handle 96 * @param classID the classid to look for 97 */ 98 void CollisionHandle::addTarget(const ClassID& target) 99 { 100 // make sure there is no dublicate 101 std::vector<ClassID>::iterator it = this->targetList.begin(); 102 for( ; it < this->targetList.end(); it++) 103 if( (*it) == target) 104 return; 105 106 107 // add element 108 this->targetList.push_back(target); 109 PRINTF(5)("addTarget: %i \n", target.id()); 110 } 111 112 113 /** 114 * registers a new Collision Object 115 * @param entityA WorldEntity A of the collision 116 * @param entityB WorldEntity B of the collision 117 * if a there is already a collision object with the same stats 118 * registration will be skipped and the last collision object is returned 119 */ 120 Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB) 121 { 122 //first get the collision object, multiple sources 123 Collision* c; 124 if( this->collisionList.empty() || 125 ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) 126 { 127 c = CREngine::getInstance()->popCollisionObject(); 128 c->collide(entityA, entityB); 129 this->collisionList.push_back(c); 130 131 // now register it as a shared collision with the other collision entity 132 CollisionHandle* ch = entityB->getCollisionHandle(this->type); 133 if( ch != NULL) 134 ch->registerSharedCollision(c); 135 } 136 else 137 c = this->collisionList.back(); 138 139 return c; 140 } 141 142 143 /** 144 * register a Collision to the Collision handle. 145 * @param collision the collision object to register 146 * 147 * This is used for internal collision registration: sharing the collision objects between Collision Reactions 148 * Therefore dispatching it only once 149 */ 150 void CollisionHandle::registerSharedCollision(Collision* collision) 151 { 152 // fist check if we are listening for this Collision 153 if( !this->filterCollision(collision)) 154 return; 155 156 // set the state to not dispatched 157 this->bDispatched = false; 158 this->bCollided = true; 159 collision->setEntityBCollide(true); 160 161 this->collisionList.push_back(collision); 162 } 163 164 165 /** 166 * this is the function to be called on a collision event for this handle 167 * @param collision the collision objects containing all collision informations 168 */ 169 void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent) 170 { 171 if( !this->filterCollisionEvent(collisionEvent)) 172 return; 173 174 // set the state to not dispatched 175 this->bDispatched = false; 176 this->bCollided = true; 177 178 // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object 179 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB()); 180 c->setEntityACollide(true); 181 182 c->registerCollisionEvent(collisionEvent); 183 PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName()); 184 } 185 186 187 /** 188 * flushes the collision list 189 */ 190 void CollisionHandle::flushCollisions() 191 { 192 this->collisionList.clear(); 193 } 194 195 196 /** 197 * handles the collisions and react according to algorithm 198 */ 199 void CollisionHandle::handleCollisions() 200 { 201 // if continuous poll poll the reaction 202 if( this->bContinuousPoll && !this->bCollided) 203 { 204 this->collisionReaction->update(this->owner); 205 return; 206 } 207 208 // collision reaction calculations (for every collision there will be a reaction) 209 std::vector<Collision*>::iterator it = this->collisionList.begin(); 210 for(; it < this->collisionList.end(); it++) 211 { 212 if( !(*it)->isDispatched()) 213 { 214 this->collisionReaction->reactToCollision(*it); 215 (*it)->flushCollisionEvents(); 216 } 217 } 218 219 // now set state to dispatched 220 this->bDispatched = true; 221 this->bCollided = false; 222 223 this->flushCollisions(); 224 } 225 226 227 /** 228 * filter out the CollisionEvents that are not wanted 229 * @param collisionEvent the collision event to filter 230 */ 231 bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent) 232 { 233 std::vector<ClassID>::iterator it = this->targetList.begin(); 234 for(; it < this->targetList.end(); it++) 235 { 236 // if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM)) 237 // { 238 // PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it); 239 // if( collisionEvent->getEntityA() == this->owner) { 240 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 241 // collisionEvent->getEntityB()->getClassCName(), *it); 242 // if( collisionEvent->getEntityB()->isA((ClassID)(*it))) { 243 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 244 // collisionEvent->getEntityB()->getClassCName(), *it); 245 // } 246 // } 247 // else { 248 // PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 249 // collisionEvent->getEntityB()->getClassCName(), *it); 250 // if( collisionEvent->getEntityA()->isA((ClassID)(*it))) { 251 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 252 // collisionEvent->getEntityA()->getClassCName(), *it); 253 // } 254 // } 255 // 256 // } 257 258 if( collisionEvent->getEntityA() == this->owner) 259 { 260 if( collisionEvent->getEntityB()->isA((*it))) 261 { 262 PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 263 collisionEvent->getEntityB()->getClassCName(), (*it).id()); 264 return true; 265 } 266 } 267 else 268 { 269 if( collisionEvent->getEntityA()->isA((*it))) 270 { 271 PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 272 collisionEvent->getEntityA()->getClassCName(), (*it).id()); 273 return true; 274 } 275 } 276 } 277 278 return false; 279 } 280 281 282 /** 283 * filter Collisions that are not wanted to be reacted to 284 * @param collision the collision object to filter 285 */ 286 bool CollisionHandle::filterCollision(Collision* collision) 287 { 288 std::vector<ClassID>::iterator it = this->targetList.begin(); 289 for(; it < this->targetList.end(); it++) 290 { 291 292 // if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM)) 293 // { 294 // PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it); 295 // if( collision->getEntityA() == this->owner) { 296 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 297 // collision->getEntityB()->getClassCName(), *it); 298 // if( collision->getEntityB()->isA((ClassID)(*it))) { 299 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 300 // collision->getEntityB()->getClassCName(), *it); 301 // } 302 // } 303 // else { 304 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 305 // collision->getEntityB()->getClassCName(), *it); 306 // if( collision->getEntityA()->isA((ClassID)(*it))) { 307 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 308 // collision->getEntityA()->getClassCName(), *it); 309 // } 310 // } 311 // } 312 313 if( collision->getEntityA() == this->owner) 314 { 315 if( collision->getEntityA()->isA(*it)) 316 return true; 317 } 318 else 319 { 320 if( collision->getEntityB()->isA(*it)) 321 return true; 322 } 323 } 324 325 return false; 326 } 327 328 329 70 330 } 71 331 72 332 73 /** 74 * standard deconstructor 75 */ 76 CollisionHandle::~CollisionHandle () 77 { 78 // delete what has to be deleted here 79 if( this->collisionReaction != NULL) 80 delete this->collisionReaction; 81 } 82 83 /** 84 * restores the CollisionHandle to its initial state 85 */ 86 void CollisionHandle::reset() 87 { 88 this->flushCollisions(); 89 } 90 91 92 /** 93 * add more filter targets to this collision handle 94 * @param classID the classid to look for 95 */ 96 void CollisionHandle::addTarget(const ClassID& target) 97 { 98 // make sure there is no dublicate 99 std::vector<ClassID>::iterator it = this->targetList.begin(); 100 for( ; it < this->targetList.end(); it++) 101 if( (*it) == target) 102 return; 103 104 105 // add element 106 this->targetList.push_back(target); 107 PRINTF(5)("addTarget: %i \n", target.id()); 108 } 109 110 111 /** 112 * registers a new Collision Object 113 * @param entityA WorldEntity A of the collision 114 * @param entityB WorldEntity B of the collision 115 * if a there is already a collision object with the same stats 116 * registration will be skipped and the last collision object is returned 117 */ 118 Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB) 119 { 120 //first get the collision object, multiple sources 121 Collision* c; 122 if( this->collisionList.empty() || 123 ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) { 124 c = CREngine::getInstance()->popCollisionObject(); 125 c->collide(entityA, entityB); 126 this->collisionList.push_back(c); 127 128 // now register it as a shared collision with the other collision entity 129 CollisionHandle* ch = entityB->getCollisionHandle(this->type); 130 if( ch != NULL) 131 ch->registerSharedCollision(c); 132 } 133 else 134 c = this->collisionList.back(); 135 136 return c; 137 } 138 139 140 /** 141 * register a Collision to the Collision handle. 142 * @param collision the collision object to register 143 * 144 * This is used for internal collision registration: sharing the collision objects between Collision Reactions 145 * Therefore dispatching it only once 146 */ 147 void CollisionHandle::registerSharedCollision(Collision* collision) 148 { 149 // fist check if we are listening for this Collision 150 if( !this->filterCollision(collision)) 151 return; 152 153 // set the state to not dispatched 154 this->bDispatched = false; 155 this->bCollided = true; 156 collision->setEntityBCollide(true); 157 158 this->collisionList.push_back(collision); 159 } 160 161 162 /** 163 * this is the function to be called on a collision event for this handle 164 * @param collision the collision objects containing all collision informations 165 */ 166 void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent) 167 { 168 if( !this->filterCollisionEvent(collisionEvent)) 169 return; 170 171 // set the state to not dispatched 172 this->bDispatched = false; 173 this->bCollided = true; 174 175 // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object 176 Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB()); 177 c->setEntityACollide(true); 178 179 c->registerCollisionEvent(collisionEvent); 180 PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName()); 181 } 182 183 184 /** 185 * flushes the collision list 186 */ 187 void CollisionHandle::flushCollisions() 188 { 189 this->collisionList.clear(); 190 } 191 192 193 /** 194 * handles the collisions and react according to algorithm 195 */ 196 void CollisionHandle::handleCollisions() 197 { 198 // if continuous poll poll the reaction 199 if( this->bContinuousPoll && !this->bCollided) 200 { 201 this->collisionReaction->update(this->owner); 202 return; 203 } 204 205 // collision reaction calculations (for every collision there will be a reaction) 206 std::vector<Collision*>::iterator it = this->collisionList.begin(); 207 for(; it < this->collisionList.end(); it++) { 208 if( !(*it)->isDispatched()) 209 { 210 this->collisionReaction->reactToCollision(*it); 211 (*it)->flushCollisionEvents(); 212 } 213 } 214 215 // now set state to dispatched 216 this->bDispatched = true; 217 this->bCollided = false; 218 219 this->flushCollisions(); 220 } 221 222 223 /** 224 * filter out the CollisionEvents that are not wanted 225 * @param collisionEvent the collision event to filter 226 */ 227 bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent) 228 { 229 std::vector<ClassID>::iterator it = this->targetList.begin(); 230 for(; it < this->targetList.end(); it++) 231 { 232 // if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM)) 233 // { 234 // PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it); 235 // if( collisionEvent->getEntityA() == this->owner) { 236 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 237 // collisionEvent->getEntityB()->getClassCName(), *it); 238 // if( collisionEvent->getEntityB()->isA((ClassID)(*it))) { 239 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 240 // collisionEvent->getEntityB()->getClassCName(), *it); 241 // } 242 // } 243 // else { 244 // PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 245 // collisionEvent->getEntityB()->getClassCName(), *it); 246 // if( collisionEvent->getEntityA()->isA((ClassID)(*it))) { 247 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 248 // collisionEvent->getEntityA()->getClassCName(), *it); 249 // } 250 // } 251 // 252 // } 253 254 if( collisionEvent->getEntityA() == this->owner) { 255 if( collisionEvent->getEntityB()->isA((*it))) { 256 PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 257 collisionEvent->getEntityB()->getClassCName(), (*it).id()); 258 return true; } 259 } 260 else { 261 if( collisionEvent->getEntityA()->isA((*it))) { 262 PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 263 collisionEvent->getEntityA()->getClassCName(), (*it).id()); 264 return true; } 265 } 266 } 267 268 return false; 269 } 270 271 272 /** 273 * filter Collisions that are not wanted to be reacted to 274 * @param collision the collision object to filter 275 */ 276 bool CollisionHandle::filterCollision(Collision* collision) 277 { 278 std::vector<ClassID>::iterator it = this->targetList.begin(); 279 for(; it < this->targetList.end(); it++) 280 { 281 282 // if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM)) 283 // { 284 // PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it); 285 // if( collision->getEntityA() == this->owner) { 286 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 287 // collision->getEntityB()->getClassCName(), *it); 288 // if( collision->getEntityB()->isA((ClassID)(*it))) { 289 // PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 290 // collision->getEntityB()->getClassCName(), *it); 291 // } 292 // } 293 // else { 294 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(), 295 // collision->getEntityB()->getClassCName(), *it); 296 // if( collision->getEntityA()->isA((ClassID)(*it))) { 297 // PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(), 298 // collision->getEntityA()->getClassCName(), *it); 299 // } 300 // } 301 // } 302 303 if( collision->getEntityA() == this->owner) { 304 if( collision->getEntityA()->isA(*it)) 305 return true; } 306 else { 307 if( collision->getEntityB()->isA(*it)) 308 return true; } 309 } 310 311 return false; 312 } 313 314 315 316 317 318 319 333
Note: See TracChangeset
for help on using the changeset viewer.