Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/coll_rect/src/lib/collision_reaction/cr_physics_full_walk.cc @ 9982

Last change on this file since 9982 was 9982, checked in by patrick, 17 years ago

collision reaction classes adapted to new structure

File size: 5.6 KB
RevLine 
[9125]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
17
18#include "collision.h"
19#include "collision_event.h"
20
21#include "physics_interface.h"
22
23#include "world_entity.h"
24#include "cr_physics_full_walk.h"
25#include "collision_reaction.h"
26
27#include <vector>
28
29#include "debug.h"
30
31#include "aabb.h"
32
33#include "cr_defs.h"
34
[9889]35namespace CoRe
[9125]36{
37
[9889]38  ObjectListDefinition(CRPhysicsFullWalk);
39  /**
40   *  standard constructor
41   */
42  CRPhysicsFullWalk::CRPhysicsFullWalk ()
43      : CollisionReaction()
44  {
45    this->registerObject(this, CRPhysicsFullWalk::_objectList);
46  }
[9125]47
48
[9889]49  /**
50   *  standard deconstructor
51   */
52  CRPhysicsFullWalk::~CRPhysicsFullWalk ()
53  {}
[9125]54
55
[9889]56  /**
57   * caluculates and applys the reaction to a specific collision
58   *  @param collision the collision
59   */
60  void CRPhysicsFullWalk::reactToCollision(Collision* collision)
[9125]61  {
62
[9889]63    AABB* box = collision->getEntityB()->getModelAABB();
64    WorldEntity* entity = collision->getEntityB();
[9125]65
[9889]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    }
[9125]71
72
[9889]73    float CR_MAX_WALK_HEIGHT = 15.0f;
[9892]74//    float CR_THRESHOLD = 0.2f;
[9125]75
[9889]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;
[9125]81
82
[9889]83    const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
84    std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
85    for(; it != collisionEvents->end(); it++)
[9125]86    {
87
[9889]88      CollisionEvent* ce = (*it);
89      Vector normal = ce->getGroundNormal();
[9125]90
[9889]91      // calculate the collision position
92      Vector collPos =  collision->getEntityB()->getAbsCoor()  + box->center - ce->getCollisionPosition();
[9125]93
[9889]94      // test the 3 axis differently
95      switch( ce->getType())
96      {
97          /* collision in the X-AXIS */
[9895]98        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X:
[9889]99          front = collPos.len() - box->halfLength[0];
[9125]100
[9889]101          // object is beneath the plane (ground)
102          if( front <= 0.0f )
103          {
104            Vector dirX = entity->getAbsDirX();
105            dirX.y = 0.0f;
106            dirX.normalize();
107            Vector backoff = dirX * front;
[9125]108
[9889]109            entity->shiftCoor(backoff);
110          }
111          else if( ce->isInWall())
112          {
113            // object is already in the wall
114            entity->setAbsCoor(entity->getLastAbsCoor());
115          }
116          break;
[9125]117
[9895]118        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG:
[9889]119          back = collPos.len() - box->halfLength[0];
[9125]120
[9889]121          // object is beneath the plane (ground)
122          if( back <= 0.0f)
123          {
124            Vector dirX = entity->getAbsDirX();
125            dirX.y = 0.0f;
126            dirX.normalize();
127            Vector backoff = dirX * back * -1.0f;
[9125]128
[9889]129            entity->shiftCoor(backoff);
130          }
131          else if( ce->isInWall())
132          {
133            // object is already in the wall
134            entity->setAbsCoor(entity->getLastAbsCoor());
135          }
136          break;
[9125]137
138
[9889]139          /* collision in the Y-AXIS */
[9895]140        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG:
[9889]141          // calulate the height above ground
142          height = collPos.len() - box->halfLength[1];
[9125]143
144
[9889]145          // object is beneath the plane (ground)
146          //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
147          if( height < 0.0f && -height < CR_MAX_WALK_HEIGHT)
148          {
149            entity->shiftCoor(Vector(0.0f, -height + 0.00001, 0.0f));
150            entity->setOnGround(true);
151          }
[9125]152          // object is already in the wall
[9889]153          else if( ce->isInWall())
154          {
155            entity->setAbsCoor(entity->getLastAbsCoor());
156            PRINTF(0)("ground collision: reset pos\n");
157          }
158          else
159          {
160            // entity is not on ground
161            entity->setOnGround(false);
162          }
163          break;
[9125]164
165
[9889]166          /* collision in the Z-AXIS */
[9895]167        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z:
[9125]168
[9889]169          right = collPos.len()  - box->halfLength[2];
[9125]170
[9889]171          // object is beneath the plane (ground)
172          if( right <= 0.0f )
173          {
174            Vector dirZ = entity->getAbsDirZ();
175            dirZ.y = 0.0f;
176            dirZ.normalize();
177            Vector backoff = dirZ * right;
178            entity->shiftCoor(backoff);
179          }
180          else if( ce->isInWall())
181          {
182            // object is already in the wall
183            entity->setAbsCoor(entity->getLastAbsCoor());
184          }
185          break;
[9125]186
187
[9889]188          // collision in the z-axis
[9895]189        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG:
[9125]190
[9889]191          left = collPos.len()  - box->halfLength[2];
[9125]192
[9889]193          // object is beneath the plane (ground)
194          if( left <= 0.0f )
195          {
196            Vector dirZ = entity->getAbsDirZ();
197            dirZ.y = 0.0f;
198            dirZ.normalize();
199            Vector backoff = dirZ * left*-1.0f;
200            entity->shiftCoor(backoff);
201          }
202          // object is already in the wall
203          else if( ce->isInWall())
204          {
205            entity->setAbsCoor(entity->getLastAbsCoor());
206          }
207          break;
208      }
209    }
210    //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
211  }
[9125]212
213
[9889]214
215
[9982]216}
Note: See TracBrowser for help on using the repository browser.