2013-02-07 39 views
2

我有一個物體可以移動並旋轉,並且我希望相機在它後面保持一定的距離。要清楚,我正在繪製一架飛機,並希望相機始終注視其後方。 (除非用戶拖動鼠標,例如在飛機飛行時看它的頂部)。在three.js中放置相機W.R.T三維物體

所以說,我已經設置了飛機的位置和旋轉(THREE.Object3D的實例):

airplane.position = {x: 1, y:2, z: 3}; 
airplane.rotation = {x: Math.PI/4, y:1.2, z: 0}; 

並說,當旋轉和位置(0,0,0)相機在(5,0,0)(即飛機中心後面5個單位)處,尋找位置矢量以設置攝像機的最簡單方法是什麼?

謝謝

對不起,代碼蔓延,我砍死它。我會做一個的jsfiddle它,但沒有得到一個服務器託管three.js所上...

$(function(){ 
    var camera1, camera2, scene, renderer, viewPort; 
    var objectManager; 
    var views = []; 
    var vpWidth, vpHeight; 
    init(); 
    animate(); 
    updateSize(); 
    function updateSize(){ 
     vpWidth = viewPort.innerWidth(); 
     vpHeight = viewPort.innerHeight(); 
    } 
    function init() { 
     viewPort = $('#viewPort'); 
     objectManager = new ObjectManager(); 

     views[0] = new View(viewPort, objectManager); 
     var view = views[0]; 
     view.fov = 20; 
     view.proportions.height = 0.5; 
     view.proportions.bottom = 0.5; 
     view.init(); 
     views[1] = new View(viewPort, objectManager); 
     var view = views[1]; 
     view.fov = 10; 
     view.proportions.height = 0.5; 
     view.init(); 
     view.updateCamera = function(){ 

      //----------------------------------------------------- 
      // when the user drags the mouse, (not yet implemented) 
      // the following camera position numbers would change 
      // so that he could view for example the top of the 
      // airplane as it flies 
      //----------------------------------------------------- 
      this.camera.position.set(5,5,5); 

      //----------------------------------------------------- 
      // This line does not work as expected: the airplane 
      // does not stay in the center of the view but follows 
      // some sort of curved path with respect to the camera 
      //----------------------------------------------------- 
      this.camera.lookAt(objectManager.airplane.position); 

      this.camera.updateProjectionMatrix(); 
     }; 
     scene = new THREE.Scene(); 
     objectManager.addTo(scene); 

     objectManager.airplane.add(views[1].camera); 

     //----------------------------------------------- 
     // The following two lines *do* work correctly // 
     //----------------------------------------------- 
     views[1].camera.position.set(0,0,5); 
     views[1].camera.lookAt(objectManager.airplane.position); 

     var ambientLight = new THREE.AmbientLight(0x808080); 
     scene.add(ambientLight);   

     var pointLight = new THREE.PointLight(0x808080); 
     pointLight.position = {x: 100, y: 100, z: 100}; 
     scene.add(pointLight);  

     renderer = new THREE.WebGLRenderer(); 
     renderer.setClearColorHex(0x000000, 1); 
     renderer.setSize(viewPort.innerWidth(), viewPort.innerHeight()); 
     viewPort.get(0).appendChild(renderer.domElement); 
    } 

    function animate() { 
     requestAnimationFrame(animate); 
     render(); 
    } 
    function render() { 
     objectManager.tick(); 
     var view; 
     for (var i in views){ 
      view = views[i]; 
      view.updateCamera(); 
      pixels = view.pixels; 
      renderer.setViewport(pixels.left, pixels.bottom, pixels.width, pixels.height); 
      renderer.setScissor(pixels.left, pixels.bottom, pixels.width, pixels.height); 
      renderer.enableScissorTest(true); 
      renderer.render(scene, view.camera); 
     } 
    } 
}); 
function View(vp, om){ 
    this.objectManager = om; 
    this.viewPort = vp; 
    this.fov = 30; 
    this.proportions = { left: 0, bottom: 0, height: 1, width: 1 }; 
    this.pixels = { left: 0, bottom: 0, height: 0, width: 0, aspect: 0 }; 
    this.aspect; 
    this.init = function(){ 
     this.camera = new THREE.PerspectiveCamera( 
       this.fov, 
       this.viewPort.innerWidth()/this.viewPort.innerHeight(), 
       0.1, 10000 
     ); 
     this.pixels.left = Math.floor(this.proportions.left * this.viewPort.innerWidth()); 
     this.pixels.width = Math.floor(this.proportions.width * this.viewPort.innerWidth()); 
     this.pixels.bottom = Math.floor(this.proportions.bottom * this.viewPort.innerHeight()); 
     this.pixels.height = Math.floor(this.proportions.height * this.viewPort.innerHeight()); 
     this.pixels.aspect = this.pixels.width/this.pixels.height; 
     this.camera.position.y = 0; 
     this.camera.position.z = 10; 
     this.camera.aspect = this.pixels.aspect; 
     this.camera.updateProjectionMatrix(); 
    }; 
    this.updateCamera = function(){}; 
} 

function newCube(dims, pos, cols, colAss){ 
    var mesh; 
    var geometry; 
    var materials = []; 
    geometry = new THREE.CubeGeometry(dims.x, dims.y, dims.z); 
    for (var i in cols){ 
     materials[i] = new THREE.MeshLambertMaterial({ color: cols[i], ambient: cols[i], overdraw: true }); 
    } 
    geometry.materials = materials; 
    for (var i in colAss){ 
     geometry.faces[i].materialIndex = colAss[i]; 
    } 
    mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials)); 
    mesh.position = pos; 
    return mesh; 
} 
function ObjectManager(){ 
    this.airplane; 
    var fuselage; 
    var tail; 
    var grid; 
    this.addTo = function(scene){ 
     this.airplane = new THREE.Object3D(); 
     fuselage = newCube(
       {x: 1, y: 0.1, z: 0.1}, 
       {x: 0, y: 0, z: 0}, 
       [0xffff00, 0x808000, 0x0000ff, 0xff00000, 0xffffff, 0x808080], 
       [0, 1, 2, 3, 4, 5] 
     ); 
     this.airplane.add(fuselage); 
     tail = newCube(
       {x: 0.15, y: 0.2, z: 0.05}, 
       {x: 0.5, y: 0.199, z: 0}, 
       [0xffff00, 0x808000, 0x0000ff, 0xff00000, 0xffffff, 0x808080], 
       [0, 1, 2, 3, 4, 5] 
     ); 
     this.airplane.add(tail); 
     scene.add(this.airplane); 

     grid = new THREE.Object3D(); 

     var geometry = new THREE.Geometry(); 
     geometry.vertices.push(new THREE.Vector3(- 200, 0, 0)); 
     geometry.vertices.push(new THREE.Vector3(200, 0, 0)); 

     linesMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00, opacity: 1, linewidth: .1 }); 

     for (var i = 0; i <= 200; i ++) { 

      var line = new THREE.Line(geometry, linesMaterial); 
      line.position.z = (i * 2) - 200; 
      grid.add(line); 

      var line = new THREE.Line(geometry, linesMaterial); 
      line.position.x = (i * 2) - 200; 
      line.rotation.y = 90 * Math.PI/180; 
      grid.add(line); 
     }  
     scene.add(grid); 

    }; 
    this.tick = function(){ 
     this.airplane.rotation.x += 0.005; 
     this.airplane.rotation.y += 0.01; 
     this.airplane.position.x += 0.01; 
    }; 
}; 

回答

4

添加的攝像頭作爲飛機的一個孩子,來代替。

airplane.add(camera); 
camera.position.set(5, 0, 0); 
camera.lookAt(new THREE.Vector3(0, 0, 0)); 

現在,當您旋轉/移動飛機時,相機會自動跟隨。

+0

謝謝 - 但這不適用於我,它將相機位置設置爲(5,0,0)在世界空間中,並且當我改變飛機位置時相機不移動。 (然而,即使在飛機旋轉時,它仍保持朝向使得它看起來與飛機的同一側相同) – Jodes

+0

如果相機是飛機的孩子,那麼當飛機移動時它會移動。你能提供一個生動的例子嗎? – WestLangley

+0

我已經發布到問題的代碼,包括你的建議 – Jodes