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

mik*_*725 60 javascript 3d three.js

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

谢谢

Bur*_*son 60

这是一个带旋转摄像头的项目.从源头看,似乎只是将相机位置移动了一圈.

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();

}
Run Code Online (Sandbox Code Playgroud)

这是另一个演示,在这一个中,我认为它只THREE.TrackballControls是以相机作为参数创建一个新对象,这可能是更好的方法.

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )
Run Code Online (Sandbox Code Playgroud)

  • 确保添加事件侦听器.在源代码中,它们看起来像这样:document.addEventListener('mousemove',onDocumentMouseMove,false); (9认同)

ekc*_*isp 43

看看下面的例子

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

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

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

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

<script src="js/OrbitControls.js"></script>
Run Code Online (Sandbox Code Playgroud)

并在您的来源中包含此行

controls = new THREE.OrbitControls( camera, renderer.domElement );
Run Code Online (Sandbox Code Playgroud)

  • 单行`controls = new THREE.OrbitControls(camera,renderer.domElement);`不能使其工作。您应该添加change事件的处理程序,并在该处理程序中调用`renderer.render(scene,camera) ,或添加动画循环,然后在“ animate()”中调用“ controls.update()”。 (2认同)
  • 我只需导入 OrbitControls 模块并实例化它就可以完成这项工作。无需处理程序或更新调用。(它需要引用渲染器 DOM 元素来附加处理程序本身,并引用渲染器来调用渲染本身。) (2认同)

amb*_*ght 6

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

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()
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

将其放入如下所示:

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))
})
Run Code Online (Sandbox Code Playgroud)

控制:

  • [按住鼠标左键/单指在触控板上]时移动以在 x/y 平面中移动相机
  • 移动[鼠标滚轮/触控板上的两根手指]在 z 方向上向上/向下移动
  • 按住 Shift + [鼠标滚轮/触控板上的两根手指]通过增加/减少视野来放大/缩小
  • 按住[鼠标右键/触控板上的两根手指]移动以旋转相机(四元数)

此外:

如果你想通过改变“距离”(沿着 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)
Run Code Online (Sandbox Code Playgroud)