Три.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 и сглаживание, что означает, что любые изменения, которые я делаю локально, отражаются в интернете, как только Google drive синхронизируется. Он может быть сломан, когда вы посмотрите.
3 ответов
Это было раньше здесь.
трюк состоит в том, чтобы добавить вторую сцену со второй камерой, которая имеет ту же ориентацию, что и исходная камера, но поддерживает заданное расстояние от источника.
camera2.position.copy( camera.position );
camera2.position.sub( controls.target );
camera2.position.setLength( CAM_DISTANCE );
camera2.lookAt( scene2.position );
EDIT: обновленная скрипка:http://jsfiddle.net/aqnL1mx9/
три.js r.69
новые three.js
версии вы можете использовать:
var axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
ссылки: AxesHelper
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>
Это "быстрый и грязный" способ добавить 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);