【问题标题】:ThreeJS orbit controls set target without lookAtThreeJS 轨道控制设置目标,无需查看
【发布时间】:2016-06-09 23:51:26
【问题描述】:

我正在尝试制作用于构建模型的 3D 查看器。我们已经加载了模型,并试图与模型进行某种交互。因此,我们使用 OrbiControls 来旋转、平移和缩放模型。

我们希望在查看器中具有这样的行为:当用户单击并拖动(因此旋转)时,旋转中心位于用户单击的建筑物的点。

我认为这样更改 OrbitControl 的目标是明智的:

control.target.set(newX, newY, newZ);

但是,我在 OrbitControl.js 文件的源代码中发现,当控件更新时,

camera.lookAt() 

函数被调用,导致相机跳转到一个新的位置。

有没有办法解决这个问题?我已经尝试了几个小时,但似乎没有任何效果。

尝试更改 target0,然后在控件上调用 reset()。 还尝试将相机改回旧位置(这可能是它的完成方式,但我可能尝试过不好。

【问题讨论】:

  • 你解决了吗? :)
  • 不,我实际上没有
  • 如果您仍然感兴趣,我想我可以为您解决这个问题,但我只是想了解您的预期结果。如果用户单击建筑物的一侧,您希望控件的中心点成为被单击的网格上最近的点吗?还是被点击的建筑物网格的中心点?是哪一个,还是我误解了?
  • 嗨@MartinJoiner,感谢您的回复。预期的结果是轨道控件的旋转中心是与拖动事件鼠标向下的第一个面的交点。所以用户点击并拖动,那个点击交点应该成为旋转目标,而不改变相机的目标。目前,相机的目标是旋转中心

标签: javascript three.js perspectivecamera orbital-mechanics


【解决方案1】:

有什么办法可以解决这个问题吗?

简短的回答是“是的,但它没有使用标准版本的 OrbitControls.js”。

继续阅读我的详细推理......

我刚刚花了一些时间查看OrbitControls.js (r87) 的源代码,考虑实施一种增强功能,允许您提供一个可选的第二点,它将用作相机目标。

但是,在探索了代码之后,我认为添加到标准公共版本中会是一个不好的功能。 OrbitControls 有许多功能,例如限制视角、最小和最大旋转以及小车距离的能力,假设相机和轨道中心是相同的。如果有一个选项 2nd camera tagret 这些都需要修改为使用轨道中心或相机目标,或者有一个可配置的参数来切换它使用哪一个。这将增加数百行额外的代码,使其更难理解,而且都是为了一个非常小众的功能。

所以... 解决方案

因为您正在构建一个技术工具,我怀疑您不关心有限的视角、距离或旋转,所以如果我是您,我会将 OrbitControls.js 复制到您的项目中,将其重命名为 OrbitControls_customised.js 并制作您需要的更改:

this.target下方添加2个新参数,分别称为this.cameraTargetthis.coupleCenters

// "target" sets the location of focus, where the object orbits around
this.target = new THREE.Vector3();

// "cameraTarget" is where the camera is looking (by default the same as target
this.cameraTarget = new THREE.Vector3();

// Whether the camera should be locked to the orbit center
this.coupleCenters = true;

在它指示相机看向中心的那一行...

scope.object.lookAt( scope.target );

...更改它,使其仅在 CoupleCenters 为 true 时更新相机...

if( scope.coupleCenters ){
    scope.cameraTarget = scope.target;
}
scope.object.lookAt( scope.cameraTarget );

现在,进行这些更改后,您可以放置​​一个onMouseDown 事件,该事件使用RayCasting 来查找对象上的点,将controls.decoupleCenters 设置为false 并将controls.target 设置为相交/交叉点的光线投射。然后是一个onMouseUp 事件,将controls.target 设置回controls.cameraTarget 以使其正常运行。

我希望这能回答您的问题,并为您提供一些粗略的工作路线图。

【讨论】:

  • Martin,感谢您的精彩教程。我会尽快调查并回复您
【解决方案2】:

试试这个:

首先将控件的位置设置为:

control.center.set(0, 0, 0);

然后这样做:

camera.position.copy(control.center).add(new THREE.Vector3(x, y, z+10));

其中 x、y 和 z 是您的建筑模型的位置。

请注意,我为 z 添加了 +10,以便相机位于模型前面。将 +10 更改为其他值,以更接近/远离模型。

【讨论】:

  • 您好,感谢您的反馈,但这并不是我真正想要的。您将相机位置设置在单击的点上,控件目标为 0,0,0。然而,我希望改变相机位置,并且只更新控件的目标!
  • 怎么样,而不是 control.target.set(newX, newY, newZ);这样做: control.center.set(newX, newY, newZ);
【解决方案3】:

以下是 Martin Joiner 的解决方案(谢谢!!!)在这个codepen 中实现:

从这里更改第 45 行:

controls.coupleCenters = false;

到这里:

controls.coupleCenters = true;

然后按任意键(或单击鼠标左键)查看 Wouter Coebergh 描述的原始行为,然后将 Martin 推荐的逻辑添加到自定义轨道控制。

【讨论】:

    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    相关资源
    最近更新 更多