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

时间:2017-03-04 02:25:00

标签: javascript 3d three.js

来自three.js的正常轨道控制非常适合圆形物体,但不适合长物体(特别是变焦近距离时),我正在寻找解决方案来解决这个问题。

很难用文字描述,请从Google查看此webgl示例(放大最大值以查看):https://www.google.com/o3d/shopping/viewer/360?q=ymMBhK8fu3C&o3ds=use_3d enter image description here

这是我正在寻找的顶视图说明: enter image description here

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

非常感谢任何想法。

1 个答案:

答案 0 :(得分:4)

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

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

  1. 相机的位置;
  2. 相机的方向
  3. 在任何情况下,相机必须旋转。所以,我的所有解决方案或多或少都基于THREE.OrbitControls,它充当了“旋转的当前状态”,并为我处理所有DOM事件。

    查看AABB上的最近点

    这个想法如下:

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

    有两种情况:

    1. 边框
      closest point on a border

    2. 角落
      closest point on a corner

    3. this (very tricky) fiddle上测试过。仍然需要修复顶部和底部面(旋转奇点)。

      在边界卷上进行光线投射

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

      • 创建相机应遵循的边界音量;
      • 在此BV上对相机位置进行光线投射;
      • 相机的新位置是交叉点;
      • 相机的新方向是相交面的正常

      我尝试使用带有圆角边框和边角的细分框几何体,以便相机以角度旋转。

      Raycasting on a BV

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

      请参阅this (tricky again) fiddle

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

      Normals interpolated along a face

      请注意,此解决方案非常繁重(光线投射很多面孔),可能需要一些预处理才能创建BV。

      改变经典轨道控制的基础

      这不是你想要的,但它也适用于长物体,老实说,这是我制作的不那么棘手的解决方案。

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

      New basis for orbit control

      我尝试使用自定义版本:THREE.BasisOrbitControls。看看this fiddle

      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);
      

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


      希望这有所帮助,我真的对一个干净的解决方案感兴趣。