Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 8190 in orxonox.OLD for trunk/src/lib/collision_reaction


Ignore:
Timestamp:
Jun 7, 2006, 3:00:01 PM (19 years ago)
Author:
patrick
Message:

trunk: merged the cr branche to trunk

Location:
trunk/src/lib/collision_reaction
Files:
5 edited
9 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/collision_reaction/Makefile.am

    r7927 r8190  
    55
    66libORXcr_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
    812
    913
    1014
    1115noinst_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
    1322
  • trunk/src/lib/collision_reaction/collision_handle.cc

    r7927 r8190  
    1717#include "collision_handle.h"
    1818
     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
    1927using namespace std;
    2028
     
    3139  this->type = type;
    3240
     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  };
    3362}
    3463
     
    4170  // delete what has to be deleted here
    4271}
     72
     73/**
     74 * restores the CollisionHandle to its initial state
     75 */
     76void 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 */
     86void 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 */
     107Collision* 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 */
     136void 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 */
     155void 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 */
     175void CollisionHandle::flushCollisions()
     176{
     177  this->collisionList.clear();
     178}
     179
     180
     181/**
     182 * handles the collisions and react according to algorithm
     183 */
     184void 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 */
     208bool 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 */
     229bool 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  
    1111
    1212#include <vector>
     13#include <list>
    1314
    1415
    1516class Collision;
    1617class WorldEntity;
     18class CollisionReaction;
    1719
    18 // struct CRType;
    1920
    2021
    2122//! A class for defining collision reactions and storing events
    22 class CollisionHandle : public BaseObject {
     23class CollisionHandle : public BaseObject
     24{
    2325
    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();
    2745
    2846
    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);
    3451
    3552
    36  private:
    37    WorldEntity*                  owner;                   //!< the worldenity this reaction will be applied on
    38    CREngine::CRType              type;                    //!< the reaction type
    3953
    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
    4257
    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
    4567
    4668};
  • trunk/src/lib/collision_reaction/cr_engine.cc

    r7927 r8190  
    1616#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
    1717
     18
     19
     20#include "collision.h"
     21#include "collision_event.h"
     22#include "collision_handle.h"
     23#include "cr_defs.h"
     24
    1825#include "cr_engine.h"
    1926
     
    2532 */
    2633CREngine::CREngine ()
     34  : BaseObject()
    2735{
    2836   this->setClassID(CL_CR_ENGINE, "CREngine");
    2937   this->setName("CREngine");
    3038
     39   this->init();
    3140}
    3241
     
    4251{
    4352  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 */
     75void 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());
    4482}
    4583
    4684
     85/**
     86 * flushes the CollisionHandles and restores the CREngine to the initial state
     87 */
     88void CREngine::reset()
     89{
     90  // first clear all CollisionHandles
    4791
     92  vector<CollisionHandle*>::iterator it = this->collisionHandles.begin();
     93  for(; it < this->collisionHandles.end(); it++)
     94  {
     95    (*it)->reset();
     96    delete *it;
     97  }
    4898
    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();
    57100}
    58101
    59102
     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 */
     109CollisionHandle* 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}
    60116
    61117
     118/**
     119 * unsubscribe reaction from the reaction list
     120 *  @param collisionHandle the CollisionHandle to remove
     121 *  @param returns true if worked collrectly
     122 */
     123bool 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 */
     142void 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 */
     159void 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
     174void CREngine::debug()
     175{
     176
     177}
     178
  • trunk/src/lib/collision_reaction/cr_engine.h

    r8145 r8190  
    22 * @file cr_engine.h
    33 * @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 */
    510
    611#ifndef _CR_ENGINE_
     
    813
    914#include "base_object.h"
    10 #include <stdarg.h>
     15
    1116#include <vector>
    1217
     
    1419class CollisionHandle;
    1520class Collision;
     21class CollisionEvent;
    1622class WorldEntity;
    1723
     
    2228  public:
    2329  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
    2735
    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!)
    3038
    31     CR_VERTEX_TRAFO,
     39    CR_VERTEX_TRAFO,              //!< vertex trafo: transforming the vertex according to the damage
    3240
    33     CR_SPECIAL_CALLBACK,
     41    CR_SPECIAL_CALLBACK,          //!< special: call a callback function
    3442
    3543    CR_NUMBER
     
    3947
    4048  /** @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();
    4252
    4353
    44   CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type, int nrOfTargets, ...);
     54  CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type);
    4555
    46   bool unsubscribeReaction(WorldEntity* worldEntity);
    4756  bool unsubscribeReaction(CollisionHandle* collisionHandle);
    48 
    4957
    5058  void handleCollisions();
    5159
    5260  /** @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();
    5672
    5773
    5874private:
    59   CREngine(void);
     75  CREngine();
     76  void init();
     77
     78  void flushCollisions();
    6079
    6180
    6281private:
    6382  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
    6589
    6690  static CREngine*                    singletonRef;             //!< the reference to the CREngine object (singleton)
Note: See TracChangeset for help on using the changeset viewer.