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
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->getEntityB()->getModelAABB();
64    WorldEntity* entity = collision->getEntityB();
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    const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
84    std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
85    for(; it != collisionEvents->end(); it++)
86    {
87
88      CollisionEvent* ce = (*it);
89      Vector normal = ce->getGroundNormal();
90
91      // calculate the collision position
92      Vector collPos =  collision->getEntityB()->getAbsCoor()  + box->center - ce->getCollisionPosition();
93
94      // test the 3 axis differently
95      switch( ce->getType())
96      {
97          /* collision in the X-AXIS */
98        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X:
99          front = collPos.len() - box->halfLength[0];
100
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;
108
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;
117
118        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG:
119          back = collPos.len() - box->halfLength[0];
120
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;
128
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;
137
138
139          /* collision in the Y-AXIS */
140        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG:
141          // calulate the height above ground
142          height = collPos.len() - box->halfLength[1];
143
144
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          }
152          // object is already in the wall
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;
164
165
166          /* collision in the Z-AXIS */
167        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z:
168
169          right = collPos.len()  - box->halfLength[2];
170
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;
186
187
188          // collision in the z-axis
189        case CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG:
190
191          left = collPos.len()  - box->halfLength[2];
192
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  }
212
213
214
215
216}
Note: See TracBrowser for help on using the repository browser.