有没有办法限制相机在场景中的平移运动?
尝试在orbitControls中修改pan
方法,但我对结果并不满意,我希望有更方便/更合适的方法来实现它。
if ( scope.object instanceof THREE.PerspectiveCamera ) {
// perspective
var position = scope.object.position;
var offset = position.clone().sub( scope.target );
var targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
// we actually don't use screenWidth, since perspective camera is fixed to screen height
var dist_l = ( 2 * deltaX * targetDistance / screenHeight );
var dist_u = ( 2 * deltaY * targetDistance / screenHeight );
/////// X,Y limit calculation //////
var limit = 100;
if( (position.x - dist_l) <= -limit ){
dist_l = -0.1;
}else if( (position.x - dist_l) >= limit){
dist_l = 0.1;
}
if( (position.z - dist_u) <= -limit ){
dist_u = -0.1;
}else if( (position.z - dist_u) >= (limit*2.5) ){
dist_u = 0.1;
}
/////// X,Y limit calculation //////
scope.panLeft( dist_l );
scope.panUp( dist_u );
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
// orthographic
scope.panLeft( deltaX * ( scope.object.right - scope.object.left ) / screenWidth );
scope.panUp( deltaY * ( scope.object.top - scope.object.bottom ) / screenHeight );
}
答案 0 :(得分:6)
我遇到了同样的问题。解决方案不是触摸pan()函数,而是检查update()函数中的限制。找到第162行:
// move target to panned location
scope.target.add( panOffset );
在此行之后立即进行限制计算:
if (scope.target.x > 1000)
scope.target.setX(1000);
if (scope.target.x < 0)
scope.target.setX (0);
...
这将钳制目标x位置。它的运作非常顺利。
答案 1 :(得分:0)
由于David的解决方案,我遇到了完全相同的问题,这给了我很多启发。我对大卫的回答加了一些:
如果仅将目标X设置为水平,则在将平移到该限制时,会有一些不必要的旋转效果。这是因为OrbitControls正在处理两件事:目标和相机。为了解决这个问题,我们需要同时设置目标和摄像机。
scope.target.setX(0);
camera.position.setX(0);
通过这种方式,我们确保相机始终位于物体的顶部,因此不会发生不必要的旋转。
如果要保持当前旋转角度,我们需要做一些数学运算。例如,在我的情况下,我仅启用了极旋转:
let polarAngle = scope.getPolarAngle();
scope.target.set(0, camera.position.y + camera.position.z * Math.tan(polarAngle), 0);
camera.position.setX(0);
这个想法是同时设置目标位置和相机位置,但不要尝试更改旋转角度。如果存在旋转,请先做一些数学运算以计算目标位置。