2016-05-11 13 views
0

私はTHREE.LoadingManagerといくつかのテクスチャでロードしているobjモデルを持っています。キャッシュをクリアしてページを開くときに、私は常にテクスチャのないモデルを取得しています。私はF5を押した後にそれらを見ることができます。私のコードは次のようになります。three.jsローディングリソース

var manager = new THREE.LoadingManager();  
var loader = new THREE.TextureLoader(manager); 
var textures_loaded = 0; 

var id; 
for (id in materials) { 
    loader.load('images/' + materials[id].unique_id + '.jpg', function(t) { 
     t.magFilter = THREE.NearestFilter; 
     t.minFilter = THREE.LinearMipMapLinearFilter; 

     var re = /images\/(\d+)\.jpg/g; 
     var result = re.exec(t.image.currentSrc); 

     material = materials.filter(function(obj) { 
      return obj.unique_id == result[1]; 
     }).shift(); 

     material.setTexture(t); 
     textures_loaded += 1; 

     if (textures_loaded == materials.length) { 
      mainLoop(); 
     } 
    }); 
} 

var loader = new THREE.OBJLoader(manager); 
loader.load('obj/' + model.model_name, function (object) { 
     object.traverse(function(child) { 
      if (child instanceof THREE.Mesh) { 
       var mesh = model.meshes.filter(function(mesh) { 
        return mesh.name == child.name; 
       }).shift(); 

       child.material.map = mesh.material.texture; 
       child.geometry.buffersNeedUpdate; 
       child.geometry.uvsNeedUpdate; 
      } 
     }); 

     scene.add(object); 
    } 
); 

私はすべてのテクスチャがロードされた後にのみ、メインループを実行していますよ。しかし時には負荷をモデル化することもあります。 THREE.LoadingManager?を使用してオブジェクトをロードする順序を制御する方法はありますか。すべてがロードされた後でのみ、どのようにモデルを表示できますか?

答えて

1

から

。コンテンツの各セットをインラインでロードする2つの関数を用意してください。この場合、材料のロードが完了するまで、メッシュはロードされません。

var manager = new THREE.LoadingManager(); 

var loader = new THREE.TextureLoader(manager); 



function loadMaterials(materials, callback){ 
    var textures_loaded = 0; 
    for (var id in materials) { 
     loader.load('images/' + materials[id].unique_id + '.jpg', function(t) { 
      t.magFilter = THREE.NearestFilter; 
      t.minFilter = THREE.LinearMipMapLinearFilter; 

      var re = /images\/(\d+)\.jpg/g; 
      var result = re.exec(t.image.currentSrc); 

      material = materials.filter(function(obj) { 
       return obj.unique_id == result[1]; 
      }).shift(); 

      material.setTexture(t); 
      textures_loaded += 1; 

      if (textures_loaded == materials.length) { 
       callback("materialsLoaded"); 
       //mainLoop(); 
      } 
     }); 
    } 
} 


var loadedMeshes = []; 

function loadMeshes(meshes, callback){ 
    var meshes_loaded = 0; 
    for(var i in meshes){ 
    var loader = new THREE.OBJLoader(manager); 
    loader.load('obj/' + model.model_name, function (object) { 
     loadedMeshes.push(object); 
     object.traverse(function(child) { 
      if (child instanceof THREE.Mesh) { 
       //you'll need to map to the right material. 
       child.material.map = mesh.material.texture; 
       child.geometry.buffersNeedUpdate; 
       child.geometry.uvsNeedUpdate; 
      } 
     }); 
     if(loadedMeshes.length == meshes.length){ 
     callback("meshesLoaded"); 
     } 
    }; 
    } 
} 


var materials = ["material1", "material2"]; 
var meshes = ["mesh1.obj", "mesh2.obj"]; 

function onLoad(){ 
    for(var i in loadedMeshes){ 
     scene.add(loadedMeshes[i]); 
    } 
    mainLoop(); 
} 

function init(){ 
    loadMaterials(materials, function(t){ 
    console.log(t); 
    loadMeshes(meshes, function(t){ 
     console.log(t); 
     onLoad(t); 
    }) 
    }) 
} 
+1

あなたのソリューションは完璧に働いた、ありがとうございました! – twoface88

+1

また、実際にロードマネージャをもっと離散的に使用することもできますが、単純な配列チェックが機能するときに、ジオメトリをメッシュとしてインスタンス化する前に、依存関係が満たされたときに別のマネージャを書き込む必要があります。 – Radio

0

たぶん、あなたはいくつかのjQueryを使用して、ドキュメントの準備ができた場合にのみ、あなたのメインループを実行しようとすることができます:

$('document').ready(function mainLoop(){}); 

「画像などすべての資産が完全に受信されるまで、このイベントがトリガされません」私はこのような何かをするだろうjQuery .ready event

+1

まだ定義されていないマテリアルオブジェクトが作成されています。 – Radio