我对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,因为我的“mass”变量为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;
}
addedToWorld布尔值只是确保if语句在每次更新时都不会继续运行代码块。 根据我的研究,这应该有效但却什么都不做。我错过了什么吗?从我所看到的最佳做法是在对它进行任何更改之前先删除刚体。然后setMassProps改变惯性,setLinearFactor和setAngularFactor允许对象不移动或移动,具体取决于碰撞时传入的向量,updateInertiaTensor允许惯性正确更新,然后我将刚体添加回来。我可能误解了其中一些,非常感谢任何帮助。
答案 0 :(得分: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;
}
答案 1 :(得分: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);
}