2017-01-27 55 views
5

ファイルを参照するファイルを読み込み、テクスチャイメージ*.pngall resources)を使用したいとします。 1つではなく複数のmtlをロードする理由は、同じジオメトリで異なる材料を動的にロードできることです。Three.jsに複数の '.mtl'ファイルを含む '.obj'をロードする方法

私は、このような例を見つけることができませんでしたが、私はMultiMaterialを作成し、すべてのMTLのをロードすることによってMultiMaterialドキュメントとwebgl_loader_obj_mtlに例をミックスしようとした、およびロードOBJ:

var resources = 'cube/'; 
var materialsToLoad = [ 
    'cube_red.mtl', 
    'cube_green.mtl', 
    'cube_blue.mtl' 
]; 

var loadedMaterials = []; 

var mtlLoader = new THREE.MTLLoader(); 
mtlLoader.setPath(resources); 
for (var i = 0; i < materialsToLoad.length; i++) { 
    mtlLoader.load(materialsToLoad[i], function(materials) { 
     materials.preload(); 
     loadedMaterials.push(materials); 
    }); 
} 

var multi = new THREE.MultiMaterial(loadedMaterials); 
var objLoader = new THREE.OBJLoader(); 
objLoader.setPath(resources); 
objLoader.setMaterials(multi); // #1 
objLoader.load('cube.obj', function (object) { 
    scene.add(object); 
}); 

しかし、これは動作しません、例外はあります投げられた:

Uncaught TypeError: this.materials.create is not a function 
at THREE.OBJLoader.parse (OBJLoader.js:684) 
at OBJLoader.js:50 
at XMLHttpRequest.<anonymous> (three.min.js:619) 

私は間違っていますか、正しく行う方法は?

答えて

0

私はここにいくつかの問題があると思います。

1)THREE.MTLLoader .loadは、「非ブロック」機能として動作します。

したがって、MTLのファイルがまだ完全にロードされていない場合は、OBJファイルをロードしています。引数として渡されたコールバック関数内のOBJファイルをmtlLoader.load()にロードする必要があります。あなたが言及したexampleを見てください。引数として渡さmtlLoader.loadコールバック関数について

2):

その引数、材料は、タイプTHREE.MTLLoader.MaterialCreatorです。したがってloadedMaterialsTHREE.MTLLoader.MaterialCreatorの要素の配列で、THREE.MultiMaterialの要素を作成する場合はTHREE.Materialの要素の配列が必要です。

さらに、MultiMaterialは、1つのオブジェクト(オブジェクトの1つの面に1つのマテリアル)に多くのマテリアルを割り当て、オブジェクトのマテリアルを「オプションで」選択するために使用されます(MultiMaterial Cube example)。


これを行うための一つのアプローチ(コードませテスト):

まず、我々はLoadingManagerが必要になります:

var manager = new THREE.LoadingManager(); 

これは、すべてのMTLさんがロードされたアサートのためでありますOBJをロードする前に:

manager.onLoad = function() { 
    /* 
     At this point, all MTL's have been loaded. 
     We will load an OBJ with the first material option 
     (for example), if it exists. 
    */ 

    if (loadedMaterials.length > 0) { 
     var objLoader = new THREE.OBJLoader(); 
     objLoader.setPath(resources); 
     objLoader.setMaterials(loadedMaterials[0]); // First material 
     objLoader.load('cube.obj', function (object) { 
     scene.add(object); 
    } 
}; 

そして、私たちはすべてのMTLを読み込みます:

var mtlLoader = new THREE.MTLLoader(manager); 
mtlLoader.setPath(resources); 
for (var i = 0; i < materialsToLoad.length; i++) { 
    mtlLoader.load(materialsToLoad[i], function(materials) { 
     materials.preload(); 
     loadedMaterials.push(materials); 
    }); 
} 

希望します!

関連する問題