3gwebtrain
3gwebtrain

Reputation: 15303

Preload approach for stl file loading

In my scene I have 2 Mesh properties. One, of them create, the other one is from stl file. When I load the page, only the mesh what I created comes on visible. The next one from stl file not showing at all.

I understand that, it takes time to load the file and render the mesh. To fix that, I added a setTimeout function. It works well.

But what is the correct approach to call the renderer function after all mesh loaded?

Example: in jQuery I use the $when().done() - how to handle here?

My code:

$(function () {

    var scene, camera, renderer;

    var init = function () {

        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera (45, window.innerWidth / window.innerHeight, 0.1, 1000 );
        renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0xEEEEEE);

        var axes = new THREE.AxisHelper(20);
        scene.add(axes);


        var cubeGeometry = new THREE.BoxGeometry(4, 4, 4)
        var cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000});

        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.position.x = -4;
        cube.position.y = 3;
        cube.position.z = 0;
        scene.add(cube);

        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        var loader = new THREE.STLLoader();

        loader.load('stl/model.stl', function ( geometry ) {

            var material = new THREE.MeshPhongMaterial( { color: 0xffffff } );
            var mesh = new THREE.Mesh( geometry, material );
            mesh.position.set( 0, - 0.25, 0.6 );
            mesh.rotation.set( 0, - Math.PI / 2, 0 );
            mesh.scale.set( 0.5, 0.5, 0.5 );
            mesh.castShadow = true;
            mesh.receiveShadow = true;
            scene.add( mesh );

        } );

        setTimeout(function () {

            $('#webGL').append(renderer.domElement);
            renderer.render(scene, camera)

        }, 100)

    }

    function render () {



    }

    init();

})

Upvotes: 0

Views: 291

Answers (1)

Falk Thiele
Falk Thiele

Reputation: 4494

One correct approach are you utilizing already, the callback function. The callback is executed when the loader has loaded the model, just add your renderer-call to it:

loader.load('stl/model.stl', function ( geometry ) {
    // this is the callback function
    // do some stuff with your model
    scene.add( mesh );
    renderer.render( scene, camera );
 } );

In three.js there are also Loading Managers, see my other posts about preloading OBJ+MTL here: Preloading Obj+Mtl Objects in Three.js.

Loading with a manager:

var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
    // this gets called after an object has been loaded
};
manager.onLoad = function () {
    // everything is loaded
    renderer.render( scene, camera );
};

var loader = new THREE.STLLoader( manager );

loader.load('stl/model.stl', function ( geometry ) {

    var material = new THREE.MeshPhongMaterial( { color: 0xffffff } );
    var mesh = new THREE.Mesh( geometry, material );
    mesh.position.set( 0, - 0.25, 0.6 );
    mesh.rotation.set( 0, - Math.PI / 2, 0 );
    mesh.scale.set( 0.5, 0.5, 0.5 );
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    scene.add( mesh );

} );

Upvotes: 1

Related Questions