Javascript ThreeJS轨道控制设置目标而不查看
我正在尝试为建筑模型制作一个3D查看器。我们加载了模型,并试图与模型进行某种交互。因此,我们使用OrbiControl来旋转、平移和缩放模型 我们希望在查看器中具有这样的行为,即当用户单击并拖动(从而旋转)时,旋转中心位于用户单击的建筑点 我认为改变轨道控制的目标是明智的:Javascript ThreeJS轨道控制设置目标而不查看,javascript,three.js,perspectivecamera,orbital-mechanics,Javascript,Three.js,Perspectivecamera,Orbital Mechanics,我正在尝试为建筑模型制作一个3D查看器。我们加载了模型,并试图与模型进行某种交互。因此,我们使用OrbiControl来旋转、平移和缩放模型 我们希望在查看器中具有这样的行为,即当用户单击并拖动(从而旋转)时,旋转中心位于用户单击的建筑点 我认为改变轨道控制的目标是明智的: control.target.set(newX, newY, newZ); 然而,我在OrbitControl.js文件的源代码中发现,当控件更新时 camera.lookAt() 函数被调用,这将导致相机跳到新位置
control.target.set(newX, newY, newZ);
然而,我在OrbitControl.js文件的源代码中发现,当控件更新时
camera.lookAt()
函数被调用,这将导致相机跳到新位置
有没有办法绕过这个问题?我已经试了几个小时了,似乎什么都没用
尝试更改target0,然后对控件调用reset()。
还尝试将相机换回原来的位置(可能就是这样做的,但我可能尝试得不好。试试这个:
首先将控制装置的位置设置为:
control.center.set(0, 0, 0);
然后这样做:
camera.position.copy(control.center).add(new THREE.Vector3(x, y, z+10));
其中x、y和z是建筑模型的位置
请注意,我已将+10添加到z,以便相机位于模型前面。请将+10更改为其他值,以靠近/远离模型
有没有办法绕过这个问题
简短的回答是“是的,但它没有使用标准版本的OrbitControls.js”。
请继续阅读我的详细推理
我刚刚花了一些时间查看了OrbitControls.js
(r87)的源代码,考虑实现一个增强功能,允许您提供一个可选的第二点,它将用作相机目标
然而,在研究了代码之后,我认为这将是一个不好的特性,无法添加到标准的公共版本中。OrbitControls有许多特性,例如限制视角、最小和最大旋转以及推拉距离的能力,假设摄影机和orbit center是相同的。如果有第二个摄影机标记选项,这些都需要o可以修改为使用轨道中心或相机目标,或者有一个可配置的参数来切换使用哪一个。这将增加数百行额外的代码,使其更难理解,并且都是为了一个非常小的功能
所以…解决方案是:
因为您正在构建一个技术工具,我怀疑您不关心有限的视角、距离或旋转,所以如果我是您,我会将OrbitControls.js
复制到您的项目中,将其重命名为OrbitControls\u customized.js
,并进行所需的更改:
在this.target
下面添加两个新参数,称为this.cameraTarget
和this.cameraTarget
// "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 );
…更改它,使其仅在为真时更新摄影机
if( scope.coupleCenters ){
scope.cameraTarget = scope.target;
}
scope.object.lookAt( scope.cameraTarget );
现在,通过这些更改,您可以放置一个用于查找对象上的点的onMouseDown
事件,设置controls.decoupcenters
到false
并将controls.target
设置到光线投射的交叉点。然后是一个设置controls.target>的onmousedup
事件t
返回控件。cameraTarget
以使其正常工作
我希望这能回答您的问题,并为您提供一些粗略的路线图。以下是Martin Joiner的解决方案(谢谢!!!),该解决方案在以下方面实施: 将第45行改为:
controls.coupleCenters = false;
为此:
controls.coupleCenters = true;
然后按任意键(或单击鼠标左键)查看Wouter Coebergh描述的原始行为,然后再将Martin建议的逻辑添加到自定义轨道控制中。嗨,谢谢你的反馈,但这不是我真正想要的。你正在将相机位置设置在单击的点上,控制目标为0,0,0。但我希望相机位置发生变化,只更新控件的目标!不如用control.target.set(newX,newY,newZ)代替它;这样做:control.center.set(newX,newY,newZ);你解决了这个问题吗?:)不,我实际上没有。如果你仍然感兴趣,我想我可以帮你解决这个问题,但我只想了解你的预期结果。如果用户单击建筑侧面,是否希望控件的中心点成为所单击网格上最近的点?还是单击的建筑网格的中心点?是哪一个,还是我误解了?嗨@MartinJoiner,谢谢你的回复。预期的结果是,动态观察控件的旋转中心是与拖动事件鼠标按下时的第一个面的交点。因此,用户单击并拖动,并且该单击交点应成为旋转目标,而无需更改摄影机的目标。目前,相机的目标是旋转中心Martin,感谢您的精彩教程。我会尽快调查此事,然后再给你回复