如何在three.js中首先加载JSON模型并在init之前分配变量?

时间:2021-12-28 19:37:30

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.

我想加载相当多的JSON模型并将它们放在全局变量中,这样我就可以使用它们进行复制,翻译等。这样我每次需要时都不需要加载模型。

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?

在完成其他所有操作后,模型似乎已加载。所以我已经声明了我的变量,但它们保持空白或不起作用。如何首先加载模型,等到完成后再启动init()和其余代码?

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 

1 个解决方案

#1


5  

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.

JSONLoader.load()异步工作。因此,当您运行它时,执行将继续执行代码中的下一行,而无需等待加载程序完成。

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().

“function(geometry,materials){...}”是在.load完成时运行的回调,在这种情况下,您在此使用用户定义的函数“createPart”。你需要做的是让每个模型一个接一个地加载,在前一个“createPart”结束时调用它们的加载器。然后,一旦最后一个模型的“createPart”完成执行,你就可以调用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.

如果所有模型都按顺序编号,您可以在psuedo-for循环回调链中进行管理,否则它可能是一个手动作业。

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();
    }
}

#1


5  

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.

JSONLoader.load()异步工作。因此,当您运行它时,执行将继续执行代码中的下一行,而无需等待加载程序完成。

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().

“function(geometry,materials){...}”是在.load完成时运行的回调,在这种情况下,您在此使用用户定义的函数“createPart”。你需要做的是让每个模型一个接一个地加载,在前一个“createPart”结束时调用它们的加载器。然后,一旦最后一个模型的“createPart”完成执行,你就可以调用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.

如果所有模型都按顺序编号,您可以在psuedo-for循环回调链中进行管理,否则它可能是一个手动作业。

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();
    }
}