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_shape = NULL;
|
||||||
m_mass = 1.0f;
|
m_mass = 1.0f;
|
||||||
|
|
||||||
setUserPointerType(UP_PROJECTILE);
|
|
||||||
// Add the graphical model
|
// Add the graphical model
|
||||||
ssgTransform *m = getModelTransform();
|
ssgTransform *m = getModelTransform();
|
||||||
m->addKid(m_st_model[type]);
|
m->addKid(m_st_model[type]);
|
||||||
@ -92,7 +91,8 @@ void Flyable::createPhysics(float y_offset, const btVector3 velocity,
|
|||||||
trans *= offset_transform;
|
trans *= offset_transform;
|
||||||
|
|
||||||
m_shape = shape;
|
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());
|
world->getPhysics()->addBody(getBody());
|
||||||
|
|
||||||
// Simplified rockets: no gravity
|
// Simplified rockets: no gravity
|
||||||
@ -106,7 +106,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 velocity,
|
|||||||
m_body->setLinearVelocity(v);
|
m_body->setLinearVelocity(v);
|
||||||
m_body->setAngularFactor(0.0f); // prevent rotations
|
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
|
// FIXME: for now it is necessary to synch the graphical position with the
|
||||||
// physical position, since 'hot' computation is done using the
|
// physical position, since 'hot' computation is done using the
|
||||||
|
@ -198,8 +198,8 @@ void Kart::createPhysics(ssgEntity *obj)
|
|||||||
// --------------------
|
// --------------------
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setIdentity();
|
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_body->setDamping(m_kart_properties->getChassisLinearDamping(),
|
||||||
m_kart_properties->getChassisAngularDamping() );
|
m_kart_properties->getChassisAngularDamping() );
|
||||||
|
|
||||||
|
@ -78,8 +78,7 @@ void Moveable::reset ()
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Moveable::createBody(float mass, btTransform& trans,
|
void Moveable::createBody(float mass, btTransform& trans,
|
||||||
btCollisionShape *shape,
|
btCollisionShape *shape) {
|
||||||
UserPointer::UserPointerType t) {
|
|
||||||
|
|
||||||
btVector3 inertia;
|
btVector3 inertia;
|
||||||
shape->calculateLocalInertia(mass, inertia);
|
shape->calculateLocalInertia(mass, inertia);
|
||||||
@ -89,8 +88,11 @@ void Moveable::createBody(float mass, btTransform& trans,
|
|||||||
// ------------------------
|
// ------------------------
|
||||||
m_body = new btRigidBody(mass, m_motion_state,
|
m_body = new btRigidBody(mass, m_motion_state,
|
||||||
shape, inertia);
|
shape, inertia);
|
||||||
m_body->setUserPointer(this);
|
// This MUST actually be set from the actual class, otherwise this
|
||||||
setUserPointerType(t);
|
// 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
|
} // createBody
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -32,11 +32,12 @@
|
|||||||
#define MAX_HERRING_EATEN 20
|
#define MAX_HERRING_EATEN 20
|
||||||
|
|
||||||
|
|
||||||
class Moveable : public UserPointer
|
class Moveable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
btVector3 m_velocityLC; /* velocity in kart coordinates */
|
btVector3 m_velocityLC; /* velocity in kart coordinates */
|
||||||
protected:
|
protected:
|
||||||
|
UserPointer m_user_pointer;
|
||||||
sgCoord m_reset_pos; /* Where to start in case of a reset */
|
sgCoord m_reset_pos; /* Where to start in case of a reset */
|
||||||
sgCoord m_curr_pos; /* current position */
|
sgCoord m_curr_pos; /* current position */
|
||||||
sgVec4* m_normal_hot; /* plane on which HOT was computed */
|
sgVec4* m_normal_hot; /* plane on which HOT was computed */
|
||||||
@ -47,9 +48,6 @@ protected:
|
|||||||
int m_crashed;
|
int m_crashed;
|
||||||
sgVec3 m_surface_avoidance_vector ;
|
sgVec3 m_surface_avoidance_vector ;
|
||||||
int m_first_time ;
|
int m_first_time ;
|
||||||
#ifndef BULLET
|
|
||||||
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
|
||||||
#endif
|
|
||||||
sgCoord* m_history_velocity;
|
sgCoord* m_history_velocity;
|
||||||
sgCoord* m_history_position;
|
sgCoord* m_history_position;
|
||||||
btRigidBody* m_body;
|
btRigidBody* m_body;
|
||||||
@ -58,9 +56,6 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* start - New Physics */
|
|
||||||
|
|
||||||
|
|
||||||
Moveable (bool bHasHistory=false);
|
Moveable (bool bHasHistory=false);
|
||||||
virtual ~Moveable();
|
virtual ~Moveable();
|
||||||
|
|
||||||
@ -80,9 +75,7 @@ public:
|
|||||||
void ReadHistory (char* s, int kartNumber, int indx);
|
void ReadHistory (char* s, int kartNumber, int indx);
|
||||||
btRigidBody* getBody () const {return m_body; }
|
btRigidBody* getBody () const {return m_body; }
|
||||||
void createBody(float mass, btTransform& trans,
|
void createBody(float mass, btTransform& trans,
|
||||||
btCollisionShape *shape,
|
btCollisionShape *shape);
|
||||||
UserPointer::UserPointerType t);
|
|
||||||
//void getTrans (btTransform& t) const {m_motion_state->getWorldTransform(t);}
|
|
||||||
const btTransform& getTrans() const {return m_transform;}
|
const btTransform& getTrans() const {return m_transform;}
|
||||||
void setTrans (btTransform& t){m_transform=t;m_motion_state->setWorldTransform(t);}
|
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;
|
std::vector<CollisionPair>::iterator p;
|
||||||
for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
|
for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
|
||||||
{
|
{
|
||||||
if(p->type_a==UserPointer::UP_KART) { // kart-kart collision
|
if(p->a->is(UserPointer::UP_KART)) { // kart-kart collision
|
||||||
Kart *kartA = (Kart*)(p->a);
|
KartKartCollision(p->a->getPointerKart(), p->b->getPointerKart());
|
||||||
Kart *kartB = (Kart*)(p->b);
|
|
||||||
KartKartCollision(kartA, kartB);
|
|
||||||
} // if kart-kart collision
|
} // if kart-kart collision
|
||||||
else // now the first object must be a projectile
|
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);
|
p->a->getPointerFlyable()->explode((Kart*)(p->b));
|
||||||
f->explode((Kart*)(p->b));
|
|
||||||
}
|
}
|
||||||
else // projectile hits projectile
|
else // projectile hits projectile
|
||||||
{
|
{
|
||||||
((Flyable*)(p->a))->explode(NULL);
|
p->a->getPointerFlyable()->explode(NULL);
|
||||||
((Flyable*)(p->b))->explode(NULL);
|
p->b->getPointerFlyable()->explode(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for all p in m_all_collisions
|
} // for all p in m_all_collisions
|
||||||
@ -199,76 +196,41 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
|||||||
int numContacts = contactManifold->getNumContacts();
|
int numContacts = contactManifold->getNumContacts();
|
||||||
if(!numContacts) continue; // no real collision
|
if(!numContacts) continue; // no real collision
|
||||||
|
|
||||||
Moveable *movA = static_cast<Moveable*>(objA->getUserPointer());
|
UserPointer *upA = (UserPointer*)(objA->getUserPointer());
|
||||||
Moveable *movB = static_cast<Moveable*>(objB->getUserPointer());
|
UserPointer *upB = (UserPointer*)(objB->getUserPointer());
|
||||||
|
|
||||||
// 1) object A is a track
|
// 1) object A is a track
|
||||||
// =======================
|
// =======================
|
||||||
if(!movA)
|
if(upA->is(UserPointer::UP_TRACK))
|
||||||
{
|
{
|
||||||
if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
if(upB->is(UserPointer::UP_PROJECTILE)) // 1.1 projectile hits track
|
||||||
{ // 1.1 projectile hits track
|
m_all_collisions.push_back(upB, upA);
|
||||||
// -------------------------
|
else if(upB->is(UserPointer::UP_KART))
|
||||||
m_all_collisions.push_back(CollisionPair(movB, UserPointer::UP_PROJECTILE,
|
upB->getPointerKart()->crashed();
|
||||||
NULL, UserPointer::UP_TRACK ));
|
|
||||||
}
|
|
||||||
else if(movB && movB->getUserPointerType()==UserPointer::UP_KART)
|
|
||||||
{
|
|
||||||
((Kart*)movB)->crashed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 2) object a is a kart
|
// 2) object a is a kart
|
||||||
// =====================
|
// =====================
|
||||||
else if(movA->getUserPointerType()==UserPointer::UP_KART)
|
else if(upA->is(UserPointer::UP_KART))
|
||||||
{
|
{
|
||||||
if(!movB)
|
if(upB->is(UserPointer::UP_TRACK))
|
||||||
{ // The casts here are important, otherwise re-casting the
|
upA->getPointerKart()->crashed(); // Kart hit track
|
||||||
// pointers later in kart-kart does not work as expected.
|
else if(upB->is(UserPointer::UP_PROJECTILE))
|
||||||
((Kart*)movA)->crashed();
|
m_all_collisions.push_back(upB, upA); // 2.1 projectile hits kart
|
||||||
}
|
else if(upB->is(UserPointer::UP_KART))
|
||||||
else if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
m_all_collisions.push_back(upA, upB); // 2.2 kart hits kart
|
||||||
{ // 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 ));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 3) object is a projectile
|
// 3) object is a projectile
|
||||||
// ========================
|
// ========================
|
||||||
else if(movA->getUserPointerType()==UserPointer::UP_PROJECTILE)
|
else if(upA->is(UserPointer::UP_PROJECTILE))
|
||||||
{
|
{
|
||||||
if(!movB)
|
if(upB->is(UserPointer::UP_TRACK ) || // 3.1) projectile hits 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(CollisionPair(movA, UserPointer::UP_PROJECTILE,
|
{
|
||||||
NULL, UserPointer::UP_TRACK ));
|
m_all_collisions.push_back(upA, upB);
|
||||||
}
|
|
||||||
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 ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 4) Nothing else should happen
|
else assert("Unknown user pointer"); // 4) Should never happen
|
||||||
// =============================
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert("Unknown user pointer");
|
|
||||||
}
|
|
||||||
} // for i<numManifolds
|
} // for i<numManifolds
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
@ -46,21 +46,21 @@ private:
|
|||||||
// While this is a natural application of std::set, the set has some
|
// 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).
|
// overhead (since it will likely use a tree to sort the entries).
|
||||||
// Considering that the number of collisions is usually rather small
|
// 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 {
|
class CollisionPair {
|
||||||
public:
|
public:
|
||||||
void *a, *b;
|
const UserPointer* a, *b;
|
||||||
UserPointer::UserPointerType type_a, type_b;
|
|
||||||
// The entries in Collision Pairs are sorted: if a projectile
|
// The entries in Collision Pairs are sorted: if a projectile
|
||||||
// is included, it's always 'a'. If only two karts are reported
|
// is included, it's always 'a'. If only two karts are reported
|
||||||
// the first kart pointer is the smaller one
|
// the first kart pointer is the smaller one
|
||||||
CollisionPair(void *a1, UserPointer::UserPointerType atype,
|
CollisionPair(const UserPointer *a1, const UserPointer *b1) {
|
||||||
void *b1, UserPointer::UserPointerType btype) {
|
if(a1->is(UserPointer::UP_KART) &&
|
||||||
if(atype==Moveable::UP_KART && btype==Moveable::UP_KART && a1>b1) {
|
b1->is(UserPointer::UP_KART) && a1>b1) {
|
||||||
a=b1;b=a1; type_a=btype; type_b=atype;
|
a=b1;b=a1;
|
||||||
} else {
|
} else {
|
||||||
a=a1; b=b1; type_a=atype; type_b=btype;
|
a=a1; b=b1;
|
||||||
}
|
}
|
||||||
}; // CollisionPair
|
}; // CollisionPair
|
||||||
bool operator==(const CollisionPair p) {
|
bool operator==(const CollisionPair p) {
|
||||||
@ -71,14 +71,18 @@ private:
|
|||||||
// This class is the list of collision objects, where each collision
|
// This class is the list of collision objects, where each collision
|
||||||
// pair is stored as most once.
|
// pair is stored as most once.
|
||||||
class CollisionList : public std::vector<CollisionPair> {
|
class CollisionList : public std::vector<CollisionPair> {
|
||||||
public:
|
private:
|
||||||
void push_back(CollisionPair p) {
|
void push_back(CollisionPair p) {
|
||||||
// only add a pair if it's not already in there
|
// only add a pair if it's not already in there
|
||||||
for(iterator i=begin(); i!=end(); i++) {
|
for(iterator i=begin(); i!=end(); i++) {
|
||||||
if((*i)==p) return;
|
if((*i)==p) return;
|
||||||
}
|
}
|
||||||
std::vector<CollisionPair>::push_back(p);
|
std::vector<CollisionPair>::push_back(p);
|
||||||
}; // push_back
|
}; // push_back
|
||||||
|
public:
|
||||||
|
void push_back(const UserPointer* a, const UserPointer*b) {
|
||||||
|
push_back(CollisionPair(a, b));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CollisionList m_all_collisions;
|
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);
|
m_body=new btRigidBody(0.0f, m_motion_state, m_collision_shape);
|
||||||
|
|
||||||
world->getPhysics()->addBody(m_body);
|
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() |
|
m_body->setCollisionFlags(m_body->getCollisionFlags() |
|
||||||
flags |
|
flags |
|
||||||
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||||
|
@ -28,15 +28,17 @@
|
|||||||
/** A special class to store a triangle mesh with a separate material
|
/** A special class to store a triangle mesh with a separate material
|
||||||
* per triangle.
|
* per triangle.
|
||||||
*/
|
*/
|
||||||
class TriangleMesh : public UserPointer
|
class TriangleMesh
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
UserPointer m_user_pointer;
|
||||||
std::vector<const Material*> m_triangleIndex2Material;
|
std::vector<const Material*> m_triangleIndex2Material;
|
||||||
btRigidBody *m_body;
|
btRigidBody *m_body;
|
||||||
btTriangleMesh m_mesh;
|
btTriangleMesh m_mesh;
|
||||||
btDefaultMotionState *m_motion_state;
|
btDefaultMotionState *m_motion_state;
|
||||||
btCollisionShape *m_collision_shape;
|
btCollisionShape *m_collision_shape;
|
||||||
public:
|
public:
|
||||||
TriangleMesh(): UserPointer(UserPointer::UP_TRACK), m_mesh() {};
|
TriangleMesh() : m_mesh() {};
|
||||||
~TriangleMesh();
|
~TriangleMesh();
|
||||||
void addTriangle(btVector3 t1, btVector3 t2, btVector3 t3,
|
void addTriangle(btVector3 t1, btVector3 t2, btVector3 t3,
|
||||||
const Material* m);
|
const Material* m);
|
||||||
|
@ -23,18 +23,29 @@
|
|||||||
/** Some bullet objects store 'user pointers'. This is a base class
|
/** Some bullet objects store 'user pointers'. This is a base class
|
||||||
* that allows to easily determine the type of the user pointer.
|
* that allows to easily determine the type of the user pointer.
|
||||||
*/
|
*/
|
||||||
|
class TriangleMesh;
|
||||||
|
class Moveable;
|
||||||
|
class Flyable;
|
||||||
|
class Kart;
|
||||||
|
|
||||||
class UserPointer
|
class UserPointer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum UserPointerType {UP_UNDEF, UP_KART, UP_PROJECTILE, UP_TRACK} ;
|
enum UserPointerType {UP_UNDEF, UP_KART, UP_PROJECTILE, UP_TRACK};
|
||||||
protected:
|
private:
|
||||||
|
void* m_pointer;
|
||||||
UserPointerType m_user_pointer_type;
|
UserPointerType m_user_pointer_type;
|
||||||
public:
|
public:
|
||||||
UserPointerType getUserPointerType() const {return m_user_pointer_type;}
|
bool is(UserPointerType t) const {return m_user_pointer_type==t; }
|
||||||
void setUserPointerType(UserPointerType t)
|
TriangleMesh* getPointerTriangleMesh() const {return (TriangleMesh*)m_pointer;}
|
||||||
{ m_user_pointer_type=t; }
|
Moveable* getPointerMoveable() const {return (Moveable*)m_pointer; }
|
||||||
UserPointer(): m_user_pointer_type(UP_UNDEF) {};
|
Flyable* getPointerFlyable() const {return (Flyable*)m_pointer; }
|
||||||
UserPointer(UserPointerType t): m_user_pointer_type(t) {};
|
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
|
#endif
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
Loading…
Reference in New Issue
Block a user