基于对象边界框的摄像头控件?

Ben*_*ack 7 javascript 3d three.js

来自three.js的正常轨道控制对于圆形物体是完美的,但对于长物体不好(特别是当变焦关闭时),我正在寻找解决方案来解决这个问题.

用文字描述很难,请从Google查看此webgl示例(放大最大值以查看):https://www.google.com/o3d/shopping/viewer/360? q = erMBhK8fu3C&o3ds = use_3d 在此输入图像描述

这是我正在寻找的顶视图插图: 在此输入图像描述

我正在考虑基于默认OrbitControls的使用,从相机到边界框连续投射光线并保持恒定距离,但问题是相机总是在看物体的中心,不像上面的例子(凸轮只在到达时旋转)对象的角落).

任何想法将不胜感激.

nee*_*eeh 5

正如您所指出的,使用现有的THREE.OrbitControls和修改的target不起作用,因为相机不会垂直地看着边界框。

我尝试了不同的方法,结果很糟糕,但这是我的工作。
在我尝试的每个解决方案中,我总是必须计算(以任何顺序):

  1. 相机的位置
  2. 相机的方向

无论如何,相机必须围绕某物旋转。因此,我所有的解决方案或多或少都基于THREE.OrbitControls,它充当“旋转的当前状态”并为我处理所有 DOM 事件。


查看 AABB 上最近的点

想法如下:

  • 相机旋转;
  • AABB 上距离相机最近的点是相机应该看到的位置(方向);
  • 使用一定的距离d将相机推离该点(位置)。

有2种情况:

  1. 边界
    边界上最近的点

  2. 角落
    角上的最近点

在这个(非常棘手的)小提琴上进行了测试。但仍然需要修复顶面和底面(旋转奇点)。


在包围体上进行光线投射

这是您在问题中描述的想法:

  • 创建相机应遵循的边界体积;
  • 光线投射此 BV 上的摄像机位置;
  • 相机的新位置是交点
  • 相机的新方向是相交面的法线。

我尝试使用带有圆形边框和角的细分盒子几何形状,以便相机以一定角度旋转。

BV 上的光线投射

考虑到表面的光滑度,结果可能会非常方便。不幸的是,当交叉点的法线发生变化时,相机会急剧改变方向,从而导致运动中出现令人不快的颠簸。

看看这个(又棘手)fiddle

为了解决这个问题,我们可以沿着三角形线性插值法线,但这需要以这样的方式计算法线:顶点的每个法线都是该顶点所属面的法线的平均值。

沿面插值的法线

请注意,此解决方案相当繁重(光线投射大量面),并且可能需要一些预处理来创建 BV。


改变经典轨道控制的基础

这并不完全是您想要的,但它也适合长物体,老实说,这是我提出的不太棘手的解决方案。

这个想法是修改经典操作的基础THREE.OrbitControls,以便修改位置但方向保持不变,如下所示:

轨道控制的新基础

我有点用定制版本做到了:THREE.BasisOrbitControls。看看这个小提琴

var basis = new THREE.Matrix4();
basis.makeScale(2.0, 3.0, 4.0); // my object is very long and a bit tall

var controls = new THREE.BasisOrbitControl(camera, basis, renderer.domElement);
Run Code Online (Sandbox Code Playgroud)

请注意,相机的最终运动由椭球体描述。


希望这有帮助,我也对干净的解决方案很感兴趣。