在使用Three.js中 使用for循環加載obj模型
出現的bug
BUG
直接上代碼:
var objArray = ["1","2","3","4"];
for(var i = 0; i < objArray.length; i++) {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath("obj/");
mtlLoader.load("" + objArray[i] + ".mtl", function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath("obj/");
objLoader.load("" + objArray[i] + ".obj", function(object) {
scene.add(object);
}, onProgress, onError);
});
}
最新版本的three.js
中加載obj模型可以分為兩步,第一步先加載mtl文件,提取mtl文件作為對象的材質。第二部加載obj文件,提取obj文件作為
對象的三維網格,然后創建對象。
當我們使用以上方式循環加載一組模型的時候。它會報錯。
obj/undefined.obj NOT_FOUND X4
but i dont't know what happend!
然后在加載obj文件的時候打印出i會發現此事的 i=5
數組越界了所以找不到文件。但是為什么mtl都被加載了呢?
then 我稍微學習了一下發現,由於文件的加載時異步的
第一次加載的時候i=0
, mtl加載的時候是正常的,但是加載obj的時候由於是單線程的obj的加載被阻塞了,所以它只好等mtl加載完成將一個函數objLoader.load(i)
放到線程池中。
但是由於是異步的,所以在加載第一個mtl加載完成時候循環早已結束。
所以mtlLoader.load(i)
(此處i=0
)結束的時候,要執行objLoader.load(i)
的時候i
早已為5
,所以會出現NOT_FOUND
。
解決方案
解決方案1
我發現只要在循環中加入這么一句:
for(var i = 0; i < objArray.length; i++) {
var arr = array[i];
這句話在使用ajax的時候很常見,我一直天真的以為它僅僅是用來簡化代碼的。
解決方案2
可以將需要循環的封裝成一個函數,然后外部循環調用。
for(var i = 0; i < objArray.length; i++) {
loadObj(objArray[i]);
}
function loadObj(objName){
//todo
}