Three.js查找可见场景的边缘

时间:2018-11-23 07:57:41

标签: javascript math three.js trigonometry

我正在构建一个动画,该动画需要在可见区域之外生成元素,以便可以将它们扔到场景中(例如,从屏幕底部下方开始的喷泉,并且元素正在向场景中射击)。

我对非常​​简单的解决方案进行了研究,发现了以下代码:

// 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

但是要找到底边(或顶部)却很棘手,因为它经常给出错误的位置。例如,我正在进行测试,并且当我将window设置为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>

0 个答案:

没有答案