Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 4, 2006, 6:42:46 PM (18 years ago)
Author:
patrick
Message:

merged the collision reaction branche back to trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/collision_reaction/cr_physics_full_walk.cc

    r9869 r10013  
    3333#include "cr_defs.h"
    3434
    35 
    36 
    37 ObjectListDefinition(CRPhysicsFullWalk);
    38 /**
    39  *  standard constructor
    40  */
    41 CRPhysicsFullWalk::CRPhysicsFullWalk ()
    42     : CollisionReaction()
     35namespace CoRe
    4336{
    44   this->registerObject(this, CRPhysicsFullWalk::_objectList);
     37
     38  ObjectListDefinition(CRPhysicsFullWalk);
     39  /**
     40   *  standard constructor
     41   */
     42  CRPhysicsFullWalk::CRPhysicsFullWalk ()
     43      : CollisionReaction()
     44  {
     45    this->registerObject(this, CRPhysicsFullWalk::_objectList);
     46  }
     47
     48
     49  /**
     50   *  standard deconstructor
     51   */
     52  CRPhysicsFullWalk::~CRPhysicsFullWalk ()
     53  {}
     54
     55
     56  /**
     57   * caluculates and applys the reaction to a specific collision
     58   *  @param collision the collision
     59   */
     60  void CRPhysicsFullWalk::reactToCollision(Collision* collision)
     61  {
     62
     63    AABB* box = collision->getEntityA()->getModelAABB();
     64    WorldEntity* entity = collision->getEntityA();
     65
     66    if( box == NULL)
     67    {
     68      PRINTF(2)("this model has no aabb box so there is no correct collision reaction implemented. skipping\n");
     69      return;
     70    }
     71
     72
     73    float CR_MAX_WALK_HEIGHT = 15.0f;
     74//    float CR_THRESHOLD = 0.2f;
     75
     76    float height = 0.0f;
     77    float front = 0.0f;
     78    float back = 0.0f;
     79    float right = 0.0f;
     80    float left = 0.0f;
     81
     82
     83    std::vector<CollisionEvent*>::const_iterator it = collision->begin();
     84    for(; it != collision->end(); it++)
     85    {
     86
     87      CollisionEvent* ce = (*it);
     88      Vector normal = ce->getGroundNormal();
     89
     90      // calculate the collision position
     91      Vector collPos =  collision->getEntityA()->getAbsCoor()  + box->center - ce->getCollisionPosition();
     92
     93      // test the 3 axis differently
     94      switch( ce->getType())
     95      {
     96          /* collision in the X-AXIS */
     97        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X:
     98          front = collPos.len() - box->halfLength[0];
     99
     100          // object is beneath the plane (ground)
     101          if( front <= 0.0f )
     102          {
     103            Vector dirX = entity->getAbsDirX();
     104            dirX.y = 0.0f;
     105            dirX.normalize();
     106            Vector backoff = dirX * front;
     107
     108            entity->shiftCoor(backoff);
     109          }
     110          else if( ce->isInWall())
     111          {
     112            // object is already in the wall
     113            entity->setAbsCoor(entity->getLastAbsCoor());
     114          }
     115          break;
     116
     117        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG:
     118          back = collPos.len() - box->halfLength[0];
     119
     120          // object is beneath the plane (ground)
     121          if( back <= 0.0f)
     122          {
     123            Vector dirX = entity->getAbsDirX();
     124            dirX.y = 0.0f;
     125            dirX.normalize();
     126            Vector backoff = dirX * back * -1.0f;
     127
     128            entity->shiftCoor(backoff);
     129          }
     130          else if( ce->isInWall())
     131          {
     132            // object is already in the wall
     133            entity->setAbsCoor(entity->getLastAbsCoor());
     134          }
     135          break;
     136
     137
     138          /* collision in the Y-AXIS */
     139        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG:
     140          // calulate the height above ground
     141          height = collPos.len() - box->halfLength[1];
     142
     143
     144          // object is beneath the plane (ground)
     145          //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
     146          if( height < 0.0f && -height < CR_MAX_WALK_HEIGHT)
     147          {
     148            entity->shiftCoor(Vector(0.0f, -height + 0.00001, 0.0f));
     149            entity->setOnGround(true);
     150          }
     151          // object is already in the wall
     152          else if( ce->isInWall())
     153          {
     154            entity->setAbsCoor(entity->getLastAbsCoor());
     155            PRINTF(0)("ground collision: reset pos\n");
     156          }
     157          else
     158          {
     159            // entity is not on ground
     160            entity->setOnGround(false);
     161          }
     162          break;
     163
     164
     165          /* collision in the Z-AXIS */
     166        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z:
     167
     168          right = collPos.len()  - box->halfLength[2];
     169
     170          // object is beneath the plane (ground)
     171          if( right <= 0.0f )
     172          {
     173            Vector dirZ = entity->getAbsDirZ();
     174            dirZ.y = 0.0f;
     175            dirZ.normalize();
     176            Vector backoff = dirZ * right;
     177            entity->shiftCoor(backoff);
     178          }
     179          else if( ce->isInWall())
     180          {
     181            // object is already in the wall
     182            entity->setAbsCoor(entity->getLastAbsCoor());
     183          }
     184          break;
     185
     186
     187          // collision in the z-axis
     188        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG:
     189
     190          left = collPos.len()  - box->halfLength[2];
     191
     192          // object is beneath the plane (ground)
     193          if( left <= 0.0f )
     194          {
     195            Vector dirZ = entity->getAbsDirZ();
     196            dirZ.y = 0.0f;
     197            dirZ.normalize();
     198            Vector backoff = dirZ * left*-1.0f;
     199            entity->shiftCoor(backoff);
     200          }
     201          // object is already in the wall
     202          else if( ce->isInWall())
     203          {
     204            entity->setAbsCoor(entity->getLastAbsCoor());
     205          }
     206          break;
     207      }
     208    }
     209    //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
     210  }
     211
     212
     213
     214
    45215}
    46216
    47 
    48 /**
    49  *  standard deconstructor
    50  */
    51 CRPhysicsFullWalk::~CRPhysicsFullWalk ()
    52 {}
    53 
    54 
    55 /**
    56  * caluculates and applys the reaction to a specific collision
    57  *  @param collision the collision
    58  */
    59 void CRPhysicsFullWalk::reactToCollision(Collision* collision)
    60 {
    61 
    62   AABB* box = collision->getEntityB()->getModelAABB();
    63   WorldEntity* entity = collision->getEntityB();
    64 
    65   if( box == NULL)
    66   {
    67     PRINTF(2)("this model has no aabb box so there is no correct collision reaction implemented. skipping\n");
    68     return;
    69   }
    70 
    71 
    72   float CR_MAX_WALK_HEIGHT = 15.0f;
    73   float CR_THRESHOLD = 0.2f;
    74 
    75   float height = 0.0f;
    76   float front = 0.0f;
    77   float back = 0.0f;
    78   float right = 0.0f;
    79   float left = 0.0f;
    80 
    81 
    82   const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
    83   std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
    84   for(; it != collisionEvents->end(); it++)
    85   {
    86 
    87     CollisionEvent* ce = (*it);
    88     Vector normal = ce->getGroundNormal();
    89 
    90     // calculate the collision position
    91     Vector collPos =  collision->getEntityB()->getAbsCoor()  + box->center - ce->getCollisionPosition();
    92 
    93     // test the 3 axis differently
    94     switch( ce->getType())
    95     {
    96         /* collision in the X-AXIS */
    97       case COLLISION_TYPE_AXIS_X:
    98         front = collPos.len() - box->halfLength[0];
    99 
    100         // object is beneath the plane (ground)
    101         if( front <= 0.0f )
    102         {
    103           Vector dirX = entity->getAbsDirX();
    104           dirX.y = 0.0f;
    105           dirX.normalize();
    106           Vector backoff = dirX * front;
    107 
    108           entity->shiftCoor(backoff);
    109         }
    110         else if( ce->isInWall())
    111         {
    112           // object is already in the wall
    113           entity->setAbsCoor(entity->getLastAbsCoor());
    114         }
    115         break;
    116 
    117       case COLLISION_TYPE_AXIS_X_NEG:
    118         back = collPos.len() - box->halfLength[0];
    119 
    120         // object is beneath the plane (ground)
    121         if( back <= 0.0f)
    122         {
    123           Vector dirX = entity->getAbsDirX();
    124           dirX.y = 0.0f;
    125           dirX.normalize();
    126           Vector backoff = dirX * back * -1.0f;
    127 
    128           entity->shiftCoor(backoff);
    129         }
    130         else if( ce->isInWall())
    131         {
    132           // object is already in the wall
    133           entity->setAbsCoor(entity->getLastAbsCoor());
    134         }
    135         break;
    136 
    137 
    138         /* collision in the Y-AXIS */
    139       case COLLISION_TYPE_AXIS_Y_NEG:
    140         // calulate the height above ground
    141         height = collPos.len() - box->halfLength[1];
    142 
    143 
    144         // object is beneath the plane (ground)
    145         //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
    146         if( height < 0.0f && -height < CR_MAX_WALK_HEIGHT)
    147         {
    148           entity->shiftCoor(Vector(0.0f, -height + 0.00001, 0.0f));
    149           entity->setOnGround(true);
    150         }
    151         // object is already in the wall
    152         else if( ce->isInWall())
    153         {
    154           entity->setAbsCoor(entity->getLastAbsCoor());
    155           PRINTF(0)("ground collision: reset pos\n");
    156         }
    157         else
    158         {
    159           // entity is not on ground
    160           entity->setOnGround(false);
    161         }
    162         break;
    163 
    164 
    165         /* collision in the Z-AXIS */
    166       case COLLISION_TYPE_AXIS_Z:
    167 
    168         right = collPos.len()  - box->halfLength[2];
    169 
    170         // object is beneath the plane (ground)
    171         if( right <= 0.0f )
    172         {
    173           Vector dirZ = entity->getAbsDirZ();
    174           dirZ.y = 0.0f;
    175           dirZ.normalize();
    176           Vector backoff = dirZ * right;
    177           entity->shiftCoor(backoff);
    178         }
    179         else if( ce->isInWall())
    180         {
    181           // object is already in the wall
    182           entity->setAbsCoor(entity->getLastAbsCoor());
    183         }
    184         break;
    185 
    186 
    187         // collision in the z-axis
    188       case COLLISION_TYPE_AXIS_Z_NEG:
    189 
    190         left = collPos.len()  - box->halfLength[2];
    191 
    192         // object is beneath the plane (ground)
    193         if( left <= 0.0f )
    194         {
    195           Vector dirZ = entity->getAbsDirZ();
    196           dirZ.y = 0.0f;
    197           dirZ.normalize();
    198           Vector backoff = dirZ * left*-1.0f;
    199           entity->shiftCoor(backoff);
    200         }
    201         // object is already in the wall
    202         else if( ce->isInWall())
    203         {
    204           entity->setAbsCoor(entity->getLastAbsCoor());
    205         }
    206         break;
    207     }
    208   }
    209   //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
    210 
    211 
    212 
    213 
    214 
    215 
    216 
    217 }
    218 
    219 
    220 
    221 
    222 /**
    223  * use this to do some collision offline calculations, only called for bContinuousPoll == true
    224  */
    225 void CRPhysicsFullWalk::update(WorldEntity* owner)
    226 {}
    227 
    228 
Note: See TracChangeset for help on using the changeset viewer.