简体   繁体   English

OrbitControl-限制平移运动

[英]OrbitControl - restrict panning movement

Is there any way to restrict the panning movement of a camera in scene? 有什么方法可以限制摄像机在场景中的平移运动?

Tried altering the pan method in orbitControls but I'm not really satisfied with the result, I wish there was more convenient/proper way to do it.. 尝试更改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 );

}

I have encountered the same problem. 我遇到了同样的问题。 The solution is not to touch the pan() function but to check the limits in the update() function. 解决方案不是触摸pan()函数,而是检查update()函数中的限制。 Locate the line 162: 找到第162行:

// move target to panned location
scope.target.add( panOffset );

Do your limit calculations right after this line: 在此行之后进行极限计算:

if (scope.target.x > 1000)
    scope.target.setX(1000);
if (scope.target.x < 0)
    scope.target.setX (0);
...

This will clamp the target x-position. 这将锁定目标x位置。 It works quite smoothly. 它工作非常顺利。

I have the exact same problem and thanks to David's solution, which gives me a lot of inspiration. 我也有同样的问题,这要归功于David的解决方案,这给了我很多启发。 I've some add up to David's answer: 我对David的答案加了一些:

If we only set target X, when keep panning to that limit, I have some unwanted rotation effect. 如果仅将目标X设置为水平,则在将平移到该限制时,会有一些不必要的旋转效果。 This is because OrbitControls is working with 2 things: the target and the camera. 这是因为OrbitControls正在处理两件事:目标和相机。 To solve that, we need to set both target and the camera. 为了解决这个问题,我们需要同时设置目标和摄像机。

scope.target.setX(0); 
camera.position.setX(0);

In this way, we guarantee the camera is always on the top of the object, hence no unwanted rotation happens. 通过这种方式,我们可以确保相机始终位于物体的顶部,因此不会发生不必要的旋转。

If we want to keep the current rotation angle, we need to do some math. 如果要保持当前旋转角度,则需要做一些数学运算。 For example in my case, I only enabled the polar rotation: 例如,在我的情况下,我仅启用了极旋转:

let polarAngle = scope.getPolarAngle(); 
scope.target.set(0, camera.position.y + camera.position.z * Math.tan(polarAngle), 0);
camera.position.setX(0);

The idea is to set both target and camera position, but don't try to change the rotation angle. 这个想法是同时设置目标位置和摄像机位置,但不要尝试更改旋转角度。 If there is rotation, do some math to calculate the target position first. 如果存在旋转,请先做一些数学运算以计算目标位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM