/* core/physics.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include #include "btBulletDynamicsCommon.h" #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" #include "model/collisionmesh.h" #include "core/physics.h" #include "core/zone.h" namespace core { /* ---- Bullet collision callbacks --------------------------------- */ //extern ContactAddedCallback gContactAddedCallback; /* * see http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Callbacks_and_Triggers */ #if (BT_BULLET_VERSION < 281) // bullet 2.80 or older 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()); #else // bullet 2.81 or newer bool bullet_contact_added_callback(btManifoldPoint &cp, const btCollisionObjectWrapper *body0, int partId0, int index0, const btCollisionObjectWrapper *body1, int partId1, int index1) { Entity *entity0 = static_cast(body0->getCollisionObject()->getUserPointer()); Entity *entity1 = static_cast(body1->getCollisionObject()->getUserPointer()); #endif 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) || (entity0->type() == Entity::Projectile)) { static_cast(entity0)->collision(entity1); } if ((entity1->type() == Entity::Dynamic) || (entity1->type() == Entity::Controlable) || (entity1->type() == Entity::Projectile)) { static_cast(entity1)->collision(entity0); } // 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; void Physics::init() { con_print << "^BInitializing physics engine..." << std::endl; model::CollisionModel::init(); physics_configuration = new btDefaultCollisionConfiguration(); 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() { con_print << "^BShutting down physics engine..." << std::endl; model::CollisionModel::shutdown(); delete physics_solver; delete physics_dispatcher; delete physics_configuration; physics_configuration = 0; physics_dispatcher = 0; physics_solver = 0; } void Physics::frame(const unsigned long elapsed) { const float seconds = (float) elapsed / 1000.0f; for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { (*it).second->physics()->stepSimulation(seconds, 8); } } } // namespace core