Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9392 was 9235, checked in by bensch, 18 years ago

merged the presentation back

File size: 5.3 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
35using namespace std;
36
37
38/**
39 *  standard constructor
40 */
41CRPhysicsFullWalk::CRPhysicsFullWalk ()
42    : CollisionReaction()
43{
44  this->setClassID(CL_CR_PHYSICS_FULL_WALK, "CRPhysicsFullWalk");
45}
46
47
48/**
49 *  standard deconstructor
50 */
51CRPhysicsFullWalk::~CRPhysicsFullWalk ()
52{}
53
54
55/**
56 * caluculates and applys the reaction to a specific collision
57 *  @param collision the collision
58 */
59void CRPhysicsFullWalk::reactToCollision(Collision* collision)
60{
61
62  AABB* box = collision->getEntityB()->getModelAABB();
63  WorldEntity* entity = collision->getEntityB();
64
65  if( box == NULL)
66  {
67    PRINTF(2)("this model has no aabb box so there is no correct collision reaction implemented. skipping\n");
68    return;
69  }
70
71
72  float CR_MAX_WALK_HEIGHT = 15.0f;
73  float CR_THRESHOLD = 0.2f;
74
75  float height = 0.0f;
76  float front = 0.0f;
77  float back = 0.0f;
78  float right = 0.0f;
79  float left = 0.0f;
80
81
82  const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
83  std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
84  for(; it != collisionEvents->end(); it++)
85  {
86
87    CollisionEvent* ce = (*it);
88    Vector normal = ce->getGroundNormal();
89
90    // calculate the collision position
91    Vector collPos =  collision->getEntityB()->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 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 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 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 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 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
217}
218
219
220
221
222/**
223 * use this to do some collision offline calculations, only called for bContinuousPoll == true
224 */
225void CRPhysicsFullWalk::update(WorldEntity* owner)
226{}
227
228
Note: See TracBrowser for help on using the repository browser.