web-dev-qa-db-ja.com

Three.jsでカメラをマウスで回転させる

シーンにはかなりの数のオブジェクトがあるので、それらをすべて回転させるのは面倒です。では、マウスのクリックとドラッグでカメラをOriginの周りに移動する最も簡単な方法は何ですか?このように、シーン内のすべてのライト、オブジェクトは同じ場所にあるため、変更されるのはカメラだけです。 Three.jsは、ポイントを中心にカメラを回転させる方法を提供しませんか?

ありがとうございました

58
miki725

これは回転カメラを使用したプロジェクトです 。ソースを見ると、カメラの位置が円を描くように移動しているようです。

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

}

別のデモがあります そして、このデモでは新しいTHREE.TrackballControlsカメラをパラメーターとして持つオブジェクト。これはおそらくより良い方法です。

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )
59
Burt Sampson

次の例を見てください

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 );
41
ekcrisp

THREE.PointerLockControlsをご覧ください

3
Pavel Galaton

これは、(TypeScriptで)マウス/トラックパッドでカメラを移動/ 回転 /ズームするための良い出発点として役立つかもしれません:

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))
})

コントロール:

  • 移動中[マウスの左ボタンを押したまま/トラックパッドで1本指] x/y平面でカメラを移動する
  • move [マウスホイール/トラックパッド上の2本の指] z方向に上下に移動する
  • Shiftキーを押しながら[マウスホイール/トラックパッド上の2本の指]視野を拡大/縮小してズームイン/ズームアウトする
  • 移動中[マウスの右ボタン/トラックパッド上の2本の指]を保持カメラを回転させます(クォータニオン)

さらに:

視野を変更する代わりに「距離」(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)
2
ambientlight

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