Three.js: показать координатные оси мира в углу сцены
Это, вероятно, очень простая проблема, но пока я еще не нашел решение, и это меня исказило. Я хотел бы показать стрелки, указывающие направления координат мира (x, y, z) в нижнем правом углу камеры, как это сделано в Maya, так что при повороте камеры вокруг объекта или перемещении по сцене, вы все же можете определить направления мировых координат. Я попытался выполнить это, используя два разных подхода, и ни один из них не работал до сих пор.
У меня есть объект с тремя стрелками как дети, использующие класс THREE.ArrowHelper
, назовем его XYZ
на данный момент. Первый подход состоит в том, чтобы сделать XYZ
дочерним элементом сцены и предоставить ему позицию, рассчитанную на текущую позицию камеры плюс смещение в направлении, которое камера указывает и настроить, поэтому она появляется в углу, в котором я хочу, вместо в центре экрана. Я почти получил эту работу, так как в стрелках поддерживается правильное вращение, но положение немного смешно, и я прекратил идти по этому маршруту, потому что это было действительно "неудобно" при перемещении камеры. Я не уверен, была ли проблема с производительностью или что-то еще.
Второй способ состоит в том, чтобы сделать XYZ
дочерним элементом камеры с локальным смещением позиции, а затем отменить поворот камеры и применить обратное вращение к XYZ
, чтобы оно соответствовало мировым координатам. Я, кажется, очень близко использую этот метод, но я могу либо получить правильную позицию, либо правильное вращение, не то и другое.
В настоящее время я использую код XYZ.matrix.extractRotation( camera.matrixWorldInverse );
, чтобы обеспечить правильную ориентацию для XYZ
, но это позиционирование отключено. Если я использую XYZ.matrixWorld.extractRotation( camera.matrixWorldInverse );
, тогда положение остается прекрасным (прикреплено к камере), но ориентация не изменяется.
Если кто-то быстро взломает эту работу, это будет очень признательно. Если у вас есть лучший метод, чем тот, который я преследую, это также будет полезно.
** - РЕДАКТИРОВАТЬ - **
Возможно, стоит упомянуть, что здесь вы можете найти рабочую версию - (https://googledrive.com/host/0B45QP71QXoR0Mm9Mbkp3WGI1Qkk/) Я сохраняю свой код на Google Диске, но работаю локально с помощью wamp и aliasing, что означает, что любые изменения, которые я делаю локально, могут отображаться онлайн, как только синхронизация Google. И.Е. это может быть нарушено, когда вы смотрите.
Ответы
Ответ 1
Это появилось до здесь.
Фокус в том, чтобы добавить вторую сцену со второй камерой, которая имеет ту же ориентацию, что и исходная камера, но поддерживает заданное расстояние от начала координат.
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
Ответ 2
С новыми версиями three.js
(не знаю с тех пор) вы можете использовать:
var axisHelper = new THREE.AxisHelper( 5 );
scene.add( axisHelper );
Ссылка: AxisHelper
Ответ 3
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
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())
axisHelper.position.copy(axesPlacement);
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>