Three.js находит края видимой сцены - PullRequest
0 голосов
/ 23 ноября 2018

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

Я провел небольшое исследование для очень простого решения и нашел этот код:

// Get half of the cameras field of view angle in radians
var fov = camera.fov / 180 * Math.PI / 2;
// Get the adjacent to calculate the opposite
// This assumes you are looking at the scene
var adjacent = camera.position.distanceTo( scene.position );
// Use trig to get the leftmost point (tangent = o / a)
var right = Math.tan( fov ) * adjacent  * camera.aspect;

Теперь, когда я использую его, он работает для обеих сторон:

  • left: -right
  • right: right

Но найти нижний край (или верх) с этим сложно, как часто это дает неправильное положение.Например, я делал тесты, и когда я установил окно на 850x920, нижний край далеко вглубь сцены.

Может кто-нибудь помочь понять, как изменить код, чтобы помочь найти все края:

{
    left: ???,
    right: ???,
    top: ???,
    bottom: ???,
}

Возможно, бонус был бы лучшей функцией, где вы могли бы, например, указать угол вместо простого нахождения вершины с жестким кодом, слева и т. Д. ...

что-то вроде:

let findPoint = (deg) => {
    // deg passed for example 270 (top), 90 (bottom) or custom (315)

    return // three.js coords (like 5.5, 3.4)
}

Но наиболее важной является базовая функция для работы. Любая помощь приветствуется.

На фрагменте вы можете увидеть проблему с верхом и низом с помощью прокрутки и посмотреть, как она появляется.

let SCENE_WIDTH = window.innerWidth;
let SCENE_HEIGHT = window.innerHeight;

let FIELD_OF_VIEW = 45;
let ASPECT = SCENE_WIDTH / SCENE_HEIGHT;
let NEAR = 0.1;
let FAR = 10000;

let scene = new THREE.Scene();

let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x8d8d8d, 1);
renderer.setSize(SCENE_WIDTH, SCENE_HEIGHT);
document.getElementById('webgl-container').appendChild(renderer.domElement);

let camera = new THREE.PerspectiveCamera(FIELD_OF_VIEW, ASPECT, NEAR, FAR);
camera.position.set(0, 0, 50);
camera.lookAt(new THREE.Vector3(0, 0, 0));  
scene.add(camera);

let light = new THREE.PointLight(0xffffff, 0.8);
light.position.set(30, 100, 50);
scene.add(light);

/* find edge */
let fov = camera.fov / 180 * Math.PI / 2;
let adjacent = camera.position.distanceTo( scene.position );
let right = Math.tan( fov ) * adjacent  * camera.aspect;

/* right */
let geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
let material = new THREE.MeshPhongMaterial({color: 0x007bff});
let object = new THREE.Mesh( geometry, material );
object.position.x = right;
scene.add(object);

/* left */
let geometry2 = new THREE.TorusGeometry( 10, 3, 16, 100 );
let material2 = new THREE.MeshPhongMaterial({color: 0x007bff});
let object2 = new THREE.Mesh( geometry2, material2 );
object2.position.x = -right;
scene.add(object2);

/* top */
let geometry3 = new THREE.TorusGeometry( 10, 3, 16, 100 );
let material3 = new THREE.MeshPhongMaterial({color: 0x007bff});
let object3 = new THREE.Mesh( geometry3, material3 );
object3.position.y = right;
scene.add(object3);

/* bottom */
let geometry4 = new THREE.TorusGeometry( 10, 3, 16, 100 );
let material4 = new THREE.MeshPhongMaterial({color: 0x007bff});
let object4 = new THREE.Mesh( geometry4, material4 );
object4.position.y = -right;
scene.add(object4);

let controls = new THREE.OrbitControls(camera, renderer.domElement);

function update () {

	renderer.render(scene, camera);
	requestAnimationFrame(update);
}
requestAnimationFrame(update);
#webgl-container {
	position: absolute;
	left: 0;
	top: 0;
	background-color: aqua;
}
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

<div id="webgl-container"></div>
...