Improved handling of bullet user pointers, which should fix the problem
of rockets not exploding when hitting the track anymore. But there is still a bug with homing missiles, which still don't explode :( git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1425 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
b75c9ec869
commit
c3d3f3ab19
@ -53,7 +53,6 @@ Flyable::Flyable(Kart *kart, CollectableType type) : Moveable(false)
|
||||
m_shape = NULL;
|
||||
m_mass = 1.0f;
|
||||
|
||||
setUserPointerType(UP_PROJECTILE);
|
||||
// Add the graphical model
|
||||
ssgTransform *m = getModelTransform();
|
||||
m->addKid(m_st_model[type]);
|
||||
@ -92,7 +91,8 @@ void Flyable::createPhysics(float y_offset, const btVector3 velocity,
|
||||
trans *= offset_transform;
|
||||
|
||||
m_shape = shape;
|
||||
createBody(m_mass, trans, m_shape, UserPointer::UP_PROJECTILE);
|
||||
createBody(m_mass, trans, m_shape);
|
||||
m_user_pointer.set(UserPointer::UP_PROJECTILE, this);
|
||||
world->getPhysics()->addBody(getBody());
|
||||
|
||||
// Simplified rockets: no gravity
|
||||
@ -106,7 +106,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 velocity,
|
||||
m_body->setLinearVelocity(v);
|
||||
m_body->setAngularFactor(0.0f); // prevent rotations
|
||||
}
|
||||
m_body->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
// m_body->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
|
||||
// FIXME: for now it is necessary to synch the graphical position with the
|
||||
// physical position, since 'hot' computation is done using the
|
||||
|
@ -198,8 +198,8 @@ void Kart::createPhysics(ssgEntity *obj)
|
||||
// --------------------
|
||||
btTransform trans;
|
||||
trans.setIdentity();
|
||||
createBody(mass, trans, &m_kart_chassis, UserPointer::UP_KART);
|
||||
|
||||
createBody(mass, trans, &m_kart_chassis);
|
||||
m_user_pointer.set(UserPointer::UP_KART, this);
|
||||
m_body->setDamping(m_kart_properties->getChassisLinearDamping(),
|
||||
m_kart_properties->getChassisAngularDamping() );
|
||||
|
||||
|
@ -78,8 +78,7 @@ void Moveable::reset ()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Moveable::createBody(float mass, btTransform& trans,
|
||||
btCollisionShape *shape,
|
||||
UserPointer::UserPointerType t) {
|
||||
btCollisionShape *shape) {
|
||||
|
||||
btVector3 inertia;
|
||||
shape->calculateLocalInertia(mass, inertia);
|
||||
@ -89,8 +88,11 @@ void Moveable::createBody(float mass, btTransform& trans,
|
||||
// ------------------------
|
||||
m_body = new btRigidBody(mass, m_motion_state,
|
||||
shape, inertia);
|
||||
m_body->setUserPointer(this);
|
||||
setUserPointerType(t);
|
||||
// This MUST actually be set from the actual class, otherwise this
|
||||
// is only a pointer to moveable, not to (say) kart, and virtual
|
||||
// functions are not called correctly.
|
||||
m_user_pointer.set(UserPointer::UP_UNDEF, 0);
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
} // createBody
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -32,11 +32,12 @@
|
||||
#define MAX_HERRING_EATEN 20
|
||||
|
||||
|
||||
class Moveable : public UserPointer
|
||||
class Moveable
|
||||
{
|
||||
private:
|
||||
btVector3 m_velocityLC; /* velocity in kart coordinates */
|
||||
protected:
|
||||
UserPointer m_user_pointer;
|
||||
sgCoord m_reset_pos; /* Where to start in case of a reset */
|
||||
sgCoord m_curr_pos; /* current position */
|
||||
sgVec4* m_normal_hot; /* plane on which HOT was computed */
|
||||
@ -47,9 +48,6 @@ protected:
|
||||
int m_crashed;
|
||||
sgVec3 m_surface_avoidance_vector ;
|
||||
int m_first_time ;
|
||||
#ifndef BULLET
|
||||
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
||||
#endif
|
||||
sgCoord* m_history_velocity;
|
||||
sgCoord* m_history_position;
|
||||
btRigidBody* m_body;
|
||||
@ -58,9 +56,6 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
/* start - New Physics */
|
||||
|
||||
|
||||
Moveable (bool bHasHistory=false);
|
||||
virtual ~Moveable();
|
||||
|
||||
@ -80,9 +75,7 @@ public:
|
||||
void ReadHistory (char* s, int kartNumber, int indx);
|
||||
btRigidBody* getBody () const {return m_body; }
|
||||
void createBody(float mass, btTransform& trans,
|
||||
btCollisionShape *shape,
|
||||
UserPointer::UserPointerType t);
|
||||
//void getTrans (btTransform& t) const {m_motion_state->getWorldTransform(t);}
|
||||
btCollisionShape *shape);
|
||||
const btTransform& getTrans() const {return m_transform;}
|
||||
void setTrans (btTransform& t){m_transform=t;m_motion_state->setWorldTransform(t);}
|
||||
}
|
||||
|
@ -103,26 +103,23 @@ void Physics::update(float dt)
|
||||
std::vector<CollisionPair>::iterator p;
|
||||
for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
|
||||
{
|
||||
if(p->type_a==UserPointer::UP_KART) { // kart-kart collision
|
||||
Kart *kartA = (Kart*)(p->a);
|
||||
Kart *kartB = (Kart*)(p->b);
|
||||
KartKartCollision(kartA, kartB);
|
||||
if(p->a->is(UserPointer::UP_KART)) { // kart-kart collision
|
||||
KartKartCollision(p->a->getPointerKart(), p->b->getPointerKart());
|
||||
} // if kart-kart collision
|
||||
else // now the first object must be a projectile
|
||||
{
|
||||
if(p->type_b==UserPointer::UP_TRACK) // must be projectile hit track
|
||||
if(p->b->is(UserPointer::UP_TRACK)) // must be projectile hit track
|
||||
{
|
||||
((Flyable*)(p->a))->hitTrack();
|
||||
p->a->getPointerFlyable()->hitTrack();
|
||||
}
|
||||
else if(p->type_b==UserPointer::UP_KART) // projectile hit kart
|
||||
else if(p->b->is(UserPointer::UP_KART)) // projectile hit kart
|
||||
{
|
||||
Flyable *f=(Flyable*)(p->a);
|
||||
f->explode((Kart*)(p->b));
|
||||
p->a->getPointerFlyable()->explode((Kart*)(p->b));
|
||||
}
|
||||
else // projectile hits projectile
|
||||
{
|
||||
((Flyable*)(p->a))->explode(NULL);
|
||||
((Flyable*)(p->b))->explode(NULL);
|
||||
p->a->getPointerFlyable()->explode(NULL);
|
||||
p->b->getPointerFlyable()->explode(NULL);
|
||||
}
|
||||
}
|
||||
} // for all p in m_all_collisions
|
||||
@ -199,76 +196,41 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
int numContacts = contactManifold->getNumContacts();
|
||||
if(!numContacts) continue; // no real collision
|
||||
|
||||
Moveable *movA = static_cast<Moveable*>(objA->getUserPointer());
|
||||
Moveable *movB = static_cast<Moveable*>(objB->getUserPointer());
|
||||
UserPointer *upA = (UserPointer*)(objA->getUserPointer());
|
||||
UserPointer *upB = (UserPointer*)(objB->getUserPointer());
|
||||
|
||||
// 1) object A is a track
|
||||
// =======================
|
||||
if(!movA)
|
||||
if(upA->is(UserPointer::UP_TRACK))
|
||||
{
|
||||
if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
||||
{ // 1.1 projectile hits track
|
||||
// -------------------------
|
||||
m_all_collisions.push_back(CollisionPair(movB, UserPointer::UP_PROJECTILE,
|
||||
NULL, UserPointer::UP_TRACK ));
|
||||
}
|
||||
else if(movB && movB->getUserPointerType()==UserPointer::UP_KART)
|
||||
{
|
||||
((Kart*)movB)->crashed();
|
||||
}
|
||||
if(upB->is(UserPointer::UP_PROJECTILE)) // 1.1 projectile hits track
|
||||
m_all_collisions.push_back(upB, upA);
|
||||
else if(upB->is(UserPointer::UP_KART))
|
||||
upB->getPointerKart()->crashed();
|
||||
}
|
||||
// 2) object a is a kart
|
||||
// =====================
|
||||
else if(movA->getUserPointerType()==UserPointer::UP_KART)
|
||||
else if(upA->is(UserPointer::UP_KART))
|
||||
{
|
||||
if(!movB)
|
||||
{ // The casts here are important, otherwise re-casting the
|
||||
// pointers later in kart-kart does not work as expected.
|
||||
((Kart*)movA)->crashed();
|
||||
}
|
||||
else if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
||||
{ // 2.1 projectile hits kart
|
||||
// -------------------------
|
||||
m_all_collisions.push_back(CollisionPair(movB, UserPointer::UP_PROJECTILE,
|
||||
(Kart*)movA, UserPointer::UP_KART ));
|
||||
}
|
||||
else if(movB && movB->getUserPointerType()==UserPointer::UP_KART)
|
||||
{ // 2.2 kart hits kart
|
||||
// ------------------
|
||||
m_all_collisions.push_back(CollisionPair((Kart*)movA, UserPointer::UP_KART,
|
||||
(Kart*)movB, UserPointer::UP_KART ));
|
||||
|
||||
}
|
||||
if(upB->is(UserPointer::UP_TRACK))
|
||||
upA->getPointerKart()->crashed(); // Kart hit track
|
||||
else if(upB->is(UserPointer::UP_PROJECTILE))
|
||||
m_all_collisions.push_back(upB, upA); // 2.1 projectile hits kart
|
||||
else if(upB->is(UserPointer::UP_KART))
|
||||
m_all_collisions.push_back(upA, upB); // 2.2 kart hits kart
|
||||
}
|
||||
// 3) object is a projectile
|
||||
// ========================
|
||||
else if(movA->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
||||
else if(upA->is(UserPointer::UP_PROJECTILE))
|
||||
{
|
||||
if(!movB)
|
||||
{ // 3.1) projectile hits track
|
||||
// --------------------------
|
||||
m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
|
||||
NULL, UserPointer::UP_TRACK ));
|
||||
}
|
||||
else if(movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
||||
{ // 3.2 projectile hits projectile
|
||||
// ------------------------------
|
||||
m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
|
||||
movB, UserPointer::UP_PROJECTILE));
|
||||
}
|
||||
else if(movB->getUserPointerType()==UserPointer::UP_KART)
|
||||
{ // 3.3 projectile hits kart
|
||||
// ------------------------
|
||||
m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
|
||||
(Kart*)movB, UserPointer::UP_KART ));
|
||||
if(upB->is(UserPointer::UP_TRACK ) || // 3.1) projectile hits track
|
||||
upB->is(UserPointer::UP_PROJECTILE) || // 3.2) projectile hits projectile
|
||||
upB->is(UserPointer::UP_KART ) ) // 3.3) projectile hits kart
|
||||
{
|
||||
m_all_collisions.push_back(upA, upB);
|
||||
}
|
||||
}
|
||||
// 4) Nothing else should happen
|
||||
// =============================
|
||||
else
|
||||
{
|
||||
assert("Unknown user pointer");
|
||||
}
|
||||
else assert("Unknown user pointer"); // 4) Should never happen
|
||||
} // for i<numManifolds
|
||||
|
||||
return returnValue;
|
||||
|
@ -46,21 +46,21 @@ private:
|
||||
// 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 being used here.
|
||||
// a simple list and linear search is faster is is being used here.
|
||||
|
||||
class CollisionPair {
|
||||
public:
|
||||
void *a, *b;
|
||||
UserPointer::UserPointerType type_a, type_b;
|
||||
const UserPointer* a, *b;
|
||||
|
||||
// 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
|
||||
CollisionPair(void *a1, UserPointer::UserPointerType atype,
|
||||
void *b1, UserPointer::UserPointerType btype) {
|
||||
if(atype==Moveable::UP_KART && btype==Moveable::UP_KART && a1>b1) {
|
||||
a=b1;b=a1; type_a=btype; type_b=atype;
|
||||
CollisionPair(const UserPointer *a1, const UserPointer *b1) {
|
||||
if(a1->is(UserPointer::UP_KART) &&
|
||||
b1->is(UserPointer::UP_KART) && a1>b1) {
|
||||
a=b1;b=a1;
|
||||
} else {
|
||||
a=a1; b=b1; type_a=atype; type_b=btype;
|
||||
a=a1; b=b1;
|
||||
}
|
||||
}; // CollisionPair
|
||||
bool operator==(const CollisionPair p) {
|
||||
@ -71,14 +71,18 @@ private:
|
||||
// This class is the list of collision objects, where each collision
|
||||
// pair is stored as most once.
|
||||
class CollisionList : public std::vector<CollisionPair> {
|
||||
public:
|
||||
void push_back(CollisionPair p) {
|
||||
private:
|
||||
void push_back(CollisionPair p) {
|
||||
// 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);
|
||||
}; // push_back
|
||||
public:
|
||||
void push_back(const UserPointer* a, const UserPointer*b) {
|
||||
push_back(CollisionPair(a, b));
|
||||
}
|
||||
};
|
||||
|
||||
CollisionList m_all_collisions;
|
||||
|
@ -58,7 +58,8 @@ void TriangleMesh::createBody(btCollisionObject::CollisionFlags flags)
|
||||
m_body=new btRigidBody(0.0f, m_motion_state, m_collision_shape);
|
||||
|
||||
world->getPhysics()->addBody(m_body);
|
||||
m_body->setUserPointer(this);
|
||||
m_user_pointer.set(UserPointer::UP_TRACK, this);
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
m_body->setCollisionFlags(m_body->getCollisionFlags() |
|
||||
flags |
|
||||
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
|
@ -28,15 +28,17 @@
|
||||
/** A special class to store a triangle mesh with a separate material
|
||||
* per triangle.
|
||||
*/
|
||||
class TriangleMesh : public UserPointer
|
||||
class TriangleMesh
|
||||
{
|
||||
private:
|
||||
UserPointer m_user_pointer;
|
||||
std::vector<const Material*> m_triangleIndex2Material;
|
||||
btRigidBody *m_body;
|
||||
btTriangleMesh m_mesh;
|
||||
btDefaultMotionState *m_motion_state;
|
||||
btCollisionShape *m_collision_shape;
|
||||
public:
|
||||
TriangleMesh(): UserPointer(UserPointer::UP_TRACK), m_mesh() {};
|
||||
TriangleMesh() : m_mesh() {};
|
||||
~TriangleMesh();
|
||||
void addTriangle(btVector3 t1, btVector3 t2, btVector3 t3,
|
||||
const Material* m);
|
||||
|
@ -23,18 +23,29 @@
|
||||
/** Some bullet objects store 'user pointers'. This is a base class
|
||||
* that allows to easily determine the type of the user pointer.
|
||||
*/
|
||||
class TriangleMesh;
|
||||
class Moveable;
|
||||
class Flyable;
|
||||
class Kart;
|
||||
|
||||
class UserPointer
|
||||
{
|
||||
public:
|
||||
enum UserPointerType {UP_UNDEF, UP_KART, UP_PROJECTILE, UP_TRACK} ;
|
||||
protected:
|
||||
enum UserPointerType {UP_UNDEF, UP_KART, UP_PROJECTILE, UP_TRACK};
|
||||
private:
|
||||
void* m_pointer;
|
||||
UserPointerType m_user_pointer_type;
|
||||
public:
|
||||
UserPointerType getUserPointerType() const {return m_user_pointer_type;}
|
||||
void setUserPointerType(UserPointerType t)
|
||||
{ m_user_pointer_type=t; }
|
||||
UserPointer(): m_user_pointer_type(UP_UNDEF) {};
|
||||
UserPointer(UserPointerType t): m_user_pointer_type(t) {};
|
||||
bool is(UserPointerType t) const {return m_user_pointer_type==t; }
|
||||
TriangleMesh* getPointerTriangleMesh() const {return (TriangleMesh*)m_pointer;}
|
||||
Moveable* getPointerMoveable() const {return (Moveable*)m_pointer; }
|
||||
Flyable* getPointerFlyable() const {return (Flyable*)m_pointer; }
|
||||
Kart* getPointerKart() const {return (Kart*)m_pointer; }
|
||||
void set(UserPointerType t, void* p)
|
||||
{ m_user_pointer_type=t;
|
||||
m_pointer =p; }
|
||||
UserPointer(): m_user_pointer_type(UP_UNDEF),m_pointer(NULL) {};
|
||||
UserPointer(UserPointerType t, void* p) {set(t,p);}
|
||||
};
|
||||
#endif
|
||||
/* EOF */
|
||||
|
Loading…
Reference in New Issue
Block a user