首页 文章

使用鼠标在Three.js中旋转相机

提问于
浏览
54

我的场景中有很多物体,所以旋转所有物体都会很痛苦 . 那么在鼠标点击和拖动时最简单的方法是将相机移动到原点?这样,场景中的所有灯光,物体都在同一个位置,因此唯一改变的是相机 . Three.js没有提供围绕某个点旋转相机的方法,或者它是什么?

谢谢

5 回答

  • 0

    看看下面的例子

    http://threejs.org/examples/#misc_controls_orbit

    http://threejs.org/examples/#misc_controls_trackball

    还有其他不同鼠标控件的例子,但这两个都允许相机围绕一个点旋转并使用鼠标滚轮进行放大和缩小,主要区别在于OrbitControls强制执行摄像机向上方向,而TrackballControls允许摄像机向上旋转-下 .

    您所要做的就是在html文档中包含控件

    <script src="js/OrbitControls.js"></script>
    

    并在您的来源中包含此行

    controls = new THREE.OrbitControls( camera, renderer.domElement );
    
  • 2

    OrbitControls和TrackballControls似乎很适合这个目的 .

    controls = new THREE.TrackballControls( camera );
    controls.rotateSpeed = 1.0;
    controls.zoomSpeed = 1.2;
    controls.panSpeed = 0.8;
    controls.noZoom = false;
    controls.noPan = false;
    controls.staticMoving = true;
    controls.dynamicDampingFactor = 0.3;
    

    在渲染中更新

    controls.update();
    
  • 55

    这可能是移动/ rotating /用鼠标/触控板缩放相机的好起点(在打字稿中):

    class CameraControl {
        zoomMode: boolean = false
        press: boolean = false
        sensitivity: number = 0.02
    
        constructor(renderer: Three.Renderer, public camera: Three.PerspectiveCamera, updateCallback:() => void){
            renderer.domElement.addEventListener('mousemove', event => {
                if(!this.press){ return }
    
                if(event.button == 0){
                    camera.position.y -= event.movementY * this.sensitivity
                    camera.position.x -= event.movementX * this.sensitivity        
                } else if(event.button == 2){
                    camera.quaternion.y -= event.movementX * this.sensitivity/10
                    camera.quaternion.x -= event.movementY * this.sensitivity/10
                }
    
                updateCallback()
            })    
    
            renderer.domElement.addEventListener('mousedown', () => { this.press = true })
            renderer.domElement.addEventListener('mouseup', () => { this.press = false })
            renderer.domElement.addEventListener('mouseleave', () => { this.press = false })
    
            document.addEventListener('keydown', event => {
                if(event.key == 'Shift'){
                    this.zoomMode = true
                }
            })
    
            document.addEventListener('keyup', event => {
                if(event.key == 'Shift'){
                    this.zoomMode = false
                }
            })
    
            renderer.domElement.addEventListener('mousewheel', event => {
                if(this.zoomMode){ 
                    camera.fov += event.wheelDelta * this.sensitivity
                    camera.updateProjectionMatrix()
                } else {
                    camera.position.z += event.wheelDelta * this.sensitivity
                }
    
                updateCallback()
            })
        }
    }
    

    把它放进去:

    this.cameraControl = new CameraControl(renderer, camera, () => {
        // you might want to rerender on camera update if you are not rerendering all the time
        window.requestAnimationFrame(() => renderer.render(scene, camera))
    })
    

    控制:

    • 移动 [holding mouse left / single finger on trackpad] 移动相机在x / y平面

    • move [mouse wheel / two fingers on trackpad] 在z方向上/下移动

    • hold shift + [mouse wheel / two fingers on trackpad] 通过增加/减少视野来放大/缩小

    • 移动 holding [mouse right / two fingers on trackpad] 旋转相机(四元数)

    另外:

    如果你想通过改变'距离'(沿着yz)而不是改变视野,你可以提高/减小相机的位置y和z,同时保持位置y和z的比例不变,如:

    // in mousewheel event listener in zoom mode
    const ratio = camera.position.y / camera.position.z
    camera.position.y += (event.wheelDelta * this.sensitivity * ratio)
    camera.position.z += (event.wheelDelta * this.sensitivity)
    
  • 40

    Here's a project with a rotating camera . 从源头看,似乎只是将相机位置移动了一圈 .

    function onDocumentMouseMove( event ) {
    
        event.preventDefault();
    
        if ( isMouseDown ) {
    
            theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 )
                    + onMouseDownTheta;
            phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 )
                  + onMouseDownPhi;
    
            phi = Math.min( 180, Math.max( 0, phi ) );
    
            camera.position.x = radious * Math.sin( theta * Math.PI / 360 )
                                * Math.cos( phi * Math.PI / 360 );
            camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
            camera.position.z = radious * Math.cos( theta * Math.PI / 360 )
                                * Math.cos( phi * Math.PI / 360 );
            camera.updateMatrix();
    
        }
    
        mouse3D = projector.unprojectVector(
            new THREE.Vector3(
                ( event.clientX / renderer.domElement.width ) * 2 - 1,
                - ( event.clientY / renderer.domElement.height ) * 2 + 1,
                0.5
            ),
            camera
        );
        ray.direction = mouse3D.subSelf( camera.position ).normalize();
    
        interact();
        render();
    
    }
    

    Here's another demo并且在这一个中我认为它只是以相机作为参数创建一个新的 THREE.TrackballControls 对象,这可能是更好的方法 .

    controls = new THREE.TrackballControls( camera );
    controls.target.set( 0, 0, 0 )
    
  • 3

    看看THREE.PointerLockControls

相关问题