【问题标题】:Bullet Physics Library switching rigidbody between static_object and dynamic_objectBullet 物理库在 static_object 和 dynamic_object 之间切换刚体
【发布时间】:2014-10-07 06:28:53
【问题描述】:

我对 Bullet 还很陌生,我的目标是能够在静态和动态之间切换 btRigidBody。为了初始化我的刚体,我首先这样做:

btGImpactMeshShape* triMesh=new btGImpactMeshShape(mTriMesh);
triMesh->setLocalScaling(btVector3(1,1,1));
triMesh->updateBound();

meshInfos[currentMesh].shape=triMesh;
meshInfos[currentMesh].motionState=new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(position.x,position.y,position.z)));
meshInfos[currentMesh].mass=mass;

btVector3 inertia;
meshInfos[currentMesh].shape->calculateLocalInertia(mass, inertia);

btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, meshInfos[currentMesh].motionState, meshInfos[currentMesh].shape, inertia);
meshInfos[currentMesh].rigidBody=new btRigidBody(rigidBodyCI);

将其设置为 static_object 因为我拥有的“质量”变量从 0 开始。稍后我有一个函数可以检查是否打开了布尔值,并将刚体切换为动态对象,如下所示:

if(gravityOn && !addedToWorld)
{
    if(mass>0)
    {
        world->removeRigidBody(body);
        btVector3 inertia;
        body->getCollisionShape()->calculateLocalInertia(mass, inertia);
        body->setMassProps(mass, inertia);
        body->setLinearFactor(btVector3(1,1,1));
        body->setAngularFactor(btVector3(1,1,1));
        body->updateInertiaTensor();
        world->addRigidBody(body);
        addedToWorld=true;
    }
    else
    {
        std::cout << "Mass must be set to a number greater than 0" << std::endl;
    }
}
else if(!gravityOn && addedToWorld)
{
    world->removeRigidBody(body);
    body->setMassProps(0, btVector3(0,0,0));
    body->setLinearFactor(btVector3(0,0,0));
    body->setAngularFactor(btVector3(0,0,0));
    body->updateInertiaTensor();
    world->addRigidBody(body);
    addedToWorld=false;
}

addToWorld 布尔值只是确保 if 语句不会在每次更新时都在代码块中运行。 根据我的研究,这应该有效,但什么也不做。我错过了什么吗?根据我所见,最佳做法是在对刚体进行任何更改之前先移除刚体。然后 setMassProps 改变惯性, setLinearFactor 和 setAngularFactor 允许对象在碰撞时根据传入的向量不移动或移动, updateInertiaTensor 允许惯性正确更新,然后我将刚体添加回来。我可能误解了其中的一些,任何帮助将不胜感激。

【问题讨论】:

    标签: bulletphysics


    【解决方案1】:

    经过一个漫长的夜晚,我想通了。首先由于未知原因此时使用三角形网格(物体的网格)将有可能导致应用程序崩溃。因此,我使用了凸碰撞形状。此外,您将需要在开关中调用一些标志才能在静态和动态之间正确切换。代码是这样的:

    btConvexShape* tmpConvexShape=new btConvexTriangleMeshShape(mTriMesh);
    
    btShapeHull* hull=new btShapeHull(tmpConvexShape);
    btScalar margin=tmpConvexShape->getMargin();
    hull->buildHull(margin);
    tmpConvexShape->setUserPointer(hull);
    
    btConvexHullShape* convexShape=new btConvexHullShape();
    bool updateLocalAabb=false;
    
    for(int i=0; i<hull->numVertices(); i++)
    {
        convexShape->addPoint(hull->getVertexPointer()[i],updateLocalAabb);
    }
    convexShape->recalcLocalAabb();
    convexShape->setMargin(0.001f);
    
    delete tmpConvexShape;
    delete hull;
    
    meshInfos[currentMesh].shape=convexShape;
    meshInfos[currentMesh].motionState=new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(position.x,position.y,position.z)));
    meshInfos[currentMesh].mass=mass;
    
    btVector3 inertia;
    meshInfos[currentMesh].shape->calculateLocalInertia(mass, inertia);
    
    btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, meshInfos[currentMesh].motionState, meshInfos[currentMesh].shape, inertia);
    meshInfos[currentMesh].rigidBody=new btRigidBody(rigidBodyCI);
    

    和切换:

        if(gravityOn && !addedToWorld)
    {
        if(mass>0)
        {
            world->removeRigidBody(body);
            btVector3 inertia(0,0,0);
            body->getCollisionShape()->calculateLocalInertia(mass, inertia);
            body->setActivationState(DISABLE_DEACTIVATION);
            body->setMassProps(mass, inertia);
            body->setLinearFactor(btVector3(1,1,1));
            body->setAngularFactor(btVector3(1,1,1));
            body->updateInertiaTensor();
            body->clearForces();
            btTransform transform;
            transform.setIdentity();
            float x=position.x;
            float y=position.y;
            float z=position.z;
            transform.setOrigin(btVector3(x, y,z));
            body->getCollisionShape()->setLocalScaling(btVector3(1,1,1));
            body->setWorldTransform(transform);
            world->addRigidBody(body);
            addedToWorld=true;
        }
        else
        {
            std::cout << "Mass must be set to a number greater than 0" << std::endl;
        }
    }
    else if(!gravityOn && addedToWorld)
    {
        world->removeRigidBody(body);
        btVector3 inertia(0,0,0);
        body->getCollisionShape()->calculateLocalInertia(0, inertia);
        body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
        body->setMassProps(0, inertia);
        body->setLinearFactor(btVector3(0,0,0));
        body->setAngularFactor(btVector3(0,0,0));
        body->setGravity(btVector3(0,0,0));
        body->updateInertiaTensor();
        body->setAngularVelocity(btVector3(0,0,0));
        body->setLinearVelocity(btVector3(0,0,0));
        body->clearForces();
        body->setActivationState(WANTS_DEACTIVATION);
        btTransform transform;
        transform.setIdentity();
        float x=position.x;
        float y=position.y;
        float z=position.z;
        transform.setOrigin(btVector3(x, y,z));
        body->getCollisionShape()->setLocalScaling(btVector3(1,1,1));
        body->setWorldTransform(transform);
        world->addRigidBody(body);
        addedToWorld=false;
    }
    

    【讨论】:

      【解决方案2】:

      使用短函数来改变物体的质量(如果为 0.0f 则为静态,否则为动态):

      void InceptionPhysics::changeMassObject(btRigidBody* rigidBody, float mass) {
      
          logFileStderr(VERBOSE, "mass... %5.2f\n", mass);
      
          m_dynamicsWorld->removeRigidBody(rigidBody);
      
          btVector3 inertia;
          rigidBody->getCollisionShape()->calculateLocalInertia(mass, inertia);
          rigidBody->setMassProps(mass, inertia);
      
          m_dynamicsWorld->addRigidBody(rigidBody);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多