Search code examples
three.jsbounding

how to get the boundingSphere for a whole scene in three.js?


How to get the bounding sphere for a whole scene in three.js? I may try to get the bounding sphere for each object and compute the resulting union of them, but I think there may be a more straight forward method.


Solution

  • There are different methods to get a boundingSphere of multiple objects dynamically. You can get first the bounding box of all of them, and then create a sphere of that bounding box... here is a sample fiddle I have shaped on boundingSphere of a boundingBox.

    enter image description here

    Basically you put all the geometries into a Group, you get the Box3 of the group, and then you do getBoundingSphere from the Box3 and position at the center. Code in the fiddle would be this.

    let g = new THREE.Group();
    scene.add(g);
    for (let i = 0; i < 5; i++) {
    
        // geometry
        var geometry = new THREE.BoxGeometry(20, 20, 20);
    
        // material
        var material = new THREE.MeshToonMaterial({
            color: 0xff0000,
            opacity: 0.7,
        });
    
        // mesh
        mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(100 * Math.random(), 100 * Math.random(), 100 * Math.random());
        g.add(mesh);
    }
    
    //g.updateWorldMatrix(true);
    var gridHelper = new THREE.GridHelper(400, 40, 0x0000ff, 0x808080);
    gridHelper.position.y = 0;
    gridHelper.position.x = 0;
    scene.add(gridHelper);
    
    let bbox = new THREE.Box3().setFromObject(g);
    let helper = new THREE.Box3Helper(bbox, new THREE.Color(0, 255, 0));
    scene.add(helper);
    
    const center = new THREE.Vector3();
    bbox.getCenter(center);
    
    let bsphere = bbox.getBoundingSphere(new THREE.Sphere(center));
    let m = new THREE.MeshStandardMaterial({
        color: 0xffffff,
        opacity: 0.3,
        transparent: true
    });
    var geometry = new THREE.SphereGeometry(bsphere.radius, 32, 32);
    let sMesh = new THREE.Mesh(geometry, m);
    scene.add(sMesh);
    sMesh.position.copy(center);
    

    EDITED: If you want to include in the boundingSphere for the scene including the lights (which could get you a huge sphere), just start from let bbox = new THREE.Box3().setFromObject(scene)