10

這可能是一個非常基本的問題,但我還沒有找到解決方案,它一直在竊聽我。我想在Maya中顯示箭頭,指示相機右下角的世界座標方向(x,y,z),這樣當在相機周圍旋轉相機或移動場景時,你仍然可以識別世界座標的方向。我試圖用兩種不同的方法來實現這一點,至今都沒有成功。Three.js:在場景的角落顯示世界座標軸

我有一個使用THREE.ArrowHelper類的三個箭頭的對象,我們暫且稱它爲XYZ。第一種方法是讓XYZ成爲場景的一個孩子,併爲其提供一個根據相機當前位置計算的位置加上相機指向和偏移的位置,以便它在我希望的角落出現而不是在屏幕的中心。我幾乎得到了這個工作,因爲在箭頭中保持正確的旋轉,但是位置有點滑稽,我停止沿着這條路線前進,因爲當移動相機時它真的很「緊張」。我不確定這是一個性能問題還是其他問題。

第二種方法是將XYZ作爲攝像機的一個孩子與本地位置偏移,然後顛倒攝像機的旋轉,並將反向旋轉應用到XYZ,以便它匹配世界座標。我似乎很接近使用這種方法,但我可以得到正確的位置,或旋轉正確,而不是兩個。

我目前使用的代碼XYZ.matrix.extractRotation(camera.matrixWorldInverse);爲我提供了正確的方向XYZ,但它的定位是關閉的。如果我使用XYZ.matrixWorld.extractRotation(camera.matrixWorldInverse);,那麼位置保持不變(連接到相機),但方向不會改變。

如果任何人有一個快速破解得到這個工作,將不勝感激。如果你有一個更好的方法,比我正在追求的方法,那也是有幫助的。 (https://googledrive.com/host/0B45QP71QXoR0Mm9Mbkp3WGI1Qkk/)我在谷歌驅動器中存儲我的代碼,但本地使用wamp和別名工作,這意味着我所做的任何更改只要谷歌驅動器同步,本地即可在線反映。 I.E.當你看一看它可能會被打破。

回答

12

這已經出現在here之前。

訣竅是用第二個相機添加第二個場景,第二個相機的方向與原始相機的方向相同,但與原點保持指定的距離。

camera2.position.copy(camera.position); 
camera2.position.sub(controls.target); 
camera2.position.setLength(CAM_DISTANCE); 
camera2.lookAt(scene2.position); 

編輯:更新小提琴:http://jsfiddle.net/aqnL1mx9/

three.js所r.69

+0

錯過了鏈接莫名其妙。我會研究這種方法並回復你。不過,我想知道如果添加第二個攝像頭會降低性能超過讓我的方法之一以上的工作? – wackozacko 2013-04-26 10:39:27

+0

它的工作原理!不得不刪除線'camera2.position.sub(controls.target);'作爲OribtControls.js不保持目標位置,但在其他的解決方案是幾乎相同的。 – wackozacko 2013-04-26 11:34:34

+0

不要刪除該行。使用r.58中的'controls.center'。 – WestLangley 2013-04-26 14:37:04

10

隨着新版本的three.js(不知道從何時起),可以使用:

var axisHelper = new THREE.AxisHelper(5); 
scene.add(axisHelper); 

參考:AxisHelper

+0

@Jessica肯定的是,這裏是一個的jsfiddle https://jsfiddle.net/84usyfsz/ – Andres 2016-12-15 01:43:55

+0

這撥弄沒有做什麼OP一直在尋找... – trusktr 2017-07-19 22:24:19

1

var camera, scene, renderer, geometry, material, mesh, axisHelper, localToCameraAxesPlacement; 
 

 
init(); 
 
animate(); 
 

 
function init() { 
 

 
    scene = new THREE.Scene(); 
 

 
    camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 10000); 
 
    camera.position.z = 500; 
 
    camera.up = new THREE.Vector3(0,0,1); 
 
    scene.add(camera); 
 
    
 
    axisHelper = new THREE.AxisHelper(0.1) 
 
    localToCameraAxesPlacement = new THREE.Vector3(0.45 * camera.aspect,-0.45, -2); // make sure to update this on window resize 
 
\t \t scene.add(axisHelper) 
 

 
    geometry = new THREE.CubeGeometry(200, 200, 200); 
 
    material = new THREE.MeshNormalMaterial(); 
 

 
    mesh = new THREE.Mesh(geometry, material); 
 
    scene.add(mesh); 
 

 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    document.body.appendChild(renderer.domElement); 
 

 
} 
 

 
function animate() { 
 

 
    requestAnimationFrame(animate); 
 
    render(); 
 

 
} 
 

 
var t = 0 
 
function render() { 
 
    t++ 
 
    
 
    camera.position.x = Math.cos(t/80) * 500 
 
    camera.position.y = Math.sin(t/80) * 500 
 
    camera.lookAt(mesh.position) 
 
    
 
    camera.updateMatrixWorld() 
 
    var axesPlacement = camera.localToWorld(localToCameraAxesPlacement.clone()) 
 
\t \t axisHelper.position.copy(axesPlacement); 
 

 
    renderer.render(scene, camera); 
 

 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>

這是一個「快速和骯髒」的方式來增加一個AxisHelper,而無需創建一個額外的場景。它通過在每個渲染器上將相機前面的軸助手移動來實現。

// Initialize 
var scene = getScene(); 
axisHelper = new THREE.AxisHelper(0.1); 
var localToCameraAxesPlacement = new THREE.Vector3(0.45 * camera.aspect,-0.45,-2); // make sure to update this on window resize 
scene.add(axisHelper); 

// On every render 
var camera = getCamera(); 
camera.updateMatrixWorld(); 
var axesPlacement = camera.localToWorld(localToCameraAxesPlacement.clone()); 
axisHelper.position.copy(axesPlacement); 
+1

多少'Vector3's你實例每一秒?創建一個並重用它。 – WestLangley 2017-05-13 20:22:45

+0

你介意發佈一個簡單的小提琴嗎? – trusktr 2017-07-19 22:24:42

+0

耽擱@trusktr對不起,我添加了一個可運行的代碼段 – seveibar 2017-08-26 07:37:21