c# - 看着球体的相机 - 极包裹

标签 c# math 3d xna camera

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

如果对象围绕球体水平移动,相机将按预期工作。但是,如果物体向球体的顶部或底部极点移动,则相机会环绕该极点。如果它直接穿过杆子,它在穿过时看起来会转 180 度。

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

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

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

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

如有任何见解,我们将不胜感激!

最佳答案

如果您希望球体像轨迹球一样工作,请将增量旋转(例如,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)

关于c# - 看着球体的相机 - 极包裹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15638962/

相关文章:

c++ - 获取线段和 2^n 网格之间的所有交点(以整数表示)

c++ - 顺时针旋转二维矩阵会产生奇数结果

javascript - 3DS Max => ThreeJs。导出场景

opengl - glm 结合旋转和平移

c# - 使用 LINQ to XML 从 XML 文件读取文本

c# - 未找到 Clickonce 部署外部 dll 引用

python - 执行双重求和的最佳方法

javascript - Three.js - 使用 CubeTextureLoader 在立方体的每个面上创建不同的图像

c# - 从命令行或窗口消息打开 "Show available networks"面板

c# - 如何使用 Entity Framework 和 MySQL 获取每个组的最新记录(包括相关实体)