移动相机使所有对象完全适合平截头体 - three.js
Move Camera to make all objects fit exactly inside the frustum - three.js
编辑:我改写了我的问题以帮助遇到同样问题的用户。
我有一个 three.js 场景,我在其中添加了一些球体。
我想将相机移向特定方向,直到所有对象(随机放置在场景中)都"fitting exactly"用户的屏幕。
我找到了问题的答案!
1. 我在一个循环内移动相机(缩放到所需的方向),并且在每次重复中我使用相机的矩阵创建一个新的平截头体
2. 我检查我的任何球体是否与平截头体的平面相交。如果是这样,则意味着我的一个对象的一部分在截头锥体之外,所以我打破循环并将相机移动到它的最后一个位置。
以上可能也适用于任何对象(不仅是球体),因为每个对象都有一个可以计算的 boundingSphere(虽然结果可能不是很精确)。
它在缩小时也有效,您只需将相机从物体移开,直到 none 与所有平面的距离为负(负距离表示物体是 "outside" 平截头体的平面)。
代码(仅用于缩小 - r72):
var finished = false;
var camLookingAt = /* calc. */ ;
while( finished === false ){
var toDirection= camera.position.clone().sub(camLookingAt.clone());
toDirection.setLength(vec.length() - 1); // reduce length for zooming out
camera.position.set(toDirection.x, toDirection.y, toDirection.z);
camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated
var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );
for (var j = frustum.planes.length - 1; j >= 0; j--) {
var p = frustum.planes[j];
for (var i = myMeshSpheres.length - 1; i >= 0; i--) {
var sphere = new THREE.Sphere(myMeshSpheres[0].position.clone(), myMeshSpheres[0].radius);
if( p.distanceToSphere(sphere) < 1 ){ // if is negative means part of sphere is outside plane/frustum
finished = true;
}
}
}
编辑:我改写了我的问题以帮助遇到同样问题的用户。
我有一个 three.js 场景,我在其中添加了一些球体。
我想将相机移向特定方向,直到所有对象(随机放置在场景中)都"fitting exactly"用户的屏幕。
我找到了问题的答案!
1. 我在一个循环内移动相机(缩放到所需的方向),并且在每次重复中我使用相机的矩阵创建一个新的平截头体
2. 我检查我的任何球体是否与平截头体的平面相交。如果是这样,则意味着我的一个对象的一部分在截头锥体之外,所以我打破循环并将相机移动到它的最后一个位置。
以上可能也适用于任何对象(不仅是球体),因为每个对象都有一个可以计算的 boundingSphere(虽然结果可能不是很精确)。
它在缩小时也有效,您只需将相机从物体移开,直到 none 与所有平面的距离为负(负距离表示物体是 "outside" 平截头体的平面)。
代码(仅用于缩小 - r72):
var finished = false;
var camLookingAt = /* calc. */ ;
while( finished === false ){
var toDirection= camera.position.clone().sub(camLookingAt.clone());
toDirection.setLength(vec.length() - 1); // reduce length for zooming out
camera.position.set(toDirection.x, toDirection.y, toDirection.z);
camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated
var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );
for (var j = frustum.planes.length - 1; j >= 0; j--) {
var p = frustum.planes[j];
for (var i = myMeshSpheres.length - 1; i >= 0; i--) {
var sphere = new THREE.Sphere(myMeshSpheres[0].position.clone(), myMeshSpheres[0].radius);
if( p.distanceToSphere(sphere) < 1 ){ // if is negative means part of sphere is outside plane/frustum
finished = true;
}
}
}