SuperTuxKart
physics.hpp
1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2006-2015 Joerg Henrichs
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #ifndef HEADER_PHYSICS_HPP
20 #define HEADER_PHYSICS_HPP
21 
27 #include <set>
28 #include <vector>
29 
30 #include "btBulletDynamicsCommon.h"
31 
32 #include "physics/irr_debug_drawer.hpp"
33 #include "physics/stk_dynamics_world.hpp"
34 #include "physics/user_pointer.hpp"
35 #include "utils/singleton.hpp"
36 
37 class AbstractKart;
38 class STKDynamicsWorld;
39 class Vec3;
40 
44 class Physics : public btSequentialImpulseConstraintSolver
45  , public AbstractSingleton<Physics>
46 {
47 private:
59  {
60  private:
62  const UserPointer *m_up[2];
63 
66  public:
70  CollisionPair(const UserPointer *a, const btVector3 &contact_point_a,
71  const UserPointer *b, const btVector3 &contact_point_b)
72  {
73  if(a->is(UserPointer::UP_KART) &&
74  b->is(UserPointer::UP_KART) && a>b) {
75  m_up[0]=b; m_contact_point[0] = contact_point_b;
76  m_up[1]=a; m_contact_point[1] = contact_point_a;
77  } else {
78  m_up[0]=a; m_contact_point[0] = contact_point_a;
79  m_up[1]=b; m_contact_point[1] = contact_point_b;
80  }
81  }; // CollisionPair
82  // --------------------------------------------------------------------
86  bool operator==(const CollisionPair &p)
87  {
88  return (p.m_up[0]==m_up[0] && p.m_up[1]==m_up[1]);
89  } // operator==
90  // --------------------------------------------------------------------
91  const UserPointer *getUserPointer(unsigned int n) const
92  {
93  assert(n<=1);
94  return m_up[n];
95  } // getUserPointer
96  // --------------------------------------------------------------------
99  const Vec3 &getContactPointCS(unsigned int n) const
100  {
101  assert(n>=0 && n<=1);
102  return m_contact_point[n];
103  } // getContactPointCS
104  }; // CollisionPair
105 
106  // ========================================================================
107  // This class is the list of collision objects, where each collision
108  // pair is stored as most once.
109  class CollisionList : public std::vector<CollisionPair>
110  {
111  private:
112  void push_back(CollisionPair p) {
113  // only add a pair if it's not already in there
114  for(iterator i=begin(); i!=end(); i++) {
115  if((*i)==p) return;
116  }
117  std::vector<CollisionPair>::push_back(p);
118  }; // push_back
119  public:
121  void push_back(const UserPointer *a, const btVector3 &contact_point_a,
122  const UserPointer *b, const btVector3 &contact_point_b)
123  {
124  push_back(CollisionPair(a, contact_point_a, b, contact_point_b));
125  }
126  }; // CollisionList
127  // ========================================================================
128 
134 
139  std::vector<const AbstractKart*> m_karts_to_delete;
140 
143 
146 
147  btCollisionDispatcher *m_dispatcher;
148  btBroadphaseInterface *m_axis_sweep;
149  btDefaultCollisionConfiguration *m_collision_conf;
150  CollisionList m_all_collisions;
151 
154 
155  Physics();
156  virtual ~Physics();
157 
158  // Give the singleton access to the constructor
159  friend class AbstractSingleton<Physics>;
160 
161 public:
162  void init (const Vec3 &min_world, const Vec3 &max_world);
163  void addKart (const AbstractKart *k);
164  void addBody (btRigidBody* b) {m_dynamics_world->addRigidBody(b);}
165  void removeKart (const AbstractKart *k);
166  void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
167  void KartKartCollision(AbstractKart *ka, const Vec3 &contact_point_a,
168  AbstractKart *kb, const Vec3 &contact_point_b);
169  void update (int ticks);
170  void draw ();
172  getPhysicsWorld () const {return m_dynamics_world;}
176  void setDebugMode(IrrDebugDrawer::DebugModeType mode) { m_debug_drawer->setDebugMode(mode); }
178  bool isDebug() const {return m_debug_drawer->debugEnabled(); }
179  IrrDebugDrawer* getDebugDrawer() { return m_debug_drawer; }
180  virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
181  btPersistentManifold** manifold,int numManifolds,
182  btTypedConstraint** constraints,int numConstraints,
183  const btContactSolverInfo& info,
184  btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,
185  btDispatcher* dispatcher);
186 };
187 
188 #endif // HEADER_PHYSICS_HPP
void draw()
A debug draw function to show the track and all karts.
Definition: physics.cpp:735
A wrapper around bullets btVector3 to include conventient conversion functions (e....
Definition: vec3.hpp:34
Physics()
Initialise physics.
Definition: physics.cpp:51
std::vector< const AbstractKart * > m_karts_to_delete
If kart need to be removed from the physics world while physics processing is taking place,...
Definition: physics.hpp:139
void KartKartCollision(AbstractKart *ka, const Vec3 &contact_point_a, AbstractKart *kb, const Vec3 &contact_point_b)
Handles the special case of two karts colliding with each other, which means that bombs must be passe...
Definition: physics.cpp:406
bool m_physics_loop_active
This flag is set while bullets time step processing is taking place.
Definition: physics.hpp:133
void nextDebugMode()
Activates the next debug mode (or switches it off again).
Definition: physics.hpp:175
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, btIDebugDraw *debugDrawer, btStackAlloc *stackAlloc, btDispatcher *dispatcher)
This function is called at each internal bullet timestep.
Definition: physics.cpp:540
static Physics * m_physics
Singleton.
Definition: physics.hpp:153
void init(const Vec3 &min_world, const Vec3 &max_world)
The actual initialisation of the physics, which is called after the track model is loaded.
Definition: physics.cpp:62
STKDynamicsWorld * m_dynamics_world
Pointer to the physics dynamics world.
Definition: physics.hpp:142
bool debugEnabled() const
Returns true if debug mode is enabled.
Definition: irr_debug_drawer.hpp:73
Bullet can report the same collision more than once (up to 4 contact points per collision.
Definition: physics.hpp:58
bool operator==(const CollisionPair &p)
Tests if two collision pairs involve the same objects.
Definition: physics.hpp:86
A thin wrapper around bullet's btDiscreteDynamicsWorld.
Definition: stk_dynamics_world.hpp:28
DebugModeType
The drawing mode to use: If bit 0 is set, draw the bullet collision shape of karts If bit 1 is set,...
Definition: irr_debug_drawer.hpp:39
const Vec3 & getContactPointCS(unsigned int n) const
Returns the contact point of the collision in car (local) coordinates.
Definition: physics.hpp:99
void nextDebugMode()
Activates the next debug mode, or switches the mode off again.
Definition: irr_debug_drawer.cpp:37
Definition: physics.hpp:44
bool isDebug() const
Returns true if the debug drawer is enabled.
Definition: physics.hpp:178
Manages the abstract singleton at runtime. This has been designed to allow multi-inheritance....
Definition: singleton.hpp:34
void update(int ticks)
Updates the physics simulation and handles all collisions.
Definition: physics.cpp:152
Vec3 m_contact_point[2]
The contact point for each object (in local coordincates).
Definition: physics.hpp:65
const UserPointer * m_up[2]
The user pointer of the objects involved in this collision.
Definition: physics.hpp:62
IrrDebugDrawer * m_debug_drawer
Used in physics debugging to draw the physics world.
Definition: physics.hpp:145
void removeKart(const AbstractKart *k)
Removes a kart from the physics engine.
Definition: physics.cpp:125
void push_back(const UserPointer *a, const btVector3 &contact_point_a, const UserPointer *b, const btVector3 &contact_point_b)
Adds information about a collision to this vector.
Definition: physics.hpp:121
A UserPointer is stored as a user pointer in all bullet bodies.
Definition: user_pointer.hpp:35
CollisionPair(const UserPointer *a, const btVector3 &contact_point_a, const UserPointer *b, const btVector3 &contact_point_b)
The entries in Collision Pairs are sorted: if a projectile is included, it's always 'a'.
Definition: physics.hpp:70
Definition: irr_debug_drawer.hpp:32
void addKart(const AbstractKart *k)
Adds a kart to the physics engine.
Definition: physics.cpp:107
An abstract interface for the actual karts.
Definition: abstract_kart.hpp:61
Definition: physics.hpp:109