From 05c560e7b9f508997a7c7c5e466329692796dab4 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 10 Oct 2012 21:27:41 +0000 Subject: Provided bullet physics collision callback methods. --- src/core/entity.cc | 22 +++++++++++++++++++++- src/core/entity.h | 10 ++++++++++ src/core/physics.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/entity.cc b/src/core/entity.cc index 1b879f3..46bcd5d 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -646,6 +646,7 @@ void Entity::reset() //entity_body->setActivationState(ISLAND_SLEEPING); entity_body->setActivationState(WANTS_DEACTIVATION); entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); + entity_body->setUserPointer((void *) this); if (zone()) zone()->physics()->addRigidBody(entity_body); @@ -779,6 +780,10 @@ void EntityDynamic::reset() // create physics body entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); + // point the bullet user pointer to the entity + entity_body->setUserPointer((void *) this); + // enable custom collision callback + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); if (entity_mass) { entity_body->setActivationState(DISABLE_DEACTIVATION); @@ -800,6 +805,9 @@ void EntityDynamic::reset() motionstate()->setWorldTransform(t); } + /* Does not work + + if (entity_mass) { if (entity_state == Docked) { entity_body->setActivationState(DISABLE_SIMULATION); @@ -809,6 +817,7 @@ void EntityDynamic::reset() entity_body->setActivationState(DISABLE_DEACTIVATION); } } + */ set_dirty(); } @@ -845,6 +854,10 @@ void EntityDynamic::frame(const unsigned long elapsed) } } +void EntityDynamic::collision(Entity *other) +{ +} + void EntityDynamic::serialize_server_create(std::ostream & os) const { Entity::serialize_server_create(os); @@ -1253,6 +1266,11 @@ void EntityControlable::reset() entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); entity_body->setActivationState(DISABLE_DEACTIVATION); + // point the bullet user pointer to the entity + entity_body->setUserPointer((void *) this); + // enable custom collision callback + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + //entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); entity_actioninterface = new ActionInterface(this); @@ -1269,6 +1287,8 @@ void EntityControlable::reset() body()->setWorldTransform(t); motionstate()->setWorldTransform(t); + /* Does not work + if (entity_state == Docked) { entity_body->setActivationState(DISABLE_SIMULATION); entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); @@ -1276,7 +1296,7 @@ void EntityControlable::reset() entity_body->setActivationState(DISABLE_DEACTIVATION); entity_body->setCollisionFlags(entity_body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE); } - + */ set_dirty(); } diff --git a/src/core/entity.h b/src/core/entity.h index 19e47bc..092f4a7 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -630,6 +630,16 @@ public: * @brief reset the physics state */ virtual void reset(); + + /** + * @brief physics collision callback + * This funcion is called by the physics engine if the entity collides with another entity. + * It can be implemented by game child classes to provide collision effects and feedback. + * If the collision happens between two EntityDynamic instances (or subclasses thereof) + * the method will be called on each collision partner. + * Warning: this can be called multiple times for a single collision + * */ + virtual void collision(Entity *other); protected: float entity_mass; diff --git a/src/core/physics.cc b/src/core/physics.cc index 9ffe13c..2c7dd96 100644 --- a/src/core/physics.cc +++ b/src/core/physics.cc @@ -8,10 +8,47 @@ #include "core/physics.h" #include "core/zone.h" +#include "btBulletDynamicsCommon.h" #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" namespace core { +/* ---- Bullet collision callbacks --------------------------------- */ + +//extern ContactAddedCallback gContactAddedCallback; + +/* + * see http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Callbacks_and_Triggers + */ + +bool bullet_contact_added_callback(btManifoldPoint &cp, const btCollisionObject *body0, int partId0, int index0, const btCollisionObject *body1, int partId1, int index1) +{ + Entity *entity0 = static_cast(body0->getUserPointer()); + Entity *entity1 = static_cast(body1->getUserPointer()); + + assert(entity0 && entity1); + + // FIXME there should probably be an entity flag indiciating wether or not it has a collision callback + + if ((entity0->type() == Entity::Dynamic) || (entity0->type() == Entity::Controlable)) { + static_cast(entity0)->collision(entity1); + } + + if ((entity1->type() == Entity::Dynamic) || (entity1->type() == Entity::Controlable)) { + static_cast(entity1)->collision(entity0); + } + //con_debug << "collision " << entity0->label() << " - " << entity1->label() << std::endl; + + // the return value should be ignored by bullet. + return true; +} + +//bool bullet_contact_processed_callback(btManifoldPoint& cp,void* body0, void* body1); + +//bool bullet_contact_destroyed_callback(void* userPersistentData); + +/* ---- Bullet physics engine and algorithms ----------------------- */ + btDefaultCollisionConfiguration *Physics::physics_configuration = 0; btCollisionDispatcher *Physics::physics_dispatcher = 0; btSequentialImpulseConstraintSolver *Physics::physics_solver = 0; @@ -26,6 +63,9 @@ void Physics::init() physics_dispatcher = new btCollisionDispatcher(physics_configuration); btGImpactCollisionAlgorithm::registerAlgorithm(physics_dispatcher); physics_solver = new btSequentialImpulseConstraintSolver; + + // set custom bullet callbacks + gContactAddedCallback = bullet_contact_added_callback; } void Physics::done() -- cgit v1.2.3