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

use*_*057 4 javascript json callback loader three.js

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

我尝试了一些方法,但似乎加载模型是异步发生的.

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

例:

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 );
}
Run Code Online (Sandbox Code Playgroud)

在控制台中:

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 
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 5

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

如果你看这一行:

 loader.load( "Models/test1.js", function ( geometry, materials ) { createPart( geometry, materials, cover ) } );
Run Code Online (Sandbox Code Playgroud)

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

如果所有模型都按顺序编号,您可以在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();
    }
}
Run Code Online (Sandbox Code Playgroud)