Revolute 在这里是旋转的意思,Revolute Joint便是旋转关节的意思。
可以想象成我们日常生活中的门,拉一下,门就会围绕着墙边旋转。
和distance Joint一样,Revolute Joint也有两个锚点。锚点的位置是和对应的rigidbody绑定的。
在场景simulate之后,锚点会控制rigidbody移动和旋转。
Unity 3D中HingeJoint就是用Revolute Joint来实现的。
在Unity 3D中HingeJoint有三种功能:
1.Spring
这个功能的作用就是 产生一个旋转的弹力。就像我们平时开了门,门的弹簧会自动把门扣上。
用Revolute Joint实现Spring:
如果要模仿Unity做编辑器功能,在设置完某个属性之后需要调用对应Rigidbody的WakeUP方法。
但unity的target position该如何设置,我还没不知道怎么设置,理论上是设置在max字段上。
还需要调用一下rigidbody 更新转动惯量的函数,不然转动会不自然。
2.Limit
这个功能的作用就是设置Joint的极限。就像我们平时用力把门关上,门的内侧撞到墙会把门反弹回来。
用Revolute Joint实现Limit:
3.Motor
可以想象成我们日常生活中的门,拉一下,门就会围绕着墙边旋转。
和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));
这样轴的旋转就完成了。