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