看球形的照相机 - 杆包裹

时间:2013-03-26 13:59:31

标签: c# math 3d xna camera

我有一个3D照相机,它以球体表面上的一个点为中心。它跟随并完美地围绕它旋转,除了在球体的两极。请注意,球体实际上是投影到球体的立方体,以便更轻松地管理位置坐标。

如果物体围绕球体水平移动,则相机按预期工作。但是,如果物体穿过球体的顶部或底部,则相机会缠绕在杆子上。如果直接穿过杆子,它会在经过时转动180度。

我理解为什么会发生这种情况 - 相机必须有一个全局向上矢量才能知道如何定位自己。如果我将向上矢量更改为不同的方向,例如右,相机不再翻转顶部或底部两极,而是在球体的左右两极表现出相同的行为。

我的问题是如何改变相机的行为,以免发生这种情况。我想要的是让我的相机感觉好像相机处于恒定位置,看着球体,球体在X和Z轴上旋转。

我意识到这可能会导致“错误”的方向 - 例如,如果用户从球体的正面开始,向上,然后向左,它们将最终位于球体的左侧但是相机在Z轴上旋转90度,而如果它们从前面开始直接移动到左侧面,则没有旋转。这很好,因为我可以检测到相机何时穿过脸部并慢慢“固定”相机的局部旋转,或者允许用户解锁相机并且他们可以自己处理相机的角度。

作为参考,我的相机目前正在使用此问题中的解决方案进行计算: Camera rotation aligned to arbitrary plane

任何见解都将受到赞赏!

1 个答案:

答案 0 :(得分:1)

如果您希望球体像轨迹球一样运行,请将增量旋转(例如,x轴和y轴)应用于用户控件指定的旋转矩阵。

更新后仍需要对旋转矩阵进行“重新标准化” - 否则,数值误差将会进入,旋转矩阵最终将不会成为旋转矩阵。计算应该是这样的:

update =  RotX(userInput.dX) * RotY(userInput.dY)
rawUpdatedRot = userRot * update
newZ = Normalize( Cross(rawUpdatedRot.x, rawUpdatedRot.y) )
newY = Normalize( Cross(newZ, rawUpdatedRot.x) )
newX = Normalize( rawUpdatedRot.x )
userRot = Matrix(newX, newY, newZ)