void CapsuleDescription::draw(GraphicsBase* context){ context->drawCapsule(getRigidBody()->getPosition(), boost::static_pointer_cast<Capsule>(getGeometry())->getRadius(), boost::static_pointer_cast<Capsule>(getGeometry())->getHeight(), getRigidBody()->getOrientation(), GraphicsBase::materialStone); }
void tgRodInfo::initRigidBody(tgWorld& world) { tgRigidInfo::initRigidBody(world); assert(m_collisionObject != NULL); getRigidBody()->setFriction(m_config.friction); getRigidBody()->setRollingFriction(m_config.rollFriction); getRigidBody()->setRestitution(m_config.restitution); }
Simulator::Simulator (EntityHandler *_ents, NetworkHandler *_net): entities(_ents), networkHandler(_net), elapsedTime(0.0), running(false), simThread(nullptr) { // Create a default network handler if one wasn't passed to us. if (_net == nullptr) { networkHandler = new ZMQHandler(); } /// collision configuration contains default setup for memory, collision setup collisionConfiguration = new btDefaultCollisionConfiguration(); /// use the default collision dispatcher. For parallel processing you can /// use a diffent dispatcher (see Extras/BulletMultiThreaded) dispatcher = new btCollisionDispatcher(collisionConfiguration); dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE, BOX_SHAPE_PROXYTYPE, collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE, CONVEX_SHAPE_PROXYTYPE)); broadphase = new btDbvtBroadphase(); /// the default constraint solver. For parallel processing you can use a /// different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver(); solver = sol; dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); dynamicsWorld->getSolverInfo().m_splitImpulse = true; dynamicsWorld->getSolverInfo().m_numIterations = 20; dynamicsWorld->getDispatchInfo().m_useContinuous = 1; dynamicsWorld->setGravity(btVector3(0, -9.8, 0)); // Hook up our callback dynamicsWorld->setInternalTickCallback(simCallback, static_cast<void*>(this)); // Add all entities to our dynamics world, starting with the static // things. for (auto pr : entities->staticEnts) { auto ent = pr.second; if (ent->getRigidBody()) { // std::cout << "Adding static entity " << pr.first << std::endl; dynamicsWorld->addRigidBody(ent->getRigidBody()); } } for (auto pr : entities->dynamicEnts) { auto ent = pr.second; if (ent->getRigidBody()) { // std::cout << "Adding dynamic entity " << pr.first << std::endl; dynamicsWorld->addRigidBody(ent->getRigidBody()); } } }
std::vector<std::string> PhysicEngine::getCollisions(const std::string& name) { RigidBody* body = getRigidBody(name); if (!body) // fall back to raycasting body if there is no collision body body = getRigidBody(name, true); ContactTestResultCallback callback; dynamicsWorld->contactTest(body, callback); return callback.mResult; }
void Collectible::onPrepare( float dt ) { //update yaw setYaw(getYaw() + (SPIN_SPEED * dt)); //get bullet representation btMotionState *ms = getRigidBody()->getMotionState(); btTransform transform = getRigidBody()->getWorldTransform(); //update bullet representation btQuaternion q = btQuaternion(getYaw(), getPitch(), 0.0f); transform *= btTransform(q); ms->setWorldTransform(transform); }
void btRaycastVehicle::updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform) { wheel.m_raycastInfo.m_isInContact = false; btTransform chassisTrans = getChassisWorldTransform(); if (interpolatedTransform && (getRigidBody()->getMotionState())) { getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); } wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; }
glm::vec3 ObjectAction::getAngularVelocity() { auto rigidBody = getRigidBody(); if (!rigidBody) { return glm::vec3(0.0f); } return bulletToGLM(rigidBody->getAngularVelocity()); }
glm::quat ObjectAction::getRotation() { auto rigidBody = getRigidBody(); if (!rigidBody) { return glm::quat(0.0f, 0.0f, 0.0f, 1.0f); } return bulletToGLM(rigidBody->getOrientation()); }
glm::vec3 ObjectAction::getPosition() { auto rigidBody = getRigidBody(); if (!rigidBody) { return glm::vec3(0.0f); } return bulletToGLM(rigidBody->getCenterOfMassPosition()); }
//-------------------------------------------------------------- void ofxBulletTriMeshShape::updateMesh( btDiscreteDynamicsWorld* a_world, ofMesh& aMesh ) { if( aMesh.getNumVertices() != totalVerts || aMesh.getNumIndices() != totalIndices ) { ofLogWarning() << "updateMesh :: the verts or the indices are not the correct size, not updating"; return; } auto& tverts = aMesh.getVertices(); btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); for( int i = 0; i < totalVerts; i++ ) { auto& v = tverts[i]; bullet_vertices[i].setValue( v.x, v.y, v.z ); aabbMin.setMin( bullet_vertices[i] ); aabbMax.setMax( bullet_vertices[i] ); } btBvhTriangleMeshShape* triShape = (btBvhTriangleMeshShape*)_shape; // triShape->partialRefitTree( aabbMin, aabbMax ); triShape->refitTree( aabbMin, aabbMax ); //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. a_world->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs( getRigidBody()->getBroadphaseHandle(), a_world->getDispatcher()); }
void Magic3D::Object::updateMatrix() { if (getRigidBody()) { btTransform transform; getRigidBody()->getMotionState()->getWorldTransform(transform); btQuaternion q = transform.getRotation(); btVector3 v = transform.getOrigin(); if (getShapeRotation().getX() != 0.0f || getShapeRotation().getY() != 0.0f || getShapeRotation().getZ() != 0.0f) { rotation = Quaternion(q.getX(), q.getY(), getRender() == eRENDER_2D ? -q.getZ() : q.getZ(), q.getW()); } if (getRender() == eRENDER_2D) { position = Vector3((v.getX() + 1.0f - 1.0f), -(v.getY() + 1.0f - 1.0f), 0.0f); } else { position = Vector3(v.getX(), v.getY(), v.getZ()); } matrix = Matrix4(rotation, position) * Matrix4(Matrix3::identity(), -getShapePosition()); } else { matrix = Matrix4(rotation, position); } matrix = appendScale(matrix, scale); upward = matrix.getCol1().getXYZ(); forward = matrix.getCol2().getXYZ(); rightward = cross(forward, upward); std::vector<Object*>::const_iterator it_o = children.begin(); while (it_o != children.end()) { (*it_o++)->needTransform = true; } if (isNetworkSpawn()) { Network::getInstance()->sendObject(this, false); } needUpdateOctree = true; }
void ObjectAction::activateBody(bool forceActivation) { auto rigidBody = getRigidBody(); if (rigidBody) { rigidBody->activate(forceActivation); } else { qDebug() << "ObjectAction::activateBody -- no rigid body" << (void*)rigidBody; } }
void ObjectAction::setLinearVelocity(glm::vec3 linearVelocity) { auto rigidBody = getRigidBody(); if (!rigidBody) { return; } rigidBody->setLinearVelocity(glmToBullet(glm::vec3(0.0f))); rigidBody->activate(); }
void ObjectAction::setAngularVelocity(glm::vec3 angularVelocity) { auto rigidBody = getRigidBody(); if (!rigidBody) { return; } rigidBody->setAngularVelocity(glmToBullet(angularVelocity)); rigidBody->activate(); }
void ObjectDynamic::activateBody(bool forceActivation) { auto rigidBody = getRigidBody(); if (rigidBody) { rigidBody->activate(forceActivation); } else { qCDebug(physics) << "ObjectDynamic::activateBody -- no rigid body" << (void*)rigidBody; } }
void RigidCompoundObject::removeAllChildren() { btCompoundShape *shape = static_cast<btCompoundShape*>(getCollisionObject()->getCollisionShape()); while(shape->getNumChildShapes()) shape->removeChildShapeByIndex(0); shape->recalculateLocalAabb(); btVector3 inertia(0,0,0); float mass = getMass(); shape->calculateLocalInertia(mass, inertia); getRigidBody()->setMassProps(mass,inertia); SceneObject::removeAllChildren(); }
void RigidCompoundObject::addChild(RigidObject* obj, bool passOwnership) { SceneObject::addChild(obj,passOwnership); btCompoundShape *shape = static_cast<btCompoundShape*>(getCollisionObject()->getCollisionShape()); shape->addChildShape(icl2bullet_scaled_mat(obj->getTransformation()),obj->getCollisionObject()->getCollisionShape()); shape->recalculateLocalAabb(); btVector3 inertia(0,0,0); float mass = getMass(); shape->calculateLocalInertia(mass, inertia); getRigidBody()->setMassProps(mass,inertia); }
void RigidCompoundObject::removeChild(RigidObject* obj) { btCompoundShape *shape = static_cast<btCompoundShape*>(getCollisionObject()->getCollisionShape()); shape->removeChildShape(obj->getCollisionObject()->getCollisionShape()); shape->recalculateLocalAabb(); btVector3 inertia(0,0,0); float mass = getMass(); shape->calculateLocalInertia(mass, inertia); getRigidBody()->setMassProps(mass,inertia); SceneObject::removeChild(obj); }
void ObjectAction::setRotation(glm::quat rotation) { auto rigidBody = getRigidBody(); if (!rigidBody) { return; } // XXX // void setWorldTransform (const btTransform &worldTrans) assert(false); rigidBody->activate(); }
void gep::HavokRigidBodySyncAction::applyAction(const hkStepInfo& stepInfo) { const auto* rb = getRigidBody(); GEP_ASSERT(rb); hkUlong userData = rb->getUserData(); GEP_ASSERT(userData, "It seems you did not initialize your rigid body!"); reinterpret_cast<HavokRigidBody*>(userData)->triggerSimulationCallbacks(); }
const btTransform &btRaycastVehicle::getChassisWorldTransform() const { /*if (getRigidBody()->getMotionState()) { btTransform chassisWorldTrans; getRigidBody()->getMotionState()->getWorldTransform(chassisWorldTrans); return chassisWorldTrans; } */ return getRigidBody()->getCenterOfMassTransform(); }
void SceneEntity::refresh() { RigidBody *rigidBody = getRigidBody(); if(rigidBody) { if((!rigidBody->isStatic() && rigidBody->isActive()) || (rigidBody->isManuallyMovedAndResetFlag())) { moveTo(rigidBody->getTransform()); } } }
QList<btRigidBody*> ObjectConstraintSlider::getRigidBodies() { QList<btRigidBody*> result; result += getRigidBody(); QUuid otherEntityID; withReadLock([&]{ otherEntityID = _otherID; }); if (!otherEntityID.isNull()) { result += getOtherRigidBody(otherEntityID); } return result; }
btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btPoint2PointConstraint* constraint { nullptr }; QUuid otherEntityID; glm::vec3 pivotInA; glm::vec3 pivotInB; withReadLock([&]{ constraint = static_cast<btPoint2PointConstraint*>(_constraint); pivotInA = _pivotInA; otherEntityID = _otherID; pivotInB = _pivotInB; }); if (constraint) { return constraint; } static QString repeatedBallSocketNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( "ObjectConstraintBallSocket::getConstraint -- no rigidBody.*"); btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"; return nullptr; } if (!otherEntityID.isNull()) { // This constraint is between two entities... find the other rigid body. btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"; return nullptr; } constraint = new btPoint2PointConstraint(*rigidBodyA, *rigidBodyB, glmToBullet(pivotInA), glmToBullet(pivotInB)); } else { // This constraint is between an entity and the world-frame. constraint = new btPoint2PointConstraint(*rigidBodyA, glmToBullet(pivotInA)); } withWriteLock([&]{ _constraint = constraint; }); // if we don't wake up rigidBodyA, we may not send the dynamicData property over the network forceBodyNonStatic(); activateBody(); updateBallSocket(); return constraint; }
void PhysicsWorld::myProcessCallback(btScalar timestep) { for (int i = 0; i < m_projectileObjects.size(); i++) { auto objectA = m_projectileObjects[i].get(); if (!objectA->isActive()) continue; for (int j = 0; j < m_physicsEnemyObjects.size(); j++) { auto objectB = m_physicsEnemyObjects[j].get(); if (!objectA->isActive()) break; if (!objectB->isActive()) continue; btDrawingResult physicsCallback; physicsCallback.objectA = objectA; physicsCallback.objectB = objectB; m_world->contactPairTest(objectA->getRigidBody(), objectB->getRigidBody(), physicsCallback); } } }
void RaycastCar::updateVehicle( btScalar step ) { m_currentVehicleSpeedKmHour = btScalar(3.6f) * getRigidBody()->getLinearVelocity().length(); const btTransform & chassisTrans = getChassisWorldTransform(); btVector3 forwardW(chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.0f)) m_currentVehicleSpeedKmHour *= btScalar(-1.0f); for (int i = 0; i < getNumWheels(); i++) { updateWheelTransform(i, false); btScalar depth; depth = rayCast(m_wheelInfo[i]); } update_suspension(step); update_engine(step); update_forces(step); apply_impulses(step); }
tgModel* tgRodInfo::createModel(tgWorld& world) { // @todo: handle tags -> model // @todo: check to make sure the rigidBody has been built // @todo: Do we need to use the group here? // Just in case it hasn't been done already... initRigidBody(world); #if (0) std::cout << "creating rod with tags " << getTags() << std::endl; #endif tgRod* rod = new tgRod(getRigidBody(), getTags(), getLength()); return rod; }
// Draws a reddish box of the correct dimensions in OpenGL // using the transform provided by Bullet void Box::drawOpenGL() { // get the Bullet transform btTransform trans; getRigidBody()->getMotionState()->getWorldTransform(trans); // Bullet has a nice funciton for this. GLfloat glTrans[16]; trans.getOpenGLMatrix(glTrans); glPushMatrix(); glMultMatrixf(glTrans); GLfloat boxColor[4] = { 0.95, 0.7, 0.75, 1.0 }; glMaterialfv(GL_FRONT, GL_DIFFUSE, boxColor); // I'm cheating a bit here and using the glutSolidSphere // I would need to do this with more standard OpenGL calls to make // this more portable. glScaled(x, y, z); glutSolidCube(1.0); glPopMatrix(); }
bool Magic3D::Object::update() { if (Scene::getInstance()->getUniqueUpdateFlag() != uniqueUpdate) { uniqueUpdate = Scene::getInstance()->getUniqueUpdateFlag(); bool needTransformOld = needTransform; if (isEnabled()) { if (isScripted()) { std::string function_AI("AI"); Script::getInstance()->execute(function_AI, 0, getName()); } if (AI) { AI->AI(); } updateTweens(); } if (needTransform || (getRigidBody() && Physics::getInstance()->isPlaying() && getRigidBody()->getActivationState() != ISLAND_SLEEPING) || (getParent() && getParent()->isInFrustum())) { if (needTransform && !needTransformOld) { resetPhysics(); } needTransform = false; updateMatrix(); } } return true; }
GameObj* GOBox::shoot() { if (getIsWeapon()) { Weapon* w = getWeapon(); if (getIsRangedWeapon()){ if (((RangedWeapon *)w)->readyToShoot()) { double rbDepth = getDepth() / 2 + ((RangedWeapon *)w)->getPDepth()/1.5 + 0.6f; btTransform* rbTrans = &getRigidBody()->getWorldTransform(); btVector3 boxRot = rbTrans->getBasis()[2]; boxRot.normalize(); btVector3 correctedDisplacement = boxRot * -rbDepth; // /2 double x = rbTrans->getOrigin().getX();// + 0.5 - w->getPWidth(); double y = rbTrans->getOrigin().getY(); double z = rbTrans->getOrigin().getZ() + correctedDisplacement.getZ(); GameObj* proj = new Projectile(x, y, z, rbTrans->getRotation().getX(), rbTrans->getRotation().getY(), rbTrans->getRotation().getZ(), rbTrans->getRotation().getW(), ((RangedWeapon *)w)->getPMass(), ((RangedWeapon *)w)->getPWidth(), ((RangedWeapon *)w)->getPHeight(), ((RangedWeapon *)w)->getPDepth()); proj->setDamage(w->getDamage()); //std::cout << "shoot: " << ((RangedWeapon *)w)->getPBlockType() << std::endl; proj->setBlockType(((RangedWeapon *)w)->getPBlockType()); ((RangedWeapon *)w)->setLastShot(); ((Projectile*)proj)->initForce = ((RangedWeapon *)w)->getPInitForce(); return proj; } } } return nullptr; }