Три.js: показать мировые координатные оси в углу сцены
Это, вероятно, очень простая проблема, но я еще не нашел решения, и это меня беспокоит. Я хотел бы показать стрелки, указывающие направления мировых координат (x, y, z) в нижнем правом углу камеры, как это делается в майя, так что при вращении камеры вокруг объекта или перемещении по сцене вы все еще можете определить направления мировых координат. Я попытался сделать это, используя два разных подхода, и ни один из них не сработал так далеко.
У меня есть объект с тремя стрелками в качестве детей, использующих класс THREE.ArrowHelper
, мы назовем его XYZ
на данный момент. Первый подход состоит в том, чтобы сделать XYZ
дочерним элементом сцены и предоставить ему положение, вычисленное из текущего положения камеры плюс смещение в направлении, в котором камера указывает, и настроить его так, чтобы он появился в углу, который я хочу, а не в центре экрана. У меня почти получилось это работать, так как стрелки поддерживают правильное вращение, но положение это немного смешно, и я перестал идти по этому маршруту, потому что он был действительно "нервным", когда перемещал камеру. Я не уверен, была ли это проблема производительности или что-то еще.
XYZ
дочерним элементом камеры с локальным смещением положения, а затем обратить вращение камеры и применить обратное вращение к XYZ
, чтобы оно соответствовало мировым координатам. Я, кажется, близок, используя этот метод, но я могу либо получить правильную позицию, либо вращение правильное, не то и другое.
В настоящее время я использую код XYZ.matrix.extractRotation( camera.matrixWorldInverse );
, чтобы обеспечить мне правильную ориентацию для XYZ
, но его позиционирование отключено. Если я использую XYZ.matrixWorld.extractRotation( camera.matrixWorldInverse );
, то положение остается прекрасным (прикрепленным к камере), но ориентация не меняется.
Если у кого-то есть быстрый хак, чтобы заставить это работать, он будет очень признателен. Если у вас есть лучший метод, чем тот, который я использую, то это также будет полезно.
* * - правка - ** Наверное, стоит упомянуть, что вы можете найти рабочую версию можно здесь - (https://googledrive.com/host/0B45QP71QXoR0Mm9Mbkp3WGI1Qkk/) я храню свой код в google drive, но работаю локально, используя wamp и aliasing, что означает, что любые изменения, которые я делаю локально, отражаются в интернете, как только 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/
Три.Яш Р.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);