Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/ODE/src/lib/collision_reaction/cr_physics_full_walk.cc @ 10357

Last change on this file since 10357 was 10357, checked in by bottac, 17 years ago
File size: 5.5 KB
Line 
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
35namespace CoRe
36{
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
215}
216
Note: See TracBrowser for help on using the repository browser.