如何用Bullet Physics制作弹簧约束?

时间:2017-10-10 16:41:51

标签: c++ physics-engine bulletphysics bullet

我想测试 Bullet Physics 的弹簧约束。所以我创建了一个悬浮在地面上的静态盒子和一个从它垂下的第二个动态盒子。但激活弹簧行为什么都不做!盒子确实是自由悬挂的。我知道它因为它自由旋转。但它不会振荡或任何东西。

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();

有什么问题?我使用StiffnessDamping参数玩了很多。但它没有改变。设置线性下限和上限使得盒子可以在y方向上移动,但它仍然不会振荡。是的,重力被激活了。

1 个答案:

答案 0 :(得分:4)

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

  • 弹簧约束违反线性限制。我以前的方法存在的问题是线性运动要么被锁定,要么限制在指定弹簧刚度的范围太小的范围内。现在没有更多限制(通过将下限设置在上限之上)。
  • 刚度太小,因此连接的物体就像在线性极限内可自由移动一样。您可以在下面的代码中查看值,我从示例项目中获取它们。
  • btGeneric6DofSpringConstraintbtGeneric6DofSpring2Constraint之间的行为存在细微差别。前一个似乎紫色非弹簧轴较少(在我的情况下是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();