2013-05-13 18 views
9

kullanarak sıfırlayın. Fare etkileşimini sağlamak için OrbitControls.js kullanıyorum. Sahneye, kamerayı herhangi bir fare etkileşiminden önce olduğu duruma "sıfırla" sağlayan bir düğme ekliyorum.Fotoğraf makinesini, OrbitControls.js

Ben herhangi bir etkileşimleri önce camera.position ve camera.rotation kurtarmaya çalıştık

:

 
    camera_initial_position = camera.position; 
    camera_initial_rotation = camera.rotation; 

Ve düğme, ilk konumunu ve rotasyon ayarlanır basıldığında "reset" sonrası:

 
    camera.position = camera_initial_position; 
    camera.rotation = camera_initial_rotation; 

Tava kullanılmadığında iyi çalışır. Kullanıcı fare sağ tuşunu kullanarak tavalarsa, yukarıdaki kod kamerayı "sıfırlayamaz".

Fotoğraf makinesini önceki durumuna sıfırlamak için doğru yöntem nedir? three.js Revizyonu R58

ve bu OrbitControls.js geçerli:

 

/** 
* @author qiao/https://github.com/qiao 
* @author mrdoob/http://mrdoob.com 
* @author alteredq/http://alteredqualia.com/ 
* @author WestLangley/http://github.com/WestLangley 
*/ 

THREE.OrbitControls = function (object, domElement) { 

    this.object = object; 
    this.domElement = (domElement !== undefined) ? domElement : document; 

    // API 

    this.enabled = true; 

    this.center = new THREE.Vector3(); 

    this.userZoom = true; 
    this.userZoomSpeed = 1.0; 

    this.userRotate = true; 
    this.userRotateSpeed = 1.0; 

    this.userPan = true; 
    this.userPanSpeed = 2.0; 

    this.autoRotate = false; 
    this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 

    this.minPolarAngle = 0; // radians 
    this.maxPolarAngle = Math.PI; // radians 

    this.minDistance = 0; 
    this.maxDistance = Infinity; 

    this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; 

    // internals 

    var scope = this; 

    var EPS = 0.000001; 
    var PIXELS_PER_ROUND = 1800; 

    var rotateStart = new THREE.Vector2(); 
    var rotateEnd = new THREE.Vector2(); 
    var rotateDelta = new THREE.Vector2(); 

    var zoomStart = new THREE.Vector2(); 
    var zoomEnd = new THREE.Vector2(); 
    var zoomDelta = new THREE.Vector2(); 

    var phiDelta = 0; 
    var thetaDelta = 0; 
    var scale = 1; 

    var lastPosition = new THREE.Vector3(); 

    var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2 }; 
    var state = STATE.NONE; 

    // events 

    var changeEvent = { type: 'change' }; 


    this.rotateLeft = function (angle) { 

     if (angle === undefined) { 

      angle = getAutoRotationAngle(); 

     } 

     thetaDelta -= angle; 

    }; 

    this.rotateRight = function (angle) { 

     if (angle === undefined) { 

      angle = getAutoRotationAngle(); 

     } 

     thetaDelta += angle; 

    }; 

    this.rotateUp = function (angle) { 

     if (angle === undefined) { 

      angle = getAutoRotationAngle(); 

     } 

     phiDelta -= angle; 

    }; 

    this.rotateDown = function (angle) { 

     if (angle === undefined) { 

      angle = getAutoRotationAngle(); 

     } 

     phiDelta += angle; 

    }; 

    this.zoomIn = function (zoomScale) { 

     if (zoomScale === undefined) { 

      zoomScale = getZoomScale(); 

     } 

     scale /= zoomScale; 

    }; 

    this.zoomOut = function (zoomScale) { 

     if (zoomScale === undefined) { 

      zoomScale = getZoomScale(); 

     } 

     scale *= zoomScale; 

    }; 

    this.pan = function (distance) { 

     distance.transformDirection(this.object.matrix); 
     distance.multiplyScalar(scope.userPanSpeed); 

     this.object.position.add(distance); 
     this.center.add(distance); 

    }; 

    this.update = function() { 

     var position = this.object.position; 
     var offset = position.clone().sub(this.center); 

     // angle from z-axis around y-axis 

     var theta = Math.atan2(offset.x, offset.z); 

     // angle from y-axis 

     var phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y); 

     if (this.autoRotate) { 

      this.rotateLeft(getAutoRotationAngle()); 

     } 

     theta += thetaDelta; 
     phi += phiDelta; 

     // restrict phi to be between desired limits 
     phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, phi)); 

     // restrict phi to be betwee EPS and PI-EPS 
     phi = Math.max(EPS, Math.min(Math.PI - EPS, phi)); 

     var radius = offset.length() * scale; 

     // restrict radius to be between desired limits 
     radius = Math.max(this.minDistance, Math.min(this.maxDistance, radius)); 

     offset.x = radius * Math.sin(phi) * Math.sin(theta); 
     offset.y = radius * Math.cos(phi); 
     offset.z = radius * Math.sin(phi) * Math.cos(theta); 

     position.copy(this.center).add(offset); 

     this.object.lookAt(this.center); 

     thetaDelta = 0; 
     phiDelta = 0; 
     scale = 1; 

     if (lastPosition.distanceTo(this.object.position) > 0) { 

      this.dispatchEvent(changeEvent); 

      lastPosition.copy(this.object.position); 

     } 

    }; 


    function getAutoRotationAngle() { 

     return 2 * Math.PI/60/60 * scope.autoRotateSpeed; 

    } 

    function getZoomScale() { 

     return Math.pow(0.95, scope.userZoomSpeed); 

    } 

    function onMouseDown(event) { 

     if (scope.enabled === false) return; 
     if (scope.userRotate === false) return; 

     event.preventDefault(); 

     if (event.button === 0) { 

      state = STATE.ROTATE; 

      rotateStart.set(event.clientX, event.clientY); 

     } else if (event.button === 1) { 

      state = STATE.ZOOM; 

      zoomStart.set(event.clientX, event.clientY); 

     } else if (event.button === 2) { 

      state = STATE.PAN; 

     } 

     document.addEventListener('mousemove', onMouseMove, false); 
     document.addEventListener('mouseup', onMouseUp, false); 

    } 

    function onMouseMove(event) { 

     if (scope.enabled === false) return; 

     event.preventDefault(); 

     if (state === STATE.ROTATE) { 

      rotateEnd.set(event.clientX, event.clientY); 
      rotateDelta.subVectors(rotateEnd, rotateStart); 

      scope.rotateLeft(2 * Math.PI * rotateDelta.x/PIXELS_PER_ROUND * scope.userRotateSpeed); 
      scope.rotateUp(2 * Math.PI * rotateDelta.y/PIXELS_PER_ROUND * scope.userRotateSpeed); 

      rotateStart.copy(rotateEnd); 

     } else if (state === STATE.ZOOM) { 

      zoomEnd.set(event.clientX, event.clientY); 
      zoomDelta.subVectors(zoomEnd, zoomStart); 

      if (zoomDelta.y > 0) { 

       scope.zoomIn(); 

      } else { 

       scope.zoomOut(); 

      } 

      zoomStart.copy(zoomEnd); 

     } else if (state === STATE.PAN) { 

      var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; 
      var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; 

      scope.pan(new THREE.Vector3(- movementX, movementY, 0)); 

     } 

    } 

    function onMouseUp(event) { 

     if (scope.enabled === false) return; 
     if (scope.userRotate === false) return; 

     document.removeEventListener('mousemove', onMouseMove, false); 
     document.removeEventListener('mouseup', onMouseUp, false); 

     state = STATE.NONE; 

    } 

    function onMouseWheel(event) { 

     if (scope.enabled === false) return; 
     if (scope.userZoom === false) return; 

     var delta = 0; 

     if (event.wheelDelta) { // WebKit/Opera/Explorer 9 

      delta = event.wheelDelta; 

     } else if (event.detail) { // Firefox 

      delta = - event.detail; 

     } 

     if (delta > 0) { 

      scope.zoomOut(); 

     } else { 

      scope.zoomIn(); 

     } 

    } 

    function onKeyDown(event) { 

     if (scope.enabled === false) return; 
     if (scope.userPan === false) return; 

     switch (event.keyCode) { 

      case scope.keys.UP: 
       scope.pan(new THREE.Vector3(0, 1, 0)); 
       break; 
      case scope.keys.BOTTOM: 
       scope.pan(new THREE.Vector3(0, - 1, 0)); 
       break; 
      case scope.keys.LEFT: 
       scope.pan(new THREE.Vector3(- 1, 0, 0)); 
       break; 
      case scope.keys.RIGHT: 
       scope.pan(new THREE.Vector3(1, 0, 0)); 
       break; 
     } 

    } 

    this.domElement.addEventListener('contextmenu', function (event) { event.preventDefault(); }, false); 
    this.domElement.addEventListener('mousedown', onMouseDown, false); 
    this.domElement.addEventListener('mousewheel', onMouseWheel, false); 
    this.domElement.addEventListener('DOMMouseScroll', onMouseWheel, false); // firefox 
    this.domElement.addEventListener('keydown', onKeyDown, false); 

}; 

THREE.OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype); 

cevap

8

Pan operasyon vektör this.center denilen güncelliyor, pan yöntemine bakın sıfırlamak gerekir

this.center.add(distance); 

bu yöntemi çok

this.resetCamera = function () { 
     this.object.position.x= camera_initial_position.xPosition; 
     this.object.position.y = camera_initial_position.yPosition; 
     this.object.position.z = camera_initial_position.zPosition; 
     this.center.x= camera_initial_target.x; 
     this.center.y= camera_initial_target.y; 
     this.center.z= camera_initial_target.z; 
    }; 

görmek ve daha sonra güncelleme yöntemi k olacak eep kameranın

5

ah.adel doğru olduğuna bakın Pan işlemi, kamera denetleyicisinin merkezini güncelleyecektir. Bu nedenle, kamerayı önceden tanımlanmış bir kameraya sıfırlamanız/geri yüklemeniz gerekiyorsa, kamera denetleyici merkezini de ayarlamanız gerekir.

ardından kod sonradan kamerayı geri kamera pozisyonu, rotasyon ve denetim merkezi

var camToSave = {}; 
camToSave.position = camera.position.clone(); 
camToSave.rotation = camera.rotation.clone(); 
camToSave.controlCenter = controls.center.clone(); 

Bu fonksiyonu kullanarak saklamak için basit bir koddur. Kayıtlı kamerayı geri yüklemek için, geri yüklemeKamera işlevini çağırın. şöyle OrbitControls kullanırken bu Kamerayı sıfırlayabilir bu sorunu

+0

değil mi' Bu controls.target? – Tlatis

+2

'controls.center', bir noktada –

18

sahip herkese yardımcı olacaktır

restoreCamera(camToSave.position, camToSave.rotation, camToSave.controlCenter); 

Umut:

controls.reset(); 

Three.js r.71

+1

'controls.target' olarak yeniden adlandırıldı! Teşekkürler! Bu zarif bir yol. Bunun yeni bir ek olduğunu kabul ediyorum. R.88'de çalışmıyor mu? –

+1

R.66'ya eklendi. – WestLangley

+0

['.saveState'] (https://threejs.org/docs/index.html#examples/controls/OrbitControls.saveState) Denetimlerin geçerli durumunu kaydedin. Bu daha sonra .reset ile kurtarılabilir. – zwcloud

İlgili konular