如何使用Bullet Physics进行弹簧约束?

M. *_*ter 3 c++ bullet bulletphysics physics-engine

我想测试子弹物理的春季约束。因此,我创建了一个悬停在地面上方的静态框,并将第二个动态框悬于其下。但是激活弹簧行为无济于事!盒子确实可以自由悬挂。我知道是因为它可以自由旋转。但它不会振荡或发生任何变化。

btCollisionShape *boxShape = createBoxShape(0.2f, 0.2f, 0.2f);

btRigidBody *box1 = createStatic(boxShape);
btRigidBody *box2 = createDynamic(1.0f /*mass*/, boxShape);

box1->setWorldTransform(btTransform(btQuaternion::getIdentity(), { 0.0f, 2.0f, 1.0f }));
box2->setWorldTransform(btTransform(btQuaternion::getIdentity(), { 0.0f, 1.0f, 1.0f }));

btGeneric6DofSpring2Constraint *spring = new btGeneric6DofSpring2Constraint(
    *box1, *box2,
    btTransform(btQuaternion::getIdentity(), { 0.0f, -1.0f, 0.0f }),
    btTransform(btQuaternion::getIdentity(), { 0.0f,  0.0f, 0.0f })
);

// I thought maybe the linear movement is locked, but even using these lines do not help.
// spring->setLinearUpperLimit(btVector3(0.0f,  0.1, 0.0f));
// spring->setLinearLowerLimit(btVector3(0.0f, -0.1, 0.0f));

// Enabling the spring behavior for they y-coordinate (index = 1)
spring->enableSpring(1,  true);
spring->setStiffness(1, 0.01f);
spring->setDamping  (1, 0.00f);
spring->setEquilibriumPoint();
Run Code Online (Sandbox Code Playgroud)

怎么了?我在StiffnessDamping参数上玩了很多。但这并没有改变。设置线性下限和上限将使盒子在y方向上可移动,但仍不会振荡。是的,重力被激活了。

M. *_*ter 5

好的,我通过检查Bullet提供的示例项目找到了一个解决方案(可能早些时候想到了这个想法)。我学到的三件事:

  • 弹簧约束不会违反线性极限。我以前的方法的问题是,线性运动要么被锁定,要么对于分配的弹簧刚度限制在一个很小的范围内。现在不再有限制(通过将上限设置为上限)。
  • 刚度太小了,所以连接的对象就像在线性极限内自由移动一样。您可以在下面的代码中查看这些值,这些值来自示例项目。
  • btGeneric6DofSpringConstraint和之间的行为略有不同btGeneric6DofSpring2Constraint。前者似乎使非弹簧轴的紫罗兰色变少(在我的情况下是x轴和z轴)。后者似乎施加了更强的阻尼。但这只是初步观察。
btGeneric6DofSpringConstraint *spring = new btGeneric6DofSpringConstraint(
    *box1, *box2,
    btTransform(btQuaternion::getIdentity(), { 0.0f, -1.0f, 0.0f }),
    btTransform(btQuaternion::getIdentity(), { 0.0f,  0.0f, 0.0f }),
    true
);

// Removing any restrictions on the y-coordinate of the hanging box
// by setting the lower limit above the upper one.
spring->setLinearLowerLimit(btVector3(0.0f, 1.0f, 0.0f));
spring->setLinearUpperLimit(btVector3(0.0f, 0.0f, 0.0f));

// Enabling the spring behavior for they y-coordinate (index = 1)
spring->enableSpring(1,  true);
spring->setStiffness(1, 35.0f);
spring->setDamping  (1,  0.5f);
spring->setEquilibriumPoint();
Run Code Online (Sandbox Code Playgroud)