2011-12-08 48 views
52

Tôi có một vài đối tượng trong cảnh để quay tất cả chúng có thể là một cơn đau. Vậy cách dễ nhất để di chuyển camera xung quanh nguồn gốc khi nhấp chuột và kéo là gì? Bằng cách này, tất cả các đèn, vật thể trong cảnh đều ở cùng một vị trí, vì vậy điều duy nhất thay đổi là camera. Three.js không cung cấp cách xoay máy ảnh xung quanh một điểm hoặc thực hiện?Xoay máy ảnh trong Three.js bằng chuột

Cảm ơn bạn

Trả lời

54

Here's a project with a rotating camera. Nhìn qua nguồn có vẻ như chỉ cần di chuyển vị trí máy ảnh trong một vòng tròn.

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 và trong vụ việc này tôi nghĩ rằng nó chỉ tạo ra một đối tượng THREE.TrackballControls mới với máy ảnh như một tham số, đó có lẽ là cách tốt hơn để đi.

controls = new THREE.TrackballControls(camera); 
controls.target.set(0, 0, 0) 
+7

Đảm bảo bạn thêm trình xử lý sự kiện. Trong nguồn, chúng trông như thế này: document.addEventListener ('mousemove', onDocumentMouseMove, false); – meetar

+0

Nó thất bại trong khi làm tương tự như đối với các điều khiển trackball trực quan. Vui lòng giúp tôi thực hiện điều này bằng các điều khiển trackball trực quan bằng camera chỉnh hình. –

+0

Bạn đã đề cập đến mã nguồn nhưng tôi dường như không thể tìm thấy nó. Khi tôi xem các tệp JS được yêu cầu bởi ứng dụng bạn đã liên kết trong Công cụ dành cho Chrome Dev, tôi không thấy mã bạn đã đăng ở trên. Bạn có thể liên kết với nguồn hoặc giải thích cách bạn tìm thấy nó không? Tôi chủ yếu là curios nơi/cách biến isMouseDown và máy chiếu tham chiếu đoạn mã của bạn được xác định. Cảm ơn! – Casey

3

Hãy xem THREE.PointerLockControls

+1

Để tham khảo: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js – defrex

38

hãy xem các ví dụ sau

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

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

có những ví dụ khác cho các điều khiển chuột khác nhau, nhưng cả hai trong số này cho phép máy ảnh xoay quanh một điểm và phóng to và thu nhỏ bằng bánh xe chuột, di chuyển chính fference là OrbitControls thực thi hướng camera lên, và TrackballControls cho phép camera xoay ngược.

Tất cả bạn phải làm là bao gồm các điều khiển trong tài liệu html của bạn

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

và bao gồm dòng này trong mã nguồn của bạn

controls = new THREE.OrbitControls(camera, renderer.domElement); 
+0

Một dòng duy nhất của 'controls = new BA.OrbitControls (camera, renderer.domElement) '' không thể làm cho nó hoạt động. Bạn nên thêm một trình xử lý sự kiện thay đổi và trong trình xử lý gọi 'renderer.render (scene, camera)', hoặc thêm vòng lặp hoạt hình và gọi 'controls.update()' trong 'animate()'. – Halt

0

này có thể đóng vai trò như một điểm khởi đầu tốt cho việc di chuyển/xoay/phóng to máy ảnh bằng chuột/bàn di chuột (theo loại):

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

thả nó trong như:

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

Controls:

  • di chuyển trong khi [giữ chuột trái/ngón tay duy nhất trên trackpad] để di chuyển camera trong x/y máy bay
  • di chuyển [ bánh xe chuột/hai ngón tay trên bàn di chuột] để di chuyển lên/xuống theo hướng z
  • giữ shift + [con chuột/hai fi ngers trên trackpad] để zoom in/out thông qua việc tăng/giảm lĩnh vực-of-view
  • di chuyển trong khi giữ [chuột phải/hai ngón tay trên trackpad] để xoay camera (quaternion)

Ngoài :

Nếu bạn muốn phóng to bằng cách thay đổi 'khoảng cách' (thay vì yz) thay vì thay đổi trường, bạn có thể tăng/giảm vị trí của máy ảnh y và z trong khi vẫn giữ tỷ lệ y và z không thay đổi như:

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

Có vẻ thú vị! Bạn có xảy ra để có một bản demo trực tiếp để kiểm tra? – davidchappy

+0

Tôi không, nhưng đó là một ý tưởng hay, sẽ cập nhật câu trả lời với hy vọng những ngày này – ambientlight