2016-01-12 40 views
0

任何人都可以請建議加載多個模型(從攪拌機導出爲JSON格式)的最佳方式是什麼?使用JSONLoader加載多個模型

在我下面的例子中,我使用了填充了一些預定義對象數據的static_objects數組,這也是存儲有關模型URL的所有信息的地方。 然後將這些URL傳遞給for循環中的JSONLoader。但由於某種原因,當我訪問JSONLoader.load方法中的static_objects數組時,我得到不正確的引用。

請看下面的例子。

var renderer, camera, scene, controls; 

/////// JSOn DATA //// 
var static_objects = [ 
     { 
     name:"ground", 
     pos:{ 
      x:-45.0, y:-1, z:14.0 
     }, 
     size:20, 
     model_url: "obj.moon_ground.json", 
     }, 
     { 
     name:"cylinder", 
     pos:{ 
      x:-20.0, y:0.0, z:0.0 
     }, 
     size:10, 
     model_url:"obj.cylinder.json", 
     } 
]; 

var ObjectsToLoad = static_objects.length || 0; 
/////////////////////////// 


function initRenderer(width, height){ 
    console.log(" - renderer"); 
    if(Detector.webgl){ 
     renderer = new THREE.WebGLRenderer({antialias:true}); 
    }else{ 
     renderer = THREE.CanvasRenderer(); 
    } 
    //// container //// 
    container = document.createElement('div'); 
    document.body.appendChild(container); 
    ///////////////////// 

    renderer.setPixelRatio(window.devicePixelRatio); 
    renderer.setSize(width, height); 
    renderer.shadowMap.enabled = true; 
    renderer.shadowMapSoft = true; 
    renderer.setClearColor(0x142639, 1); 
    /////////////////////// 
    container.appendChild(renderer.domElement); 
} 

function initCamera(width, height){ 
    console.log(" - camera"); 
    camera = new THREE.PerspectiveCamera(55, width/height, 1, 100); 
    camera.position.set(17.05217, 8.07079, 0.0); 
    camera.lookAt(static_objects[1].pos); 
    controls = new THREE.OrbitControls(camera); 
} 

function InitLights(){ 
    console.log(" - lights"); 
    var spot_light = new THREE.SpotLight(0xC1C1C1, 0.4); 
    spot_light.castShadow = true; 
    spot_light.shadowDarkness = 0.1; 
    spot_light.shadowCameraNear = 0.1; 
    spot_light.shadowCameraFar = 100; 
    spot_light.shadowCameraFov = 45; 
    spot_light.shadowMapWidth = 512; 
    spot_light.shadowMapHeight = 512; 
    spot_light.position.set(-1.8, 100, 2.5); 
    spot_light.target.position.set( static_objects[1].pos.x, static_objects[1].pos.y, static_objects[1].pos.z); 
    scene.add(spot_light); 
    var c_helper = new THREE.CameraHelper(spot_light.shadow.camera); 
    scene.add(c_helper); 
    var ambient_light = new THREE.AmbientLight(0xD0D0D0, 0.25); 
    scene.add(ambient_light); 
} 

function initScene(){ 
    console.log(" - scene"); 
    scene = new THREE.Scene(); 
} 


function initObjects(){ 
    console.log(" - StaticObjects"); 
    for(var o = 0; o < static_objects.length; o++){ 
     var loader = new THREE.JSONLoader(); 
     var o_data = static_objects[o]; 
     loader.load(o_data.model_url, function(){ 
      console.log("loading object "+ o_data.name) <----- it always refers to same object /// 
      ObjectsToLoad--; 
      //object.scale.set(self.properties.size, self.properties.size, self.properties.size) ; 
     }) 
    } 
} 

function initAll(){ 
    console.log(" initializing:"); 
    initRenderer(window.innerWidth/2, window.innerHeight/2); 
    initScene(); 
    initCamera(window.innerWidth/2, window.innerHeight/2); 
    InitLights(); 
    initObjects(); 
    animate(); 
} 

function animate(){ 
    window.requestAnimationFrame(animate); 
    if(ObjectsToLoad === 0){ 
     render_all(); 
    } 
} 

function render_all(){ 
     //var timer = Date.now() * 0.001; 
     controls.update(); 
     renderer.render(scene, camera); 
} 

initAll(); 

回答

0

我已經通過傳遞一個現有的函數來加載方法(而不是創建一個新的方法)來解決這個問題。

function loadObjects(){ 
    console.log(" - StaticObjects"); 
    var loader = new THREE.JSONLoader(); 
    for(var o = 0; o < static_objects.length; o++){ 
     var o_data = static_objects[o]; 
     loader.load(o_data.model_url, initObject(o)); 
    } 
} 

function initObject(o_id){ 
    console.log("loading object "+ o_id); 
    return function(geometry, materials) { 
     geometry.translate(0.0, 0.0, -2.0); 
     mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials)); 
     mesh.scale.set(static_objects[o_id].size, static_objects[o_id].size, static_objects[o_id].size) ; 
     mesh.position.set( static_objects[o_id].pos.x, static_objects[o_id].pos.y, static_objects[o_id].pos.z); 
     mesh.traverse(function(node) { if (node instanceof THREE.Mesh) { node.castShadow = true; node.receiveShadow = true; } }); 
     ObjectsToLoad--; 
     scene.add(mesh); 
    } 
} 
1

剝離,以說明問題不相關的代碼,這裏是你的原始功能:

function initObjects(){ 
    for(var o = 0; o < static_objects.length; o++){ 
     var loader = new THREE.JSONLoader(); 
     var o_data = static_objects[o]; 
     loader.load(o_data.model_url, function(){ 
      console.log("loading object "+ o_data.name) <----- it always refers to same object /// 
     }) 
    } 
} 

這並不完全在JavaScript中,你會從其他語言期望的那樣var什麼做的不是詞彙作用域。 var的作用範圍是它在其中定義的功能,並影響其在線初始化,該初始化僅發生一次。

您有效地寫道:

function initObjects(){ 
    var loader = new THREE.JSONLoader(); 
    var o_data = undefined; 

    for(var o = 0; o < static_objects.length; o++){ 

     if (o_data === undefined) { 
      o_data = static_objects[o]; 
     } 

     loader.load(o_data.model_url, function(){ 
      console.log("loading object "+ o_data.name) <----- it always refers to same object /// 
     }) 
    } 
} 

ES6解決了這個與letconst關鍵字,但你需要transpile你的代碼在構建過程中,使這項工作在所有瀏覽器。這雖然是一個完全不同的主題,所以雖然你仍然使用常規的var你應該總是聲明你的函數的開始變量,使它更清楚發生了什麼。

+0

感謝您的解釋。 – Alexus

相關問題