2015-10-15 9 views
6

ColladaLoaderで.daeシーンを正常にインポートしました。Three.js Collada - メモリを処分(ガベージコレクション)するにはどうすればよいですか?

問題は、いくつかの.daeファイルを切り替える必要があることです。

私はdisposeメソッドを適切に実装できないようです。

 dae.traverse(function(obj) { 

      console.log('unloading ' + obj.id); 

      scene.remove(obj); 

      if(obj.geometry) 
       obj.geometry.dispose(); 
      if(obj.material) 
       obj.material.dispose(); 
      if(obj.mesh) 
       obj.mesh.dispose(); 
      if(obj.texture) 
       obj.texture.dispose(); 

     }); 

     scene.remove(dae); 

私は間違っている可能性がありますか?

ありがとうございます!


EDIT:

は、ここで全体のコードです。これは、仕事をする必要があります

var renderer = null; 
    var scene = null; 
    var camera = null; 
    var controls = null; 
    var dae = null; 
    //var loader = null; 

    function init() { 


     renderer = new THREE.WebGLRenderer({ alpha: 1, antialias: true, clearColor: 0xffffff }); 
     renderer.setSize(800, 600); 

     var elem = $('.main3d')[0]; 
     elem.appendChild(renderer.domElement); 

     scene = new THREE.Scene(); 

     camera = new THREE.PerspectiveCamera(20, 800/600, 1, 1000); 
     camera.position.set(0, -100, 50); 
     //camera.lookAt(scene.position); 
     controls = new THREE.TrackballControls(camera, renderer.domElement); 

     var light = new THREE.AmbientLight(0xffffff); // soft white light 
     scene.add(light); 

     threeAnimate(); 


    } 

    function load(url) { 
     loader = new THREE.ColladaLoader(); 

      loader.load(url, function (collada) { 
       dae = collada.scene; 
       scene.add(dae); 

      }); 

    } 

    function unload() { 

     dae.traverse(function(obj) { 

      console.log('unloading ' + obj.id); 

      scene.remove(obj); 

      if(obj.geometry) 
       obj.geometry.dispose(); 
      if(obj.material) 
       obj.material.dispose(); 
      if(obj.mesh) 
       obj.mesh.dispose(); 
      if(obj.texture) 
       obj.texture.dispose(); 

     }); 

     scene.remove(dae); 

    } 

    var animFrame = null; 
    function animate() { 

     animFrame = requestAnimationFrame(threeAnimate); 
     renderer.render(scene, camera); 
     controls.update(); 

    } 

答えて

17

function disposeNode (node) 
{ 
    if (node instanceof THREE.Mesh) 
    { 
     if (node.geometry) 
     { 
      node.geometry.dispose(); 
     } 

     if (node.material) 
     { 
      if (node.material instanceof THREE.MeshFaceMaterial) 
      { 
       $.each (node.material.materials, function (idx, mtrl) 
       { 
        if (mtrl.map)   mtrl.map.dispose(); 
        if (mtrl.lightMap)  mtrl.lightMap.dispose(); 
        if (mtrl.bumpMap)  mtrl.bumpMap.dispose(); 
        if (mtrl.normalMap)  mtrl.normalMap.dispose(); 
        if (mtrl.specularMap) mtrl.specularMap.dispose(); 
        if (mtrl.envMap)  mtrl.envMap.dispose(); 

        mtrl.dispose(); // disposes any programs associated with the material 
       }); 
      } 
      else 
      { 
       if (node.material.map)   node.material.map.dispose(); 
       if (node.material.lightMap)  node.material.lightMap.dispose(); 
       if (node.material.bumpMap)  node.material.bumpMap.dispose(); 
       if (node.material.normalMap) node.material.normalMap.dispose(); 
       if (node.material.specularMap) node.material.specularMap.dispose(); 
       if (node.material.envMap)  node.material.envMap.dispose(); 

       node.material.dispose(); // disposes any programs associated with the material 
      } 
     } 
    } 
} // disposeNode 

function disposeHierarchy (node, callback) 
{ 
    for (var i = node.children.length - 1; i >= 0; i--) 
    { 
     var child = node.children[i]; 
     disposeHierarchy (child, callback); 
     callback (child); 
    } 
} 

、あなたが

disposeHierarchy (YOUR_OBJECT3D, disposeNode); 
+0

ワウ!それはかなり包括的です!私はちょっとそれをチェックします。答える時間をとってくれてありがとう! –

+0

私は答えが自分の研究に基づいているのか、それとも何らかの情報源があるのか​​どうかを知りたい。再度、感謝します! –

+0

驚くばかりの答え!私はdisposeHierarchy()関数を使って700MB +をリリースすることができました!ちょうど素晴らしい人。どうもありがとう。この回答が他の人にも役立つことを願っています –

6

それを使用する私はすでにgaitatさんだけ削除するには、今のシーントラバース機能で構築を使用するために素晴らしい答えを微調整$とMultiMaterialも処理します。なぜ、オハイオ州になぜメモリクリーンアップが組み込まれていないのですか?もちろん、scene.dispose()を実行するときにそれを行う必要があります。私はrenderer.info.memory.textures

ここでの回答をオフに構築
this.disposeNode = function (parentObject) { 

    parentObject.traverse(function (node) { 
     if (node instanceof THREE.Mesh) { 
      if (node.geometry) { 
       node.geometry.dispose(); 
      } 

      if (node.material) { 

       if (node.material instanceof THREE.MeshFaceMaterial || node.material instanceof THREE.MultiMaterial) { 
        node.material.materials.forEach(function (mtrl, idx) { 
         if (mtrl.map) mtrl.map.dispose(); 
         if (mtrl.lightMap) mtrl.lightMap.dispose(); 
         if (mtrl.bumpMap) mtrl.bumpMap.dispose(); 
         if (mtrl.normalMap) mtrl.normalMap.dispose(); 
         if (mtrl.specularMap) mtrl.specularMap.dispose(); 
         if (mtrl.envMap) mtrl.envMap.dispose(); 

         mtrl.dispose(); // disposes any programs associated with the material 
        }); 
       } 
       else { 
        if (node.material.map) node.material.map.dispose(); 
        if (node.material.lightMap) node.material.lightMap.dispose(); 
        if (node.material.bumpMap) node.material.bumpMap.dispose(); 
        if (node.material.normalMap) node.material.normalMap.dispose(); 
        if (node.material.specularMap) node.material.specularMap.dispose(); 
        if (node.material.envMap) node.material.envMap.dispose(); 

        node.material.dispose(); // disposes any programs associated with the material 
       } 
      } 
     } 
    }); 
} 
+1

これが_automagically_削除されていない理由です。 [ヒープオブジェクトのデロイ...](https://github.com/mrdoob/three.js/issues/5175)。プログラマー**はあなたが思っているほど簡単ではないので**関与しています。大規模なプロジェクトでは事が複雑になり、マテリアル、ジオメトリ、シーン間のメッシュまで再利用することになります(冗談ではなく、上記のすべてを行うことになります)。とても楽しいものを削除するだけで、痛みや悲しみをもたらすことになります。学習曲線を持ち、プログラマーとして関与しなければならないことは、あなたが愚かな間違いをしないようにします。 – tfrascaroli

1

によると、このコードは、材料の配列を扱う編)(まだ私が使用しているカップルより多くのテクスチャを追跡しようとしているが、処分を取得していないようです。

function disposeNode(parentObject) { 
    parentObject.traverse(function (node) { 
     if (node instanceof THREE.Mesh) { 
      if (node.geometry) { 
       node.geometry.dispose(); 
      } 
      if (node.material) { 
       var materialArray; 
       if (node.material instanceof THREE.MeshFaceMaterial || node.material instanceof THREE.MultiMaterial) { 
        materialArray = node.material.materials; 
       } 
       else if(node.material instanceof Array) { 
        materialArray = node.material; 
       } 
       if(materialArray) { 
        materialArray.forEach(function (mtrl, idx) { 
         if (mtrl.map) mtrl.map.dispose(); 
         if (mtrl.lightMap) mtrl.lightMap.dispose(); 
         if (mtrl.bumpMap) mtrl.bumpMap.dispose(); 
         if (mtrl.normalMap) mtrl.normalMap.dispose(); 
         if (mtrl.specularMap) mtrl.specularMap.dispose(); 
         if (mtrl.envMap) mtrl.envMap.dispose(); 
         mtrl.dispose(); 
        }); 
       } 
       else { 
        if (node.material.map) node.material.map.dispose(); 
        if (node.material.lightMap) node.material.lightMap.dispose(); 
        if (node.material.bumpMap) node.material.bumpMap.dispose(); 
        if (node.material.normalMap) node.material.normalMap.dispose(); 
        if (node.material.specularMap) node.material.specularMap.dispose(); 
        if (node.material.envMap) node.material.envMap.dispose(); 
        node.material.dispose(); 
       } 
      } 
     } 
    }); 
} 
関連する問題