#How to zoom out to fit all objects in view?

8 messages · Page 1 of 1 (latest)

foggy tinsel
foggy tinsel
#
    function does_model_fit() {
        const raycaster = new THREE.Raycaster();
        let pointer = new THREE.Vector2();
    
        var objects = []
        Outliner.elements.forEach(element => {
            if (element.mesh && element.mesh.geometry && element.visibility) {
                objects.push(element.mesh);
            }
        })

        function is_object_hit(x, y) {
            pointer.x = ( x / Preview.selected.width ) * 2 - 1;
            pointer.y = - ( y / Preview.selected.height ) * 2 + 1;
            raycaster.setFromCamera(pointer, Preview.selected.camera)
            return raycaster.intersectObjects(objects).length > 0;
        }
    
        // check top and bottom pixels
        for (let y of [0, Preview.selected.height]) {
            for (let x = 0; x < Preview.selected.width; x++) {
                if (is_object_hit(x, y)) return false;
            }
        }
    
        // check left and right pixels
        for (let x of [0, Preview.selected.width]) {
            for (let y = 0; y < Preview.selected.height; y++) {
                if (is_object_hit(x, y)) return false;
            }
        }
    
        return true;
    }

    async function fit_model(zoom_in, zoom_out) {
        let zoom_max = 1000;
        if (zoom_in) {
            for (let i = 0; i < zoom_max; i++) {
                // zoom in until model doesnt fit
                if (!does_model_fit()) break;
                setZoomLevel('in');
                await new Promise((resolve) => setTimeout(resolve, 1));
            }
            setZoomLevel('out');
            setZoomLevel('out');
        }
        if (zoom_out) {
            for (let i = 0; i < zoom_max; i++) {
                // zoom out until model fits
                if (does_model_fit()) break;
                setZoomLevel('out');
                await new Promise((resolve) => setTimeout(resolve, 1));
            }
        }
    }
await fit_model(true, true);
#

heres my implementation in case anyone else needs it

#

it basically checks the preview scene's outer pixels, and if it detects an object it will zoom out

#

its not perfect because it only zooms out if an object is at the preview border. so if an object is completely outside of the view, it wont keep zooming out to find it. you could technically scan every pixel in the view and count the objects to make sure they are all visible, and if not, then keep zooming. but checking every pixel with a raycast is very slow. so if anyone has a better idea lmk

late inlet