diff --git a/src/flyable.cpp b/src/flyable.cpp index 85192f953..35c19bb72 100644 --- a/src/flyable.cpp +++ b/src/flyable.cpp @@ -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 diff --git a/src/kart.cpp b/src/kart.cpp index 91b973169..bf606d90d 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -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() ); diff --git a/src/moveable.cpp b/src/moveable.cpp index 605eccf52..cd92ecfa2 100644 --- a/src/moveable.cpp +++ b/src/moveable.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/moveable.hpp b/src/moveable.hpp index 168851405..7752ec3bb 100644 --- a/src/moveable.hpp +++ b/src/moveable.hpp @@ -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);} } diff --git a/src/physics.cpp b/src/physics.cpp index 7f0ad201e..abaf3ab77 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -103,26 +103,23 @@ void Physics::update(float dt) std::vector::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(objA->getUserPointer()); - Moveable *movB = static_cast(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 ib1) { - 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 { - 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::push_back(p); }; // push_back + public: + void push_back(const UserPointer* a, const UserPointer*b) { + push_back(CollisionPair(a, b)); + } }; CollisionList m_all_collisions; diff --git a/src/triangle_mesh.cpp b/src/triangle_mesh.cpp index 4a6bd9204..345b7e92e 100644 --- a/src/triangle_mesh.cpp +++ b/src/triangle_mesh.cpp @@ -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); diff --git a/src/triangle_mesh.hpp b/src/triangle_mesh.hpp index f26e5e85c..6b77a1d2e 100644 --- a/src/triangle_mesh.hpp +++ b/src/triangle_mesh.hpp @@ -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 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); diff --git a/src/user_pointer.hpp b/src/user_pointer.hpp index 6b49f0aea..f9bb03e87 100644 --- a/src/user_pointer.hpp +++ b/src/user_pointer.hpp @@ -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 */