I want to load quite a lot of JSON models and put them in global variables so I can use them to copy, translate, etc. That way I won't have to load a model every time i need one.

I tried some methods but it seems loading the models happens asynchronously.

The models seem to be loaded after everything else is already done. So I will already have declared my variables but they stay empty or don’t work. How do I load the models first, wait until that is done and then start the init() and the rest of my code?

example:

var loader = new THREE.JSONLoader();

var test1 = new THREE.Object3D();
var test2 = new THREE.Object3D();
var test3 = new THREE.Object3D();
var test4 = new THREE.Object3D();
var test5 = new THREE.Object3D();
var test6 = new THREE.Object3D();
var test7 = new THREE.Object3D();

loadparts();
init();
animate();

function init() {
    var newpart = test1.clone();
    console.log("newpart.id:" + newpart.id);
    newpart.position.set(0,0,0);
    scene.add(newpart);

    console.log("test1.children.length:" + test1.children.length);

    placePart(test1,0,100,0);
    placePart(test2,0,200,0);
    placePart(test3,0,300,0);
    placePart(test4,0,400,0);
    placePart(test5,0,500,0);
    placePart(test6,0,600,0);
    placePart(test7,0,700,0);
}

function loadparts( ) {

    loader.load( "Models/test1.js", function ( geometry, materials ) { createPart( geometry, materials, test1 ) } );
    loader.load( "Models/test2.js", function ( geometry, materials ) { createPart( geometry, materials, test2 ) } );
    loader.load( "Models/test3.js", function ( geometry, materials ) { createPart( geometry, materials, test3 ) } );
    loader.load( "Models/test4.js", function ( geometry, materials ) { createPart( geometry, materials, test4 ) } );
    loader.load( "Models/test5.js", function ( geometry, materials ) { createPart( geometry, materials, test5 ) } );
    loader.load( "Models/test6.js", function ( geometry, materials ) { createPart( geometry, materials, test6 ) } );
    loader.load( "Models/test7.js", function ( geometry, materials ) { createPart( geometry, materials, test7 ) } );
}

function createPart( geometry, materials, object3Dtemp) {
    Part = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
    Part.scale.set( 1000, 1000, 1000 );
    console.log("ModelPart created:" + Part.id);
    object3Dtemp.add( Part );
}

function placePart( object3Dtemp, x, y, z) {
    Part = object3Dtemp.clone();
    Part.position.set( x, y, z );

    console.log("Part.id:" + Part.id);
    scene.add( Part );
}

in console:

newpart.id:12 
test1.children.length:0
Part placed: 0 100 0 13 
Part placed: 0 200 0 14 
Part placed: 0 300 0 15 
Part placed: 0 400 0 16 
Part placed: 0 500 0 17 
Part placed: 0 600 0 18 
Part placed: 0 700 0 19
THREE.WebGLRenderer 63 
ModelPart created:21 
ModelPart created:22 
ModelPart created:23 
ModelPart created:24 
ModelPart created:25 
ModelPart created:26 
ModelPart created:27 
有帮助吗?

解决方案

JSONLoader.load() works asynchronously. So when you run it, execution will move on to the next line in your code without waiting for the loader to finish.

If you look at this line here:

 loader.load( "Models/test1.js", function ( geometry, materials ) { createPart( geometry, materials, cover ) } );

the "function(geometry,materials){...}" is the callback which runs when .load is finished, in this case you are using a user-defined function "createPart" within this. What you need to do to make each model load one after the other is call their loader at the end of the previous one's "createPart". Then once the last model's "createPart" finishes executing you can call init().

If all of your models are numbered sequentially you may be able to manage this in a psuedo-for loop chain of callbacks, otherwise it could be a manual job.

var partNo = 0;
var partCount = 5;
loadUp(partNo);

function loadUp(_partNo){
    var loader = new THREE.JSONLoader();
    loader.load("Models/part"+_partNo+".js", function(geo, mat) {
        createPart(geo, mat, ..., _partNo);
    }
}

function createPart(geo, mat, ...,  _partNo) {
    //create mesh etc as before
    ...

    if(_partNo + 1 < partCount){ //first 4 parts
        _partNo++;
        loadUp(_partNo); //load next part
    }
    else { //this is the 5th part so we are finished
        init();
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top