我想弄清楚如何以多个增量应用旋转, 到一个动态的方向(即我不能使用slerp )。
详细信息:
我在3D空间中有一个对象,其方向可由四元数Q
描述。
当此对象旋转时,它会从另一台服务器接收定期更新,
它定义了真正的方向。例如,在时间t1
,对象的方向
已Q1
,并收到正确方向应为K1
的更新。
我不能简单地将Q1
替换为K1
,因为视觉效果不会很顺利,
所以我宁愿在一系列10个步骤中逐渐从Q1
到K1
进行纠正。
另外,我不能使用slerp,因为Q1
不是静态的。相反,我想
派生增量修正,我称之为dK
,直到下一次服务器更新
到达。
现在我以下列方式派生dK
:
delK = K1 * Q1.conjugate()
dk = delK / 10
第2步实际发生的是我将delK
转换为轴+角度表示,
然后将角度除以10.然后我转换回四元数。
问题1:上述方法在数学上是否正确?
问题2:我看到的情况是dk
不是一个小的修正,可能会向相反的方向旋转。可能导致这种情况的原因。
这是用于在JavaScript incheon中实现客户端预测。
答案 0 :(得分:1)
您可以将“十步走”的方法替换为“坚定的”解决方案:
Q = slerp(Q, Q1, 1 - Math.pow(smoothingRatio, deltaTime)
此解决方案将以帧速率独立的方式将Q推向Q1,并使Q1是动态的。插值1秒后,到Q1的“距离”的剩余分数将为smoothingRatio
。了解更多here。
如果每次更新旋转的角度大于180度,则最接近的旋转轴将不同于服务器上的旋转轴。天真的解决方案是更频繁地发送更新,或者限制对象的旋转速度。
如果要随更新一起发送角速度,则可以进行更好的客户端预测,并且可以解决“相反方向”的问题。这个想法是使四元数沿最后一次更新发送的角速度旋转。
Cannon.js中的Quaternion#integrate函数实现了四元数集成,您可以使用它。
// Rotate Q along the angular velocity provided in the last update
Q = Q.integrate(angularVelocity, deltaTime, Vec3.ZERO);