2013-12-20 1 views
4

꽤 많은 JSON 모델을로드하고 전역 변수에 넣으므로 복사, 변환 등을 할 수 있습니다. 그런 식으로 필요할 때마다 모델을로드 할 필요가 없습니다.three.js에서 JSON 모델을 먼저로드하고 init 전에 변수를 할당하는 방법은 무엇입니까?

몇 가지 방법을 시도했지만 모델로드가 비동기 적으로 발생합니다.

다른 모든 작업이 이미 완료된 후에 모델이로드 된 것 같습니다. 그래서 나는 이미 변수를 선언했지만 비어 있거나 작동하지 않습니다. 모델을 먼저로드하고 완료 될 때까지 기다린 다음 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); 
} 

:

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 

답변

5

JSONLoader.load()는 비동기 적으로 작동합니다. 따라서 실행하면 로더가 끝나기를 기다리지 않고 실행이 코드의 다음 줄로 넘어갑니다.

여기이 선을 보면 :

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

은 "기능 (기하학, 자료) {...}".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(); 
    } 
} 
+0

고맙습니다. – user2099057

관련 문제