【问题标题】:3D Scene Panning in perspective projection (OpenGL)透视投影中的 3D 场景平移 (OpenGL)
【发布时间】:2012-08-19 07:50:42
【问题描述】:

我设计了一个 C++ 类,将用户从轨迹球旋转、缩放和平移中抽象出来。我已经按预期进行了旋转(使用轨迹球)和缩放。但是,平移的行为与预期不同。当我选择一个点并拖动时,我希望在完成拖动时,选择的点继续在鼠标下方。我对透视投影中平移的理解如下。目标和摄像机位置都会受到平移操作的影响。摄像机目标和摄像机位置(眼睛)应与拖动成比例平移。比例(可能不是恒定的)应基于 z 深度。

在正交投影中平移是直截了当的,但在透视中会出现问题。如果有人能解释 OpenGL 的数学和实现细节,将会很有用。

【问题讨论】:

  • 你是在改变凸轮还是整个世界来获得结果?
  • 我都实现了。但我更喜欢改造世界,因为它不涉及计算模型视图矩阵的逆矩阵。但是,如果我有任何一种方法的解决方案,我都很好。
  • “但是,平移的行为不像预期的那样。当我选择一个点并拖动时,我希望在完成拖动时,选择的点继续在鼠标下方”。这就像你的鼠标按钮被锁住并没有松开吗?
  • 是的。当我按下 lButtonDown 时,我在鼠标下方选择了一个假想点,当我继续保持 lButtonPressed 时,我可以移动鼠标以平移场景。 2D 中的一个类似示例是 pdf 文档查看器,用户在其中抓取页面上的一个点并移动查看区域。
  • 我打赌你可以从gamedev.stackexchange.com获得真正好的答案和声誉

标签: c++ opengl renderer


【解决方案1】:

我不了解 OpenGL 的具体细节,但如果我正确理解了您的问题,我可以在数学方面提供帮助:

我假设您已经选择了该对象,方法是单击该对象并因此“发送”一条穿过您的场景的光线,该光线会在锚点处击中您的对象p

了解以下内容:

现在您将鼠标沿矢量 t 拖动。使用截距定理,您可以轻松计算向量 s,通过该向量 p 必须被转换为“将其保持在光标下”:

|p| / |q| = |s| / |t|

|s| = ( |p| / |q| ) * |t|

s 与 t 平行,所以它是 t 归一化乘以 |s|:

s = t / |t| * |s|

s = t / |t| * ( |p| / |q| ) * |t|

s = t * ( |p| / |q| )

如果你在平移,你正在做同样的事情,只是你没有将 p 移动 s,但你必须通过 - s.

【讨论】:

  • “我假设您已经选择了该对象,通过单击该对象并因此“发送”一条穿过您的场景的射线,该射线在锚点 p 中击中您的对象。”并不真地。平移锚点可能位于也可能不在场景中的对象上。但是,我可以构造一个通过目标点并且垂直于视图方向的平面。我还没有吸收你的数学,但你的数字告诉我计算位移并不难。感谢那。我会试一试,看看它是否能解决我的问题。
  • @Ram:要在透视模式下进行平移,您需要一些锚点。想一想:如果鼠标指针下面什么都没有,它下面还有什么东西可以保留?一个健壮的实现将优雅地退回到仅将相机移动某个因素。
  • 嗯,对,你如何在场景中表达观点并不重要。我只是想指出,您实际上选择了一个属于某个对象的点作为您的“锚点”。我不知道如何在 stackoverflow 上写出简洁的公式,但这里有一点解释:每个字母代表一个向量,如图所示,|p|是向量 p 的长度。在前两行中,我只是使用了截距定理,如图所示,然后重新排列该术语以获得 s 的长度。下面的三行显示了如何根据长度 |s| 计算实际 s它是 t 给出的方向。
【解决方案2】:

在你的鼠标下不可能有终点。透视模式下的平移可以通过两种方式完成。一个是平移相机,另一个是旋转相机。平移相机将导致对象旋转以供用户查看。用于平移的旋转相机有两个约束。一种是不改变相机位置,另一种是停止相对于相机方向的旋转。即,旋转轴应平行于相机右和上矢量形成的平面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    相关资源
    最近更新 更多