在加载了多个gltf文件之后,我将重命名这些文件并尝试重新定位相机,使其居中,并查看新对象的质心,并使整个场景适合相机。
但是定心并不总是有效,有时质心的计算完全不同。加载所有对象后,以下代码仅在render()
中运行一次:
var all_centers = [];
scene.updateMatrixWorld();
scene.traverse(function(child){
if (child instanceof THREE.Mesh){
if (child.name.indexOf("_") !== -1){ // the newly imported objects
child.geometry.computeBoundingSphere();
var the_center = new THREE.Vector3();
child.getWorldPosition(the_center);
all_centers.push(the_center);
}
}
});
var the_centroid = getPointsCentroid(all_centers);
var cameraPosition = new THREE.Vector3(the_centroid.x,the_centroid.y,-55);
camera.position.copy(cameraPosition);
camera.lookAt(the_centroid);
这是质心的功能:
function getPointsCentroid(points){
var centroid = [0.,0.,0.];
for(var i = 0; i < points.length; i++) {
var point = points[i];
centroid[0] += point.x;
centroid[1] += point.y;
centroid[2] += point.z;
}
centroid[0] /= points.length;
centroid[1] /= points.length;
centroid[2] /= points.length;
return new THREE.Vector3(centroid[0],centroid[1],centroid[2]);
}
答案 0 :(得分:0)
现在暂时忽略使整个场景适合相机的问题(这是一个常见问题,我确定您可以在网上找到有用的信息(也许this?)。)
相反,让我们关注似乎是您的主要问题:您希望找到一组对象的中心。您当前正在做的是计算对象中心的平均值。这意味着,如果最左边有一个对象,最右边有9个对象,则计算出的中心点也将最右边。 (假设物体的质量相似,这将是重心的近似值。)
但是,为了使摄像机居中以使每个对象可见,您对质心不感兴趣,但是希望找到一个点,使得到最左点的距离等于到最右边,类似地最低到最高,依此类推。可以使用所有对象的bounding box找到这样的点。该边界框的中心是您要寻找的点。
如果要将相机与轴对齐,则可以轻松地为每个对象计算这样的边界框,如下所示:
new THREE.Box3().setFromObject(myMesh)
所有对象的边界框就是您所计算的所有对象边界框的最低和最高坐标所代表的框。完整边界框的中心将为您提供所要指向的点。
接下来,假设摄影机与轴对齐,问题就是简单地找到从摄影机到此点的合适距离,以使整个边界框都适合视口。