2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
|
|
|
// Copyright (C) 2006 Joerg Henrichs
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2009-01-22 07:02:40 -05:00
|
|
|
#ifndef HEADER_PHYSICS_HPP
|
|
|
|
#define HEADER_PHYSICS_HPP
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2011-10-25 13:46:14 -04:00
|
|
|
/**
|
|
|
|
* \defgroup physics
|
|
|
|
* Contains various physics utilities.
|
|
|
|
*/
|
2010-04-23 16:48:56 -04:00
|
|
|
|
2008-09-07 10:55:05 -04:00
|
|
|
#include <set>
|
2008-11-06 20:05:52 -05:00
|
|
|
#include <vector>
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
#include "btBulletDynamicsCommon.h"
|
2008-02-14 22:53:41 -05:00
|
|
|
|
2010-02-22 13:39:41 -05:00
|
|
|
#include "physics/irr_debug_drawer.hpp"
|
2011-11-30 20:14:10 -05:00
|
|
|
#include "physics/stk_dynamics_world.hpp"
|
2009-06-02 20:54:17 -04:00
|
|
|
#include "physics/user_pointer.hpp"
|
2008-11-06 20:05:52 -05:00
|
|
|
|
2012-03-19 16:21:11 -04:00
|
|
|
class AbstractKart;
|
2011-11-30 20:14:10 -05:00
|
|
|
class STKDynamicsWorld;
|
|
|
|
class Vec3;
|
2008-11-06 20:05:52 -05:00
|
|
|
|
2010-04-23 16:48:56 -04:00
|
|
|
/**
|
|
|
|
* \ingroup physics
|
|
|
|
*/
|
2007-12-08 08:04:56 -05:00
|
|
|
class Physics : public btSequentialImpulseConstraintSolver
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2007-12-08 08:04:56 -05:00
|
|
|
private:
|
2011-12-12 00:42:40 -05:00
|
|
|
/** Bullet can report the same collision more than once (up to 4
|
|
|
|
* contact points per collision. Additionally, more than one internal
|
|
|
|
* substep might be taken, resulting in potentially even more
|
|
|
|
* duplicates. To handle this, all collisions (i.e. pair of objects)
|
|
|
|
* are stored in a vector, but only one entry per collision pair
|
|
|
|
* of objects.
|
|
|
|
* While this is a natural application of std::set, the set has some
|
|
|
|
* overhead (since it will likely use a tree to sort the entries).
|
|
|
|
* Considering that the number of collisions is usually rather small
|
|
|
|
* a simple list and linear search is faster is is being used here. */
|
2007-12-08 08:04:56 -05:00
|
|
|
class CollisionPair {
|
2011-12-14 16:02:15 -05:00
|
|
|
private:
|
2011-12-12 00:42:40 -05:00
|
|
|
/** The user pointer of the objects involved in this collision. */
|
2011-12-14 16:02:15 -05:00
|
|
|
const UserPointer *m_up[2];
|
2009-01-22 07:02:40 -05:00
|
|
|
|
2011-12-14 16:02:15 -05:00
|
|
|
/** The contact point for each object (in local coordincates). */
|
|
|
|
Vec3 m_contact_point[2];
|
|
|
|
public:
|
2011-12-12 00:42:40 -05:00
|
|
|
/** The entries in Collision Pairs are sorted: if a projectile
|
|
|
|
* is included, it's always 'a'. If only two karts are reported
|
|
|
|
* the first kart pointer is the smaller one. */
|
2011-12-14 16:02:15 -05:00
|
|
|
CollisionPair(const UserPointer *a, const btVector3 &contact_point_a,
|
|
|
|
const UserPointer *b, const btVector3 &contact_point_b)
|
|
|
|
{
|
|
|
|
if(a->is(UserPointer::UP_KART) &&
|
|
|
|
b->is(UserPointer::UP_KART) && a>b) {
|
|
|
|
m_up[0]=b; m_contact_point[0] = contact_point_b;
|
|
|
|
m_up[1]=a; m_contact_point[1] = contact_point_a;
|
2009-01-22 07:02:40 -05:00
|
|
|
} else {
|
2011-12-14 16:02:15 -05:00
|
|
|
m_up[0]=a; m_contact_point[0] = contact_point_a;
|
|
|
|
m_up[1]=b; m_contact_point[1] = contact_point_b;
|
2009-01-22 07:02:40 -05:00
|
|
|
}
|
2007-12-08 08:04:56 -05:00
|
|
|
}; // CollisionPair
|
2011-12-12 00:42:40 -05:00
|
|
|
// --------------------------------------------------------------------
|
|
|
|
/** Tests if two collision pairs involve the same objects. This test
|
|
|
|
* is simplified (i.e. no test if p.b==a and p.a==b) since the
|
|
|
|
* elements are sorted. */
|
2011-12-14 16:02:15 -05:00
|
|
|
bool operator==(const CollisionPair p)
|
|
|
|
{
|
|
|
|
return (p.m_up[0]==m_up[0] && p.m_up[1]==m_up[1]);
|
|
|
|
} // operator==
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
const UserPointer *getUserPointer(unsigned int n) const
|
|
|
|
{
|
|
|
|
assert(n>=0 && n<=1);
|
|
|
|
return m_up[n];
|
|
|
|
} // getUserPointer
|
2011-12-12 00:42:40 -05:00
|
|
|
// --------------------------------------------------------------------
|
2011-12-14 16:02:15 -05:00
|
|
|
/** Returns the contact point of the collision in
|
|
|
|
* car (local) coordinates. */
|
|
|
|
const Vec3 &getContactPointCS(unsigned int n) const
|
|
|
|
{
|
|
|
|
assert(n>=0 && n<=1);
|
|
|
|
return m_contact_point[n];
|
|
|
|
} // getContactPointCS
|
2009-01-22 07:02:40 -05:00
|
|
|
}; // CollisionPair
|
|
|
|
|
2011-12-12 00:42:40 -05:00
|
|
|
// ========================================================================
|
2007-12-08 08:04:56 -05:00
|
|
|
// This class is the list of collision objects, where each collision
|
|
|
|
// pair is stored as most once.
|
2011-12-12 00:42:40 -05:00
|
|
|
class CollisionList : public std::vector<CollisionPair>
|
|
|
|
{
|
2008-01-30 00:30:10 -05:00
|
|
|
private:
|
|
|
|
void push_back(CollisionPair p) {
|
2007-12-08 08:04:56 -05:00
|
|
|
// only add a pair if it's not already in there
|
|
|
|
for(iterator i=begin(); i!=end(); i++) {
|
|
|
|
if((*i)==p) return;
|
|
|
|
}
|
|
|
|
std::vector<CollisionPair>::push_back(p);
|
2009-01-22 07:02:40 -05:00
|
|
|
}; // push_back
|
2008-01-30 00:30:10 -05:00
|
|
|
public:
|
2011-12-12 00:42:40 -05:00
|
|
|
/** Adds information about a collision to this vector. */
|
2011-12-14 16:02:15 -05:00
|
|
|
void push_back(const UserPointer *a, const btVector3 &contact_point_a,
|
|
|
|
const UserPointer *b, const btVector3 &contact_point_b)
|
2011-12-12 00:42:40 -05:00
|
|
|
{
|
2011-12-14 16:02:15 -05:00
|
|
|
push_back(CollisionPair(a, contact_point_a, b, contact_point_b));
|
2008-01-30 00:30:10 -05:00
|
|
|
}
|
2009-01-22 07:02:40 -05:00
|
|
|
}; // CollisionList
|
2011-12-12 00:42:40 -05:00
|
|
|
// ========================================================================
|
2009-01-22 07:02:40 -05:00
|
|
|
|
2012-05-07 17:59:21 -04:00
|
|
|
/** This flag is set while bullets time step processing is taking
|
|
|
|
* place. It is used to avoid altering data structures that might
|
|
|
|
* be used (e.g. removing a kart while a loop over all karts is
|
|
|
|
* taking place, as can happen in collision handling). */
|
|
|
|
bool m_physics_loop_active;
|
|
|
|
|
|
|
|
/** If kart need to be removed from the physics world while physics
|
|
|
|
* processing is taking place, store the pointers to the karts to
|
|
|
|
* be removed here, and remove them once the physics processing
|
|
|
|
* is finished. */
|
|
|
|
std::vector<const AbstractKart*> m_karts_to_delete;
|
|
|
|
|
2011-11-30 20:14:10 -05:00
|
|
|
/** Pointer to the physics dynamics world. */
|
|
|
|
STKDynamicsWorld *m_dynamics_world;
|
|
|
|
|
|
|
|
/** Used in physics debugging to draw the physics world. */
|
2010-02-22 07:02:13 -05:00
|
|
|
IrrDebugDrawer *m_debug_drawer;
|
2009-01-22 07:02:40 -05:00
|
|
|
btCollisionDispatcher *m_dispatcher;
|
|
|
|
btBroadphaseInterface *m_axis_sweep;
|
|
|
|
btDefaultCollisionConfiguration *m_collision_conf;
|
2012-01-31 07:02:10 -05:00
|
|
|
CollisionList m_all_collisions;
|
2007-12-08 08:04:56 -05:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
public:
|
2008-09-19 02:07:29 -04:00
|
|
|
Physics ();
|
2008-09-07 11:10:59 -04:00
|
|
|
~Physics ();
|
2008-09-19 02:07:29 -04:00
|
|
|
void init (const Vec3 &min_world, const Vec3 &max_world);
|
2012-03-19 16:21:11 -04:00
|
|
|
void addKart (const AbstractKart *k);
|
2008-09-07 11:10:59 -04:00
|
|
|
void addBody (btRigidBody* b) {m_dynamics_world->addRigidBody(b);}
|
2012-03-19 16:21:11 -04:00
|
|
|
void removeKart (const AbstractKart *k);
|
2008-09-07 11:10:59 -04:00
|
|
|
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
|
2012-03-19 16:21:11 -04:00
|
|
|
void KartKartCollision(AbstractKart *ka, const Vec3 &contact_point_a,
|
|
|
|
AbstractKart *kb, const Vec3 &contact_point_b);
|
2008-09-07 11:10:59 -04:00
|
|
|
void update (float dt);
|
|
|
|
void draw ();
|
2011-11-30 20:14:10 -05:00
|
|
|
STKDynamicsWorld*
|
2008-09-07 11:10:59 -04:00
|
|
|
getPhysicsWorld () const {return m_dynamics_world;}
|
2010-02-26 02:03:12 -05:00
|
|
|
/** Activates the next debug mode (or switches it off again).
|
|
|
|
*/
|
|
|
|
void nextDebugMode () {m_debug_drawer->nextDebugMode(); }
|
|
|
|
/** Returns true if the debug drawer is enabled. */
|
|
|
|
bool isDebug() const {return m_debug_drawer->debugEnabled(); }
|
2012-03-19 16:21:11 -04:00
|
|
|
bool projectKartDownwards(const AbstractKart *k);
|
2007-12-08 08:04:56 -05:00
|
|
|
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
|
|
|
btPersistentManifold** manifold,int numManifolds,
|
|
|
|
btTypedConstraint** constraints,int numConstraints,
|
2009-08-18 06:59:21 -04:00
|
|
|
const btContactSolverInfo& info,
|
2007-12-08 08:04:56 -05:00
|
|
|
btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,
|
|
|
|
btDispatcher* dispatcher);
|
2007-05-27 12:01:53 -04:00
|
|
|
};
|
|
|
|
|
2009-01-22 07:02:40 -05:00
|
|
|
#endif // HEADER_PHYSICS_HPP
|