我需要实现平移,缩放和旋转Gizmos,但是旋转Gizmo遇到了麻烦。基本上,我不知道如何转换鼠标的移动来确定旋转对象的方向。

通过旋转Gizmo(小部件),我的意思是如下所示:


对于以3轴表示的平移和缩放小控件,我执行以下操作:我对屏幕空间中先前和当前鼠标位置之间的差异进行矢量处理。然后将此向量乘以视图矩阵和投影矩阵的逆矩阵,即可得到世界空间中鼠标移动的向量。然后,我用选定的轴取向量在世界空间中的点积。这使我可以确定鼠标移动是与轴对齐还是远离轴。

但是旋转Gizmo我不能做同样的事情。旋转Gizmo用3个圆表示,每个圆代表绕轴的旋转。单击一个圆后,我需要找到某种方法来平移鼠标的运动,以确定围绕所选轴旋转对象的方向。我不知道该怎么做。请提供帮助。

请务必注意,我使用的是颜色选择而不是光线投射来确定单击Gizmo的位置。这意味着我没有射线从世界上撞击小发明的起点。我之所以这样说是因为我看过像libgizmo这样使用光线投射的示例,但我认为我做不到同样的事情。

预先感谢您的帮助。

评论

我花了一秒钟的时间来理解旋转小控件的含义。我添加了一张图片以防万一(我认为您不能添加图片,除非您有更多的声誉!)。如果您想使用更合适的图像,请随时告诉我,我可以更改图像。

感谢您添加图像艾伦。您说得对,我认为这会使情况变得更清楚。

我想你是对的。为此,无法使用基于颜色的选择。

#1 楼

通过在当前圆的平面上的鼠标和Gizmo中心之间绘制一条假想线,将鼠标位置映射到圆上。对起始位置和当前位置执行此操作。

然后通过执行normalize(quat(1+dot(v_1, v_2), cross(v_1, v_2)))可以轻松地使四元数围绕中心从中心旋转。

这是可行的,因为点积是矢量之间的角度的余弦,而十字是垂直于2个矢量的矢量(又称旋转角度),并且具有矢量之间角度的正弦长度。这意味着您可以从中创建双四元数。然后,您可以将双四元数与单元四元数一起套用以获得所需的旋转。

但是,利用这些信息,您可以通过将鼠标投射到Gizmo球上并使用起点来做一个Arcball和结束向量的方式。

评论


$ \ begingroup $
这个答案真的需要一张照片
$ \ endgroup $
– joojaa
17年1月19日在7:49

#2 楼

棘轮怪胎的答案可能有用。我不确定,我没有花太多时间,因为我不知道如何根据所述的点和叉积来创建四元数。

我们最终要做的是:


将Gizmo的中心投影到屏幕空间。
使用点积公式:acos(Dot(Got(GizmoToLastMouse,GizmoToCurrentMouse))/获得矢量GizmoToLastMouse和GizmoToCurrentMouse之间的夹角。 (GizmoToLastMouse.Length()* GizmoToCurrentMouse.Length()))
通过取GizmoToLastMouse和GizmoToCurrentMouse的交叉点并使其与屏幕法线交点来获取角度的符号。
获取另一个符号(倍1.0f或-1.0f)基于Gizmo的方向,方法是获取旋转轴和从Gizmo中心到相机的向量之间的点积
根据角度和两个角度应用旋转标记到适当的轴

可能会有更好的方法,但这可以很好地满足我们的需求。

评论


$ \ begingroup $
四元数被构造为quat(cos(angle / 2),axis * sin(angle / 2)),并且您知道点积us等于cos(angle)乘以长度和叉形的乘积乘积是轴乘以sin(角度)乘以长度乘积。对其进行归一化,您可以轻松获得相同旋转但四倍角度的四元数。为了得到合适的四元数,可以执行slerp(unit,quat,0.5),在内联后将其标准化为(unit + quat);
$ \ endgroup $
–棘轮怪胎
17年1月19日在10:18