2014-10-07 2 views
1

Я довольно новичок в Bullet, и моя цель здесь - переключить btRigidBody между статическими и динамическими. Для того, чтобы инициализировать мой Rigidbody я начинаю, делая это:Bullet Physics Library switch rigidbody между static_object и dynamic_object

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, чтобы начать. Позже у меня есть функция, которая проверяет, является ли булево был включен и он переключает Rigidbody в динамический объект, как это:

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; 
} 

булево addedToWorld просто делает уверен, что если оператор не продолжает работать через кодовый блок для каждого обновления. Из того, что я исследовал, это должно работать, но вместо этого ничего не делает. Я что-то упускаю? Из того, что я видел, лучшая практика заключается в том, чтобы удалить твердое тело прежде, чем вы внесете какие-либо изменения в него. А затем setMassProps для изменения инерции, setLinearFactor и setAngularFactor позволяет объекту не перемещаться и не перемещаться в зависимости от вектора, который вы передаете в него при столкновении, updateInertiaTensor позволяет инерции правильно обновляться, а затем я добавляю твердое тело назад. Я, возможно, неправильно понял некоторые из них, любая помощь была бы весьма признательна.

ответ

2

После долгой ночи я понял это. Прежде всего по неизвестной причине в это время использование треугольной сетки (сетка объекта) будет иметь возможность свернуть приложение. Поэтому вместо этого я использовал выпуклую форму столкновения. Кроме того, вам нужно будет вызвать некоторые флаги в коммутаторе для правильного переключения между статическими и динамическими. Код, как например:

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; 
} 
0

использовать короткую функцию для изменения массы тела (статический, если 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); 
} 
Смежные вопросы