Three.js 3D缩放至鼠标位置

7
我有一个问题。我的项目是用Three.js + orbitControls.js制作的,用于处理相机。场景中有一个简单的立方体和相机。我有一个来自orbitControls.js的相机,当我滚动鼠标时,它会向屏幕中心缩放(默认行为)。我需要修改它,使其像3D编辑器(如3D Max、blender)中那样,向3D对象上的鼠标位置缩放。
我理解逻辑应该是这样的:从你开始缩放的鼠标位置和实际想要缩放到的位置获取鼠标位置,并存储该值,在缩放过程中缩放并获取新的鼠标位置,找到第一个鼠标位置和当前位置之间的偏移量,并将相机移动到该偏移量。
但是,它没有正常工作。我认为主要问题在于我的相机坐标和我想要缩放到的位置。
以下是我的代码:
 window.onload = function() {

        var renderer = new THREE.WebGLRenderer();
        var width = 640;
        var height = 480;
        renderer.setSize( width, height );
        var div = document.getElementById('canvas')
        div.appendChild( renderer.domElement );

        var scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera(
            70,
            width / height,
            0.1,
            10000
        );
        camera.position.set( 0, 10, 10 );
        camera.lookAt( scene.position );

        control = new THREE.OrbitControls( camera );

        var geometry = new THREE.CubeGeometry( 5, 5, 5 );
        var material = new THREE.MeshLambertMaterial( { color: 0xFF0000 } );
         mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );

        var light = new THREE.PointLight( 0xFFFF00 );
        light.position.set( 10, 0, 10 );
        scene.add( light );

        var dt = 30;
        var renderFunc = function() {
          update(dt);
          renderer.render(scene,camera);
        };

        setInterval(renderFunc,dt);

        //MY ZOOMING CODE.
        var mouseVector = new THREE.Vector3();
        var projector = new THREE.Projector();  
        var startMousePos = new THREE.Vector3();
        var intersectedPoint = new THREE.Vector3();
        var intersectedOffset = new THREE.Vector3();

//FIND INTERSECTED POSITION ON THE CUBE         
        canvas.onmousemove = function (event)
        {
            mouseVector.x = ( event.clientX / 640 ) * 2 - 1;
            mouseVector.y = - ( event.clientY / 480 ) * 2 + 1;
            startMousePos.x = mouseVector.x;
            startMousePos.y = mouseVector.y;

            var vector = new THREE.Vector3( mouseVector.x, mouseVector.y, 1 );
            projector.unprojectVector( vector, camera );
            var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

            var intersects = ray.intersectObjects( scene.children );

            if ( intersects.length > 0 )
            {
                 intersectedPoint = intersects[0].point;
            }
        }
//HERE I THINK I MUST TRANSLATE MY CAMERA.
        canvas.onmousewheel = function(event)
        {
            if(event.wheelDelta > 0)
            {
                camera.position.x -= intersectedPoint.x;
                camera.position.y -= intersectedPoint.y;
                camera.position.z -= intersectedPoint.z;
            }
            else
            {
                camera.position.x += intersectedPoint.x;
                camera.position.y += intersectedPoint.y;
                camera.position.z += intersectedPoint.z;

            }
        }
    };

有人之前做过这件事吗?你能否向我展示你是如何解决的,或者给我一些处理建议呢?

谢谢!


1
已解决:https://dev59.com/aIDba4cB1Zd3GeqPBz8K#30514984 - RAM
非常感谢!这对我很有帮助! - PolosatiyVjih
3个回答

3
在获取交点后,您可以将其应用为orbitControl的目标,如下所示:
  if ( intersects.length > 0 )
        {
             intersectedPoint = intersects[0].point;
        }

 control.target = intersectedPoint ;

然后,当您缩放时,它会朝您选择的点缩放。

2
尝试一下,它有效。
mousewheel = function (event) {
var factor = 15;
var mX = (event.clientX / jQuery(container).width()) * 2 - 1;
var mY = -(event.clientY / jQuery(container).height()) * 2 + 1;
var vector = new THREE.Vector3(mX, mY, 0.1);
vector.unproject(camera);
vector.sub(camera.position);
if (event.deltaY < 0) {
   camera.position.addVectors(camera.position, vector.setLength(factor));
   controls.target.addVectors(controls.target, vector.setLength(factor));
} else {
   camera.position.subVectors(camera.position, vector.setLength(factor));
   controls.target.subVectors(controls.target, vector.setLength(factor));
}
};

谢谢,它可以工作。但是有没有办法使其平滑地缩放? - Asadbek Eshboev

1
根据这个Pull Request,这个功能将会在r154版本中被整合到three.js中——目前计划于2023年6月28日发布。
此外,这也应该可以处理使用正交相机进行缩放,这在下面的问题中提到了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接