【问题标题】:Loading multiple models using JSONLoader使用 JSONLoader 加载多个模型
【发布时间】:2016-11-10 04:15:18
【问题描述】:

谁能告诉我加载多个模型(从搅拌机导出为 JSON 格式)的最佳方式是什么?

在下面的示例中,我使用了填充了一些预定义对象数据的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();

【问题讨论】:

    标签: javascript three.js


    【解决方案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 关键字解决了这个问题,但您确实需要在构建过程中转译您的代码以使其在所有浏览器中都能正常工作。虽然这是一个完全不同的话题,所以当您仍在使用常规 var 时,您应该始终在函数的 start 处声明变量以使其更多更清楚发生了什么。

    【讨论】:

      【解决方案2】:

      我通过将现有函数传递给加载方法(而不是创建新函数)解决了这个问题。

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

      【讨论】:

        猜你喜欢
        • 2013-12-07
        • 1970-01-01
        • 2013-07-25
        • 1970-01-01
        • 2014-11-17
        • 2012-12-23
        • 1970-01-01
        • 2020-01-23
        • 2018-05-03
        相关资源
        最近更新 更多