2013-09-16 136 views
3

我有我的應用程序的相機:three.js所旋轉攝像頭在平面

camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
camera.position.z = 1; 
camera.position.y = -5; 
camera.rotateOnAxis(new THREE.Vector3(1, 0, 0), degInRad(90)); 
camera.up = new THREE.Vector3(0, 0, 1); 

,而我在按鍵在render運行的那些代碼必須旋轉的攝像頭:

if (leftPressed) { 
    camera.rotateOnAxis((new THREE.Vector3(0, 1, 0)).normalize(), degInRad(1)); 
} else if (rightPressed) { 
    camera.rotateOnAxis((new THREE.Vector3(0, 1, 0)).normalize(), degInRad(-1)); 
} 
if (upPressed) { 
    camera.rotateOnAxis((new THREE.Vector3(1, 0, 0)).normalize(), degInRad(1)); 
} else if (downPressed) { 
    camera.rotateOnAxis((new THREE.Vector3(1, 0, 0)).normalize(), degInRad(-1)); 
} 

相機旋轉,但不是我需要的方式。我想讓相機像飛機上的FPS(第一人稱射擊)一樣旋轉。見圖片明白我想要什麼...
我嘗試使用sin(1)cos(1)但不能如何理解rotateOnAxis作品,引起translate職能的工作就像一個魅力和方向,她看到什麼動作相機。
P.S.
這是一個docsthree.js也許它有幫助。
要處理我用KeyboardJS
這裏鍵盤事件是degInRad功能:

function degInRad(deg) { 
    return deg * Math.PI/180; 
} 

鏈接上JSFiddle

camera rotation

O - 當前攝像機的方向
- 相機
O-O1的位置 R1 - 當前旋轉方向
R - 我想要
對不起畫面方向。

+0

考慮,而不是使用/修改,'THREE.PointerLockControls'。請參閱http://threejs.org/examples/misc_controls_pointerlock.html。請注意指針鎖定源代碼如何將相機添加爲2個對象的子/孫,以實現所需的效果。 – WestLangley

+0

@WestLangley,這是很好的鏈接,謝謝,但我不需要用鼠標移動相機。 'camera'只用於'controls = new THREE.PointerLockControls(camera); scene.add(controls.getObject());' - 它是'PointerLockControls'內部對象添加到場景中,而不是'camera'本身和'onWindowResize'函數 - 只是應用新屬性,並在'渲染器中。渲染(場景,相機);' - 這裏使用原始的'camera'變量。關於你在說什麼「小孩/孫子」?我真的不明白,你能解釋一下嗎?提前致謝。 – ostapische

+0

注意'PointerLockControls'如何根據需要旋轉相機,除了它使用鼠標而不是鍵盤。爲了達到這個效果,它使用'pitchObject'和'yawObject'技術。查看源代碼。這就是我的意思是「孩子/孫子」。你不必使用'PointerLockControls';你可以自己實現類似的邏輯。 – WestLangley

回答

12

你可能會得到你想要的東西簡單地通過設置camera.rotation.order = 'YXZ';

+2

+1。是的,只需直接增加/減少'camera.rotation.x'和'.y'。 – WestLangley

+0

我認爲這是一個更好的解決方案,謝謝。現在我看到'Object3D.rotation'是一個'Euler'而不是'Vector3'類型... – ostapische

4

相信您在概念上尋找的是相機鑽機設置。在這種方法中,您首先建立一個Object3D作爲「脖子」,然後將相機按照所需的旋轉方式固定在該物體上。然後,您可以將旋轉應用到Object3D以環顧四周,而不會產生擺動效果。爲了進一步提升它,你可以在另一個Object3D中嵌套該「頸部」對象,以充當「身體」,並將該翻譯應用於該對象以移動場景。這樣你就有了一個基本的攝像機控制檯。我修改你的小提琴是這樣的:

編輯:執行更改以更好地適合@ostapische用例。這裏的link

function degInRad(deg) { 
    return deg * Math.PI/180; 
} 
///////////////////////////////// 
function render() { 
    requestAnimationFrame(render); 
    if (leftPressed) { 
     neck.rotation.y += degInRad(1); 
    } else if (rightPressed) { 
     neck.rotation.y -= degInRad(1); 
    } 
    if (upPressed) { 
     camera.rotation.x += degInRad(1); 
    } else if (downPressed) { 
     camera.rotation.x -= degInRad(1); 
    } 
    renderer.render(scene, camera); 
} 
///////////////////////////////// 
var scene, camera, renderer, grass, neck; 
var leftPressed = false; 
var rightPressed = false; 
var upPressed = false; 
var downPressed = false; 
///////////////////////////////// 
window.onload = function() { 
    scene = new THREE.Scene(); 
    camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
    cameraHolder = new THREE.Object3D(); 
    cameraHolder.add(camera); 
    renderer = new THREE.WebGLRenderer(); 
    renderer.rendererSize = {width: window.innerWidth, height: window.innerHeight, quality: 100, maxQuality: 400, minQuality: 20}; 
    renderer.setSize(renderer.rendererSize.width, renderer.rendererSize.height); 
    document.body.appendChild(renderer.domElement); 

    var texture, material, geometry, element; 

    material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
    material.side = THREE.DoubleSide; 
    geometry = new THREE.PlaneGeometry(24, 24); 
    grass = new THREE.Mesh(geometry, material); 
    grass.name = "grass"; 
    scene.add(grass); 

    neck = new THREE.Object3D(); 
    neck.rotateOnAxis(new THREE.Vector3(1, 0, 0), degInRad(90)); 
    neck.up = new THREE.Vector3(0, 0, 1); 
    neck.position.z = 1; 
    neck.position.y = -5; 


    neck.add(camera); 
    scene.add(neck);  

    KeyboardJS.on('left', function() { leftPressed = true; }, function() { leftPressed = false; }); 
    KeyboardJS.on('right', function() { rightPressed = true; }, function() { rightPressed = false; }); 
    KeyboardJS.on('up', function() { upPressed = true; }, function() { upPressed = false; }); 
    KeyboardJS.on('down', function() { downPressed = true; }, function() { downPressed = false; }); 

    render(); 
} 

我要提PointLockControl或FirstPersonControl小提琴,但我看到WestLangley一直這麼好建議。反正好運氣,

+0

您的代碼存在錯誤,但@WestLangley給了我一個好主意,以查看PointerLockControls的源代碼。你可以添加[this](http://jsfiddle.net/ostapische/uFwFC/2/)鏈接到你的答案或修改你的代碼工作狀態,我可以批准答案。 – ostapische

+0

在那裏,修改後的代碼已更新。感謝您的考慮,並感謝@WestLangley的堅實建議。 –