Programing

마우스로 Three.js에서 카메라 회전

lottogame 2020. 12. 12. 09:56
반응형

마우스로 Three.js에서 카메라 회전


씬에 꽤 많은 오브젝트가 있으므로 모든 오브젝트를 회전하는 것이 고통 스러울 수 있습니다. 그렇다면 마우스 클릭 및 드래그로 원점 주위로 카메라를 이동하는 가장 쉬운 방법은 무엇입니까? 이렇게하면 장면의 모든 조명, 객체가 동일한 위치에 있으므로 카메라 만 변경됩니다. Three.js는 한 지점을 중심으로 카메라를 회전하는 방법을 제공하지 않습니까?

감사합니다


회전 카메라가있는 프로젝트가 있습니다 . 소스를 살펴보면 카메라 위치를 원으로 이동하는 것 같습니다.

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 )

다음 예를 살펴보십시오.

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

THREE.PointerLockControls를 살펴보십시오.


이것은 마우스 / 트랙 패드 (타이프 스크립트에서)로 카메라 를 이동 / 회전 / 확대하기 위한 좋은 시작점 역할을 할 수 있습니다 .

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

통제 수단:

  • 이동하면서 [채 마우스 왼쪽 / 단일 손가락을 트랙 패드] X / Y 평면에 카메라를 이동
  • move [mouse wheel / two fingers on trackpad] to move up/down in z-direction
  • hold shift + [mouse wheel / two fingers on trackpad] to zoom in/out via increasing/decreasing field-of-view
  • move while holding [mouse right / two fingers on trackpad] to rotate the camera (quaternion)

Additionally:

If you want to kinda zoom by changing the 'distance' (along yz) instead of changing field-of-view you can bump up/down camera's position y and z while keeping the ratio of position's y and z unchanged like:

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

OrbitControls and TrackballControls seems to be good for this purpose.

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;

update in render

controls.update();

참고URL : https://stackoverflow.com/questions/8426822/rotate-camera-in-three-js-with-mouse

반응형