Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/collision_reaction/cr_physics_full_walk.cc @ 10183

Last change on this file since 10183 was 10013, checked in by patrick, 18 years ago

merged the collision reaction branche back to trunk

File size: 5.5 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
[10013]35namespace CoRe
[9125]36{
37
[10013]38  ObjectListDefinition(CRPhysicsFullWalk);
39  /**
40   *  standard constructor
41   */
42  CRPhysicsFullWalk::CRPhysicsFullWalk ()
43      : CollisionReaction()
[9125]44  {
[10013]45    this->registerObject(this, CRPhysicsFullWalk::_objectList);
[9125]46  }
47
48
[10013]49  /**
50   *  standard deconstructor
51   */
52  CRPhysicsFullWalk::~CRPhysicsFullWalk ()
53  {}
[9125]54
55
[10013]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
[10013]63    AABB* box = collision->getEntityA()->getModelAABB();
64    WorldEntity* entity = collision->getEntityA();
[9125]65
[10013]66    if( box == NULL)
[9125]67    {
[10013]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
[10013]73    float CR_MAX_WALK_HEIGHT = 15.0f;
74//    float CR_THRESHOLD = 0.2f;
[9125]75
[10013]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
[10013]83    std::vector<CollisionEvent*>::const_iterator it = collision->begin();
84    for(; it != collision->end(); it++)
85    {
[9125]86
[10013]87      CollisionEvent* ce = (*it);
88      Vector normal = ce->getGroundNormal();
[9125]89
[10013]90      // calculate the collision position
91      Vector collPos =  collision->getEntityA()->getAbsCoor()  + box->center - ce->getCollisionPosition();
[9125]92
[10013]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];
[9125]99
[10013]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;
[9125]107
[10013]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;
[9125]116
[10013]117        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG:
118          back = collPos.len() - box->halfLength[0];
[9125]119
[10013]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;
[9125]127
[10013]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;
[9125]136
137
[10013]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];
[9125]142
143
[10013]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;
[9125]163
164
[10013]165          /* collision in the Z-AXIS */
166        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z:
[9125]167
[10013]168          right = collPos.len()  - box->halfLength[2];
[9125]169
[10013]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;
[9125]185
186
[10013]187          // collision in the z-axis
188        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG:
[9125]189
[10013]190          left = collPos.len()  - box->halfLength[2];
[9125]191
[10013]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  }
[9125]211
212
213
214
[10013]215}
[9125]216
Note: See TracBrowser for help on using the repository browser.