void World:: reset() { btCollisionObjectArray a = dynamicsWorld->getCollisionObjectArray(); for (int i = 0; i < a.size(); i++) { auto o = a[i]; if (!o->isStaticOrKinematicObject()) { std::cout << "Object: " << o->getUserPointer() << std::endl; btTransform t = o->getWorldTransform(); btVector3 v = t.getOrigin(); if (v.getY() < -10) { std::shared_ptr<app::gl::AppObject> new_object; dynamicsWorld->removeCollisionObject(o); for (auto i = objects.begin(); i != objects.end(); ++i) { if (i->get() == o->getUserPointer()) { new_object = std::make_shared<app::gl::AppObject>(*(i->get())); v.setX(disx(gen)); v.setY(disy(gen)); v.setZ(disz(gen)); t.setOrigin(v); new_object->setWorldTransform(t); objects.erase(i); break; } } addToWorld(new_object, btRigidBody::btRigidBodyConstructionInfo(new_object->getMass(), nullptr, nullptr, new_object->getInitialInertia())); } else { v.setX(disx(gen)); v.setY(disy(gen)); v.setZ(disz(gen)); t.setOrigin(v); o->setWorldTransform(t); o->setInterpolationLinearVelocity(btVector3(0,0,0)); o->setInterpolationAngularVelocity(btVector3(0,0,0)); o->setActivationState(1); o->activate(true); } } } }
bool GameWorld::ContactProcessedCallback(btManifoldPoint &mp, void *body0, void *body1) { auto obA = static_cast<btCollisionObject*>(body0); auto obB = static_cast<btCollisionObject*>(body1); if( !( obA->getUserPointer() && obB->getUserPointer() ) ) { return false; } GameObject* a = static_cast<GameObject*>(obA->getUserPointer()); GameObject* b = static_cast<GameObject*>(obB->getUserPointer()); bool valA = a && a->type() == GameObject::Instance; bool valB = b && b->type() == GameObject::Instance; if( ! (valA && valB) && (valB || valA) ) { // Figure out which is the dynamic instance. InstanceObject* dynInst = nullptr; const btRigidBody* instBody = nullptr, * otherBody = nullptr; btVector3 src, dmg; if( valA ) { dynInst = static_cast<InstanceObject*>(a); instBody = static_cast<const btRigidBody*>(obA); otherBody = static_cast<const btRigidBody*>(obB); src = mp.getPositionWorldOnB(); dmg = mp.getPositionWorldOnA(); } else { dynInst = static_cast<InstanceObject*>(b); instBody = static_cast<const btRigidBody*>(obB); otherBody = static_cast<const btRigidBody*>(obA); src = mp.getPositionWorldOnA(); dmg = mp.getPositionWorldOnB(); } if( dynInst->dynamics != nullptr && instBody->isStaticObject() ) { // Attempt to determine relative velocity. auto dV = (otherBody->getLinearVelocity()); auto impulse = dV.length()/ (otherBody->getInvMass()); if( dynInst->dynamics->uprootForce <= impulse ) { dynInst->takeDamage({ {dmg.x(), dmg.y(), dmg.z()}, {src.x(), src.y(), src.z()}, 0.f, GameObject::DamageInfo::Physics, impulse }); } } } // Handle vehicles if(a) handleVehicleResponse(a, mp, true); if(b) handleVehicleResponse(b, mp, false); return true; }