拖动 3D 杠杆(基于方向和视角)
Dragging a 3D lever (based on orientation & viewing angle)
在我的项目(c++/UE4)中,我有一个杠杆网格从地板伸出来。按住此杠杆上的鼠标左键并移动鼠标将启动拖动操作。此拖动操作负责计算2D增量鼠标移动,并利用此数据旋转杠杆*在本地空间*,它只能在单个轴上旋转(负或正,但仍然只有一个轴)。
但是,如果我不是在杠杆前面,而是在杠杆后面呢?如果我在它的一边呢?如果杠杆实际上是伸出墙壁而不是地板呢?我如何使它,使鼠标移动实际上旋转杠杆适当的角度,在它被观看,不管杠杆的方向?
为了进一步解释我自己…
下面是一个场景列表,以及我希望鼠标如何控制它们:
当杠杆在地板上并且你在它前面时:
- 如果你向上移动鼠标(-Y),它应该旋转远离相机
- 如果你向下移动鼠标(+Y),它应该向摄像机方向旋转
当杠杆在地板上而你在它后面时:
- 如果你向上移动鼠标(-Y),它应该旋转远离摄像机
(这与你在它前面的世界空间方向相反) - 如果你向下移动鼠标(+Y),它应该向摄像机方向旋转
(这与你在它前面的世界空间方向相反)
当杠杆在地板上而你在它旁边时:
- 如果你向左移动鼠标(-X),它应该旋转到相机的左边
(这是相反的方向,当你在它的另一边) - 如果你向右移动鼠标(+X),它应该旋转到相机的右边
(这是相反的方向,当你在它的另一边)
当杠杆在墙上而你在它前面时:
- 如果你向上移动鼠标,它应该向上旋转(朝向天空)
- 如果你向下移动鼠标,它应该向下旋转(朝向地板)
当杠杆在墙上而你在它旁边时:
- 就像它在墙上,你在它前面一样
请注意,如果它有帮助的话,UE4确实有内置的2D/3D矢量数学功能,以及简单的方法来投影和解投影坐标到/从3D世界或2D屏幕。因此,我总是知道鼠标位置的确切世界空间和屏幕空间坐标,杠杆的枢轴(基础)位置,杠杆的手柄(顶部)位置,以及鼠标每帧移动的量(增量)。
获取杠杆的枢轴(它周围的点旋转),并将其投影到屏幕坐标上。然后,当你第一次点击时,你存储点击的坐标。
现在,当你需要知道旋转的方式时,你计算向量枢轴到第一次点击和向量枢轴到当前位置之间的点积(你应该在点积之前规范化向量)。这给了你鼠标移动的cos(角度),你可以使用它(取arccos(值)来获得角度)在3d中移动杠杆。因为屏幕上的角度与投影角度不一样,所以它会有点不稳定,但它更容易控制这种方式(如果你移动鼠标90度,即使它们没有正确对齐,杠杆也会移动90度)。试玩一下设置,看看哪个最适合你的项目。
另一种方法是:当你第一次点击时,你将杠杆末端的点(或者你点击杠杆的点)存储在3d空间中。你可以使用相机投影平面在3d中移动点(你可以使用相机向上向量,在你使它与相机视图方向正交之后,然后使用视图方向交叉向上向量来获得正确的方向)。你将鼠标的增量移动应用到点上,然后将其投影到旋转平面上,并移动杠杆使点与投影的点对齐(数学原理与上面的类似,只是使用3d点而不是屏幕投影)。
注意:如果相机非常靠近旋转平面,因为它并不总是清楚杠杆应该向前或向后移动,因此此操作不能很好地工作。
我不是unreal-engine4的专家(只是自己学习),但所有这些都是基本的矢量数学,应该得到很好的支持。查看维基百科上的点积和叉积,因为它们对这些技巧非常有用。
这里有一个方法:
-
当用户点击杠杆时,假设有一个平面穿过杠杆的枢轴,其法线与相机到枢轴的方向相同。计算光标光线与该平面的交点
FVector rayOrigin; FVector rayDirection; FVector cameraPosition; FVector leverPivotPosition; FVector planeNormal = (leverPivotPosition-cameraPosition).GetSafeNormal(0.0001f); float t = ((leverPivotPosition - rayOrigin) | planeNormal) / (planeNormal | rayDirection); FVector planeHitPosition = rayOrigin + rayDirection * t;
-
将其标量投影到杠杆的局部上/下轴上。让我们假设它是本地上下轴:
FVector leverLocalUpDirectionNormalized; float scalarPosition = planeHitPosition | leverLocalUpDirectionNormalized;
-
然后,在按下杠杆的每一帧中,计算该帧的新
scalarPosition
。当scalarPosition
在帧间增加时,杠杆应该旋转,使其向杠杆的上方移动。当它在帧间减小时,杠杆应该朝杠杆的下端旋转。
- 使用Unreal C++获取VR耳机的世界位置/方向
- 在C++中向零方向近似的最佳方法
- 垂直方向的 Gtk3+ 旋转按钮 (c/c++)
- OpenVR:向视图方向移动
- 来自逆 vp 矩阵和相机位置的光线方向不正确
- 带有枚举方向/类型的气泡排序结构数组
- OpenGL通常"Up"方向?
- 定义/预设NURBS起点和终点的方向
- 如何按另一个向量的方向调整一个向量?
- 粒子系统:所有粒子都朝同一方向运动
- C++指标评价方向
- SFML - 弹丸以不同的方向减速
- C++位移位在相反方向上具有相同的常量,结果不同,代码更改很小
- 如何在相对于观看方向的地形中移动
- RCPP 函数,用于在 4 个方向上生成随机游走
- "in"和"out"在参数方向上是什么意思?
- DirectX矩阵:相对于面向方向的转换(例如在FPS中)
- 平行于上方向向量时,Arcball摄影机被锁定
- 在 x 方向和 y 方向上计算一次第一索贝尔导数,并将这两者结合起来(对于每个通道)
- 相对于其数据在特定方向上移动的有效方法是什么