physx 3.3.4中的 Revolute Joint

Revolute 在这里是旋转的意思,Revolute Joint便是旋转关节的意思。
可以想象成我们日常生活中的门,拉一下,门就会围绕着墙边旋转。
和distance Joint一样,Revolute Joint也有两个锚点。锚点的位置是和对应的rigidbody绑定的。
在场景simulate之后,锚点会控制rigidbody移动和旋转。
Unity 3D中HingeJoint就是用Revolute Joint来实现的。
在Unity 3D中HingeJoint有三种功能:
1.Spring 
  这个功能的作用就是 产生一个旋转的弹力。就像我们平时开了门,门的弹簧会自动把门扣上。
用Revolute Joint实现Spring:
PxJointAngularLimitPair limitPair(min, max, tolerance));
limitPair.spring = ....弹力...;
limitPair.damping = ....摩擦力;
revolute->setLimit(limitPair);
revolute->setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED, true);


    如果要模仿Unity做编辑器功能,在设置完某个属性之后需要调用对应Rigidbody的WakeUP方法。
但unity的target position该如何设置,我还没不知道怎么设置,理论上是设置在max字段上。
还需要调用一下rigidbody 更新转动惯量的函数,不然转动会不自然。
2.Limit
这个功能的作用就是设置Joint的极限。就像我们平时用力把门关上,门的内侧撞到墙会把门反弹回来。
用Revolute Joint实现Limit:
PxJointAngularLimitPair limit(min, max, tolerance)
limit.bounceThreshold = minBounce;
limit.restitution= maxBounce;
revolute->setLimit(limit); // upper, lower, tolerance
revolute->setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED, true);

3.Motor

这个功能的作用就是给Joint设置一个旋转速度,像发动机一样。

用Revolute Joint实现Motor:

joint->setDriveVelocity(目标速度);
joint->setDriveForceLimit(force);
joint->setConstraintFlag(PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES, true);
revolute->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_ENABLED, true);
if(需要平滑)
{
	revolute->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_FREESPIN, true);
}
 

最后,如果要设置Joint的轴,也就是U3D里面的axis,需要算一下Joint每个锚点的。

设置joint的轴的朝向,就是设置Joint的两个锚点的旋转。

physx 3.3.4中Joint轴的默认朝向是x轴,也就是(1,0,0).

假设旋转后的轴为(A,B,C),我们需要算出旋转矩阵是多少。

设旋转矩阵为

        x1,x2,x3

R=[   y1,y2,y3 ]

         z1,z2,z3

那么(1,0,0)叉乘R的结果为 

(x1,x2,x3)

且我们得知旋转后的轴为(A,B,C).

所以旋转矩阵为

        A , 0,  0

R=[  B , 0,0]

        C ,0,0

最后我们通过旋转矩阵初始化一个四元素 ,

PxQua qua(R);

调用

revolute->setLocalPose(PxTransform(pos,qua));

这样轴的旋转就完成了。

你可能感兴趣的:(Physx)