10

Это, вероятно, очень простая проблема, но я еще не нашел решение, и это меня прослушивало. Я хотел бы показать стрелки, указывающие направления координат мира (x, y, z) в нижнем правом углу камеры, как это сделано в Maya, так что при повороте камеры вокруг объекта или перемещении по сцене, вы все же можете определить направления мировых координат. Я попытался выполнить это, используя два разных подхода, и ни один из них не работал до сих пор.Three.js: Показывать координатные оси мира в углу сцены

У меня есть объект с тремя стрелками, как дети, используя класс THREE.ArrowHelper, назовем его XYZ. Первый подход состоит в том, чтобы сделать XYZ ребенком сцены и предоставить ему позицию, рассчитанную из текущего положения камеры, плюс смещение в направлении, которое камера указывает и отрегулировать так, чтобы оно отображалось в углу, в котором я хочу, вместо того, чтобы центр экрана. Я почти получил эту работу, так как в стрелках поддерживается правильное вращение, но положение немного смешно, и я прекратил идти по этому маршруту, потому что это было действительно «неудобно» при перемещении камеры. Я не уверен, было ли это проблемой производительности или чем-то еще.

Второй способ состоит в том, чтобы сделать XYZ ребенком камеры с локальным смещением положения, а затем отменить поворот камеры и применить обратное вращение к XYZ, чтобы он соответствовал мировым координатам. Похоже, что я использую этот метод близко, но я могу либо правильно определить позицию, либо правильность вращения, а не то, и другое.

Я в настоящее время использую код XYZ.matrix.extractRotation(camera.matrixWorldInverse);, чтобы обеспечить правильную ориентацию для XYZ, но это позиционирование отключено. Если я использую XYZ.matrixWorld.extractRotation(camera.matrixWorldInverse);, тогда положение остается точным (прикреплено к камере), но ориентация не меняется.

Если у кого есть быстрый взлом, чтобы получить эту работу, это будет очень признательно. Если у вас есть лучший метод, чем тот, который я преследую, это тоже будет полезно.

** - EDIT - ** вероятно, следует отметить, что вы можете найти рабочую версию здесь - (https://googledrive.com/host/0B45QP71QXoR0Mm9Mbkp3WGI1Qkk/) Я хранящую свой код в Google Диск, но работаю локально с помощью WAMP и сглаживание, что означает, что любые изменения, которые я сделать локально получать информацию в Интернете, как только синхронизация Google. И.Е. это может быть нарушено, когда вы посмотрите.

ответ

12

Это произошло до here.

Хитрость заключается в том, чтобы добавить вторую сцену со второй камерой, которая имеет ту же ориентацию, что и исходная камера, но поддерживает заданное расстояние от начала координат.

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

EDIT: Обновленная скрипка: http://jsfiddle.net/aqnL1mx9/

Three.js R.69

+0

Пропущено эту ссылку. Я рассмотрю этот метод и вернусь к вам. Тем не менее, мне интересно, добавит ли вторая камера снижение производительности больше, чем использование одного из моих методов выше? – wackozacko

+0

Он работает! Пришлось удалить строку 'camera2.position.sub (controls.target);' поскольку OribtControls.js не поддерживает целевую позицию, но в остальном решение практически одно и то же. – wackozacko

+0

Не удаляйте линию. Используйте 'controls.center' в r.58. – WestLangley

10

С новыми версиями three.js (не знает, так как, когда), вы можете использовать:

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

Артикул: AxisHelper

+0

@Jessica конечно, вот JSFiddle https://jsfiddle.net/84usyfsz/ – Andres

+0

Эта скрипка не делает то, что искали OP ... – trusktr

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' вы создаете каждую секунду? Создайте и повторно используйте его. – WestLangley

+0

Не могли бы вы опубликовать простую скрипку? – trusktr

+0

@trusktr извините за задержку, я добавил исполняемый фрагмент – seveibar

Смежные вопросы