Bullet 3 动力学不适用于非球体
Bullet 3 dynamics not working for non-sphere
我有一个简单的程序,可以在某些地形上生成球,效果很好。但是尝试添加一个盒子会导致性能极度下降,而一个盒子不会掉落。
这里是子弹代码的完整范围
// create the physics world
auto collisionConfiguration = new btDefaultCollisionConfiguration();
auto dispatcher = new btCollisionDispatcher(collisionConfiguration);
auto broadphase = new btDbvtBroadphase();
auto solver = new btSequentialImpulseConstraintSolver;
auto dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0, 0, -10));
// create terrain
auto terrainIndices = std::vector<int>(terrainModel.faceData.size() / 11);
std::iota(terrainIndices.begin(), terrainIndices.end(), 0);
auto terrainVertices = terrainModel.faceData;
auto terrainMesh = new btTriangleIndexVertexArray(terrainIndices.size() / 3, terrainIndices.data(), 3 * sizeof(int), terrainVertices.size() / 11, terrainVertices.data(), 11 * sizeof(int));
auto terrainShape = new btBvhTriangleMeshShape(terrainMesh, false);
auto terrainMotionState = new btDefaultMotionState();
auto terrainBody = new btRigidBody(0.0, terrainMotionState, terrainShape);
dynamicsWorld->addRigidBody(terrainBody);
// vvvvvvvvvvvvvvvvvvv new code
// create box
auto boxShape = new btBoxShape(btVector3(0.3, 0.3, 0.3));
//auto boxShape = new btSphereShape(0.3); // this works just fine
auto boxMotionState = new btDefaultMotionState(btTransform(btMatrix3x3(), btVector3(0, 0, 5)));
auto boxBody = new btRigidBody(1.0, boxMotionState, boxShape);
dynamicsWorld->addRigidBody(boxBody);
// bind body to renderable
// ^^^^^^^^^^^^^^^^^^^
// create balls (called later on key press)
auto ballShape = new btSphereShape(0.1);
auto spawnBall = [&]() {
auto ballMotionState = new btDefaultMotionState(btTransform(btMatrix3x3(), btVector3(0, 0, 5)));
auto ballBody = new btRigidBody(1.0, ballMotionState, ballShape);
ballBody->setCcdMotionThreshold(0.1);
ballBody->setCcdSweptSphereRadius(0.2);
dynamicsWorld->addRigidBody(ballBody);
// bind body to renderable
};
while(...)
{
// process input
dynamicsWorld->stepSimulation(1.0f / 144.0f);
// render
}
我也试过用胶囊也有同样的效果。需要明确的是,问题是如果新对象是一个盒子或一个胶囊,它似乎不会动态表现,如果它是一个球体,它会按预期工作。初始位置远高于地形高度。
奇怪的是,性能下降只发生在新生成的球下降了一点之后。
这是 运行 在 Bullet 3 v2.87 上从 运行 在调试模式下于 Visual Studio 2017 编译的。
哇,我想通了。 btMatrix3x3()
不创建单位矩阵(其为零或未初始化)。所以 rotation/transformation 不对。使用 btMatrix3x3::getIdentity()
解决了这个问题。
因此,球体的物理计算似乎不需要适当的旋转变换(在某种程度上有点意义),这只会增加我的困惑。
我有一个简单的程序,可以在某些地形上生成球,效果很好。但是尝试添加一个盒子会导致性能极度下降,而一个盒子不会掉落。
这里是子弹代码的完整范围
// create the physics world
auto collisionConfiguration = new btDefaultCollisionConfiguration();
auto dispatcher = new btCollisionDispatcher(collisionConfiguration);
auto broadphase = new btDbvtBroadphase();
auto solver = new btSequentialImpulseConstraintSolver;
auto dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0, 0, -10));
// create terrain
auto terrainIndices = std::vector<int>(terrainModel.faceData.size() / 11);
std::iota(terrainIndices.begin(), terrainIndices.end(), 0);
auto terrainVertices = terrainModel.faceData;
auto terrainMesh = new btTriangleIndexVertexArray(terrainIndices.size() / 3, terrainIndices.data(), 3 * sizeof(int), terrainVertices.size() / 11, terrainVertices.data(), 11 * sizeof(int));
auto terrainShape = new btBvhTriangleMeshShape(terrainMesh, false);
auto terrainMotionState = new btDefaultMotionState();
auto terrainBody = new btRigidBody(0.0, terrainMotionState, terrainShape);
dynamicsWorld->addRigidBody(terrainBody);
// vvvvvvvvvvvvvvvvvvv new code
// create box
auto boxShape = new btBoxShape(btVector3(0.3, 0.3, 0.3));
//auto boxShape = new btSphereShape(0.3); // this works just fine
auto boxMotionState = new btDefaultMotionState(btTransform(btMatrix3x3(), btVector3(0, 0, 5)));
auto boxBody = new btRigidBody(1.0, boxMotionState, boxShape);
dynamicsWorld->addRigidBody(boxBody);
// bind body to renderable
// ^^^^^^^^^^^^^^^^^^^
// create balls (called later on key press)
auto ballShape = new btSphereShape(0.1);
auto spawnBall = [&]() {
auto ballMotionState = new btDefaultMotionState(btTransform(btMatrix3x3(), btVector3(0, 0, 5)));
auto ballBody = new btRigidBody(1.0, ballMotionState, ballShape);
ballBody->setCcdMotionThreshold(0.1);
ballBody->setCcdSweptSphereRadius(0.2);
dynamicsWorld->addRigidBody(ballBody);
// bind body to renderable
};
while(...)
{
// process input
dynamicsWorld->stepSimulation(1.0f / 144.0f);
// render
}
我也试过用胶囊也有同样的效果。需要明确的是,问题是如果新对象是一个盒子或一个胶囊,它似乎不会动态表现,如果它是一个球体,它会按预期工作。初始位置远高于地形高度。
奇怪的是,性能下降只发生在新生成的球下降了一点之后。
这是 运行 在 Bullet 3 v2.87 上从 运行 在调试模式下于 Visual Studio 2017 编译的。
哇,我想通了。 btMatrix3x3()
不创建单位矩阵(其为零或未初始化)。所以 rotation/transformation 不对。使用 btMatrix3x3::getIdentity()
解决了这个问题。
因此,球体的物理计算似乎不需要适当的旋转变换(在某种程度上有点意义),这只会增加我的困惑。