Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10771 was 10618, checked in by bknecht, 18 years ago

merged cleanup into trunk (only improvements)

File size: 6.2 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 case CoRe::CREngine::CR_COLLISION_TYPE_WAY:
166          // calulate the height above ground
167          height = collPos.len() - box->halfLength[1];
168
169
170          // object is beneath the plane (ground)
171          //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
172          if( height < 0.0f  )
173          {
174            entity->shiftCoor(Vector(0.0f, -height + 0.5f, 0.0f));
175            entity->setOnGround(true);
176          }
177          // object is already in the wall
178          else if( ce->isInWall())
179          {
180            entity->setAbsCoor(entity->getLastAbsCoor());
181            PRINTF(0)("ground collision: reset pos\n");
182          }
183          else
184          {
185            // entity is not on ground
186            entity->setOnGround(false);
187          }
188          break;
189
190
191          /* collision in the Z-AXIS */
192        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z:
193
194          right = collPos.len()  - box->halfLength[2];
195
196          // object is beneath the plane (ground)
197          if( right <= 0.0f )
198          {
199            Vector dirZ = entity->getAbsDirZ();
200            dirZ.y = 0.0f;
201            dirZ.normalize();
202            Vector backoff = dirZ * right;
203            entity->shiftCoor(backoff);
204          }
205          else if( ce->isInWall())
206          {
207            // object is already in the wall
208            entity->setAbsCoor(entity->getLastAbsCoor());
209          }
210          break;
211
212
213          // collision in the z-axis
214        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG:
215
216          left = collPos.len()  - box->halfLength[2];
217
218          // object is beneath the plane (ground)
219          if( left <= 0.0f )
220          {
221            Vector dirZ = entity->getAbsDirZ();
222            dirZ.y = 0.0f;
223            dirZ.normalize();
224            Vector backoff = dirZ * left*-1.0f;
225            entity->shiftCoor(backoff);
226          }
227          // object is already in the wall
228          else if( ce->isInWall())
229          {
230            entity->setAbsCoor(entity->getLastAbsCoor());
231          }
232          break;
233      }
234    }
235    //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
236  }
237
238
239
240
241}
242
Note: See TracBrowser for help on using the repository browser.