2011-12-08 137 views
52

我的场景中有很多物体,所以旋转它们都可能是一种痛苦。那么,通过鼠标点击和拖动来移动相机的最简单方法是什么?这样,场景中的所有灯光,物体都处于相同的位置,所以唯一改变的就是相机。 Three.js没有提供围绕某个点旋转摄像机的方法,或者它可以吗?用鼠标在Three.js中旋转相机

谢谢

回答

54

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

确保您添加了事件侦听器。在源代码中,它们看起来像这样:document.addEventListener('mousemove',onDocumentMouseMove,false); – meetar

+0

与拼写轨迹球控件做同样的操作会失败。请帮助我使用正交相机使用拼写轨迹球控件来做到这一点。 –

+0

你提到了源代码,但我似乎无法找到它。当我查看您在Chrome开发工具中链接到的应用程序请求的JS文件时,我没有看到您上面发布的代码。 你能链接到源代码或解释你如何找到它吗? 我大部分都是古怪的,你的代码片段引用中定义的isMouseDown和projector变量的位置/方式。 谢谢! – Casey

3

看一看THREE.PointerLockControls

+1

参考:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js – defrex

38

看看下面的实施例

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

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

存在用于不同的鼠标控制其它实例中,但两者其中的相机可以围绕一个点旋转,并使用鼠标滚轮进行放大和缩小fference是OrbitControls强制摄像头向上的方向,而TrackballControls允许摄像头颠倒旋转。

所有你需要做的是包括HTML文档

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

在控制和包括该行源

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

一个'控制的单线=新THREE.OrbitControls(照相机,renderer.domElement) ;'不能使它工作。你应该添加一个change事件处理程序,并且在处理程序中调用'renderer.render(scene,camera)',或者添加动画循环并且调用'controls.update()'到'动画()'。 – Halt

0

这可以作为一个很好的起点,移动/ 旋转 /使用鼠标/触控板(打字稿)缩放相机:

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 rerendering all the time 
    window.requestAnimationFrame(() => renderer.render(scene, camera)) 
}) 

控制:

  • 移动而[拿着触控板鼠标左/单个手指]在X/Y平面上移动相机
  • 移动[鼠标滚轮/触控板]两个手指/上下移动在z方向
  • 保持移位+ [鼠标滚轮/ 2网络连接触控板] NGERS到放大/缩小通过增加/减少字段的视图
  • 移动而保持[鼠标上的触控板的右/两个手指]旋转相机(四元)

另外:

如果您想通过改变“距离”(沿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) 
+0

看起来很有意思!你是否有一个现场演示来检查? – davidchappy

+0

我不这样做,但这是一个好主意,它会在最近更新答案 – ambientlight