问题描述
我正在尝试在 Bullet Physics 中实现布娃娃,模仿我在使用 physx 的 Maya 插件中创建的布娃娃。除了约束电机之外,我拥有一切 1:1。
在 physx 中,电机仅具有线性和角度阻尼/刚度以及表示为 mat4(位置和旋转)的目标。
理想情况下,我会使用 btConeTwist
,但它似乎没有线性/角电机设置,所以我已切换到 btGeneric6DofConstraint
,它确实提供了可访问性,我设置如下,我觉得是对的...
// Angular
joint.dof6->getRotationalLimitMotor(0)->m_damping = joint.drive_angulardamping;
joint.dof6->getRotationalLimitMotor(1)->m_damping = joint.drive_angulardamping;
joint.dof6->getRotationalLimitMotor(2)->m_damping = joint.drive_angulardamping;
joint.dof6->getRotationalLimitMotor(0)->m_limitSoftness = (1 / joint.drive_angularstiffness);
joint.dof6->getRotationalLimitMotor(1)->m_limitSoftness = (1 / joint.drive_angularstiffness);
joint.dof6->getRotationalLimitMotor(2)->m_limitSoftness = (1 / joint.drive_angularstiffness);
// Linear
joint.dof6->getTranslationalLimitMotor()->m_damping = joint.drive_lineardampening;
joint.dof6->getTranslationalLimitMotor()->m_limitSoftness = (1 / joint.drive_linearStiffness);
问题是我找不到任何设置电机目标的方法。它必须有一个,即马达的唯一目的,将刚体旋转/平移到目标旋转/平移。
Bullet 文档至少可以说是缺乏的,任何见解或建议都是令人难以置信的。
解决方法
您应该使用 btGeneric6DofSpring2Constraint
。它是所有 Bullets 约束中最灵活、功能最丰富的,也是我经验中最稳定的。从我可以告诉你的理解如何设置约束框架和约束的其余部分,所以我将跳过那部分。设置与其他所有相同。
从那里开始就很简单了。让我们从约束的简单目标速度开始。您必须启用电机,设置最大电机力,最后是目标速度。索引对应于约束中的轴。线性 X、Y 和 Z 为 0、1 和 2。旋转 X、Y 和 Z 为 3、4 和 5。旋转的目标速度以弧度为单位。所以这个例子在约束框架中创建了一个围绕 X 轴的旋转电机,它试图每秒移动 180 度。
pConstraint->enableMotor(3,true);
pConstraint->setMaxMotorForce(3,10000.0);
pConstraint->setTargetVelocity(3,M_PI);
伺服,或带有目标的电机,稍微复杂一些,但不多。它与上一节完全相同,但增加了两个内容。首先,启用伺服,并设置伺服目标。请注意,您仍然必须设置目标速度才能使其工作。伺服目标以弧度为单位旋转。所以在这个例子中,舵机试图围绕约束 X 轴旋转 90 度。
pConstraint->enableMotor(3,10.0);
pConstraint->setServo(3,true);
pConstraint->setServoTarget(3,M_PI / 2.0);
需要注意的是,btGeneric6DofSpring2Constraint
使用欧拉角,因此会受到万向节锁定。一个轴被限制为 [-PI / 2,PI / 2] 而不是完整的 360 度运动。该轴是旋转顺序中的中间轴。默认情况下,顺序为 X、Y、Z,因此 Y 轴受到约束。如果这是一个问题,您可以使用其他轮换顺序之一。
约束代码注释得体。我想你会在那里找到任何其他问题的答案。 Bullet 论坛也有一些关于约束的讨论,这些讨论很有用。