Javascript 移动相机,使所有对象正好适合于平截头体-three.js
编辑:我重新表述了我的问题,以帮助用户解决同样的问题 我有一个three.js场景,其中添加了一些球体Javascript 移动相机,使所有对象正好适合于平截头体-three.js,javascript,three.js,intersect,plane,frustum,Javascript,Three.js,Intersect,Plane,Frustum,编辑:我重新表述了我的问题,以帮助用户解决同样的问题 我有一个three.js场景,其中添加了一些球体 我想将相机移向一个特定的方向,直到所有对象(在场景中随机放置)都与用户的屏幕“完全匹配”。我找到了问题的答案 1。我在一个循环内移动相机(缩放到所需的方向),每次重复时,我都使用相机的矩阵创建一个新的平截头体 2.我检查我的球体是否与平截头体平面相交。如果是的话,这意味着我的一个对象的一部分在平截头体之外,所以我打破了循环,将相机移动到它的最后一个位置 上述方法也可能适用于任何对象(不仅仅是球
我想将相机移向一个特定的方向,直到所有对象(在场景中随机放置)都与用户的屏幕“完全匹配”。我找到了问题的答案 1。我在一个循环内移动相机(缩放到所需的方向),每次重复时,我都使用相机的矩阵创建一个新的平截头体 2.我检查我的球体是否与平截头体平面相交。如果是的话,这意味着我的一个对象的一部分在平截头体之外,所以我打破了循环,将相机移动到它的最后一个位置 上述方法也可能适用于任何对象(不仅仅是球体),因为每个对象都有一个可以计算的边界球体(尽管结果可能不是很精确) 当缩小时,它也起作用,您只需将相机从对象上移开,直到所有平面之间都没有负距离为止(负距离表示对象“在”平截头体平面之外) 代码(仅用于缩小-r72):
var finished=false;
var camLookingAt=/*计算*/;
while(finished==false){
var toDirection=camera.position.clone().sub(camLookingAt.clone());
toDirection.setLength(vec.length()-1);//缩小长度以缩小
摄影机.position.set(toDirection.x、toDirection.y、toDirection.z);
camera.updateMatrix();//确保更新了camera的本地矩阵
camera.UpdateMatrix();//确保更新了camera的世界矩阵
var trustum=新的三个.trustum();
setFromMatrix(新的三个.Matrix4().multilyMatrices(camera.projectionMatrix,camera.matrixWorldInverse));
对于(var j=trustum.planes.length-1;j>=0;j--){
var p=平截头体平面[j];
对于(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为负值表示球体的一部分在平面/平截头体外
完成=正确;
}
}
}
这似乎是一个非常低效的解决方案。我正在寻找一个更直接的解决方案,使用相机的平截体平面。
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;
}
}
}