首页 > 解决方案 > 我尝试数组 OBJECT3D

问题描述

我只是 Three.js 的初学者。我想将我的“模型”对象推送到数组中。我想我的代码应该没问题。
我有我的 var nextobj = [];。

function Loadobj() {
    var mx = [-1500,1500] , my = [350,350] , mz = [-1000,-1000];
    var nextobj = []; //Keep Array Model

    for(var i = 0; i < 2; i++) { 
        var mtloader = new THREE.MTLLoader(); 
        mtloader.load('obj1/az-mp0076.mtl', function (materials) {
        materials.preload(); 
        var objloader = new THREE.OBJLoader();
        objloader.setMaterials( materials );
        objloader.load('obj1/az-mp0076.obj', function (object){ 
            model = object;
            model.position.set(mx[i],my[i],mz[i]);
            scen.add(model); 
            nextobj.push(model); 
            console.log(nextobj.length);  //This here my check data Object
            });
        });
    }
}

第 1 步:
我循环 < 1 显示的对象

https://i.stack.imgur.com/3ktGD.jpg

第 2 步
我循环 > 1 个对象未显示但我的数据显示完成

https://i.stack.imgur.com/IIZVv.png

如何推送我的对象数组?非常感谢。
我不确定我的代码有什么问题。

标签: javascriptarraysthree.js

解决方案


尝试Loadobj递归运行或使其成为一个承诺。在 for 循环内部,您有两个回调(用于加载材料和对象)。问题是循环执行无需等待(回调的)每个项目被加载,它同步运行。但是所有与材质/对象加载相关的方法都是异步的(它们具有回调并且仅在回调函数内部加载结果)。要完全加载对象,您需要确保仅在加载(回调的)项之后才操作加载方法的结果,并且Loadobj仅在之前的执行Loadobj完成后再次调用。
使用递归函数:

var mx = [-1500,1500] , my = [350,350] , mz = [-1000,-1000];
var nextobj = []; //Keep Array Model
var numOfObjs = 1;
var start = 0;
function Loadobj() {
  if (Loadobj == numOfObjs) return;
  start++;
  var mtloader = new THREE.MTLLoader(); 
  mtloader.load('obj1/az-mp0076.mtl', function (materials) {
    materials.preload(); 
    var objloader = new THREE.OBJLoader();
    objloader.setMaterials( materials );
    objloader.load('obj1/az-mp0076.obj', function (object) { 
      model = object;
      model.position.set(mx[start],my[start],mz[start]);
      scen.add(model); 
      nextobj.push(model);
      console.log(nextobj.length);
      Loadobj();
    });
  });
}

另一种方法是使用 Promise:

function Loadobj(obj) {
  return loadMaterials()
    .then(function(materials) {
      return loadObjs(materials, obj);
    })
    .catch(function(err) {
      console.log(err);
   });
}

function loadMaterials() {
  return new Promise(function(resolve, reject) {
    var mtloader = new THREE.MTLLoader(); 
    mtloader.load('obj1/az-mp0076.mtl', function (materials) {
      materials.preload(); 
      resolve(materials);
    });
  });  
}

function loadObjs(materials, obj) {
  return new Promise(function (resolve, reject) {
    var objloader = new THREE.OBJLoader();
    objloader.setMaterials( materials );
    objloader.load('obj1/az-mp0076.obj', function (object){ 
      var model = object;
      model.position.set(obj.mx, obj.my,obj.mz);
      // scene is available globally
      scene.add(model); 
      nextobj.push(model);
      resolve(model);
    });
  });
}

var objs = [
  {
    mx : -1500, 
    my: 350, 
    mz: -1000
  },
  {
    mx: 1500, 
    my: 350, 
    mz: -1000
  }
];

var nextobj = []; 

// use reduce to iterate over objs
objs.reduce(function(acc, obj) {
  return Loadobj(obj);
}, Promise.resolve());

推荐阅读