2015-06-01 4 views
0

Итак, у меня есть сценарий THREE.js, в которой я должен отменить загрузку файла в сцену. На моей странице я могу загрузить несколько возможных файлов, но я пытаюсь настроить его так, чтобы вы могли загружать только по одному для просмотра в сцене. Я использую углы для реализации моей трехмерной сцены и холста как основной фабрики, так как мне нужен только один экземпляр холста за раз. Вот основной код этой фабрики (для этого конкретного вопроса) я использую Angular между прочим, что является причиной app.factory в начале и инъекции PartLibrary, но это не актуально. Все, что вам нужно знать, что PartLibrary.load_part_stl() это просто функция, которая делает Ajax вызов, чтобы получить URL для СТЛ файл, который будет загружен ::Отмена загрузки объекта в сцену в THREE.js

app.factory('ModelViewer', ['PartLibrary', function(QuoteLibrary){ 
    var modelViewer = { 
     model_material: {}, 
     part_model: {}, 
     part: {}, 
     scene: {}, 
     camera: {}, 
     renderer: {}, 
     loader: {}, 
     manager: {}, 
     id: {} 
    }; 

    modelViewer.destroy_old = function(canvas_selector){ 
     cancelAnimationFrame(this.id); 
     this.scene = null; 
     this.renderer = null; 
     this.camera = null; 
     this.part_edges = null; 
     this.part_model = null; 
     this.loader = null; 
     this.manager = null; 
     $('canvas').remove(); 
    } 

    modelViewer.init = function(part, canvas_selector){ 
     var self = this; 


     // distroy any old three js canvases 
     self.destroy_old(canvas_selector); 

     self.part = part; 
     self.initiated = true; 
     var container = $(canvas_selector)[0]; 
     self.scene = new THREE.Scene(); 
     self.camera = new THREE.PerspectiveCamera(45, $(canvas_selector).width()/$(canvas_selector).height(), 1, 20000); 
     self.scene.add(new THREE.AmbientLight(0x4F4F4F)); 


     self.renderer = new THREE.WebGLRenderer({ antialias: true }); 
     container.appendChild(self.renderer.domElement); 

     PartLibrary.load_part_stl(part.id) 
      .success(function(url){ 
       loadModel(url, self); 
      }) 
      .error(function(){ 
       console.log("Error loading STL file for 3D view"); 
      }); 

     function loadModel(url){ 

      self.manager = new THREE.LoadingManager(); 
      self.loader = new THREE.STLLoader(self.manager); 

      self.manager.onLoad = function(item, loaded, total){ 
       $('.model-loading').hide(); 
      } 

      self.loader.load(url, function(geometry){ 
       self.model_material = new THREE.MeshPhongMaterial(); 
       self.part_model = new THREE.Mesh(geometry, self.model_material); 

       self.scene.add(self.part_model); 
      }); 
     } 

     function animate() { 
      self.id = requestAnimationFrame(animate); 
      render(); 
     } 

     function render() { 
      // var timer = Date.now() * 0.0005; 
      self.renderer.render(self.scene, self.camera); 

     } 
     animate(); 
    } 

    return modelViewer; 
}]); 

Так в основном, как это работает, что есть несколько возможных холстов (в зависимости от canvas_selector), но только один активный холст, так как старый файл canvas/scene/renderer/etc ... уничтожается каждый раз при запуске новой модели (следовательно, self.destroy_old в начале init функция).

Если я жду загрузки объекта перед созданием новой сцены, он работает так, как ожидалось, поэтому, когда начинается новая сцена, на сцене появляется только одна часть. Однако, если сцена инициируется, а затем запускается другая сцена, а старая - по-прежнему загружает эту часть, новая сцена будет загружаться как в новой, так и в старой части. Это происходит, несмотря на то, что перед созданием новых компонентов загрузчик, loadermanager и часть имеют значение null.

Так кто-нибудь знает, как остановить загрузчик от загрузки файла в сцену во время загрузки?

Я не смог найти какие-либо функции, которые казались родными для загрузчика или STLLoader (который наследует загрузчик) в документации.

ответ

0

Хорошо, поэтому мне пришлось сделать пару (очень простых) изменений в файлах three.js и STLLoader, и у меня появилась идея отсюда cancel download jsonLoader & ImageUtils.loadTexture. Во всяком случае, это мое собственное решение:

В three.js я должен был сделать следующее изменение THREE.XHRLoader:

THREE.XHRLoader.prototype = { 

    constructor: THREE.XHRLoader, 

    load: function (url, onLoad, onProgress, onError) { 

     ... 

     var request = new XMLHttpRequest(); 

     ... 

     scope.manager.itemStart(url); 

     return request; // I ADDED THIS 

    }, 
    ... 

}; 

Тогда в STLLoader.js я добавил:

THREE.STLLoader.prototype = { 

constructor: THREE.STLLoader, 

load: function (url, onLoad, onProgress, onError) { 

    var scope = this; 

    var loader = new THREE.XHRLoader(scope.manager); 
    loader.setCrossOrigin(this.crossOrigin); 
    loader.setResponseType('arraybuffer'); 

    // Here I added request to equal loader since i made load return the original xmlhttprequest 
    var request = loader.load(url, function (text) { 

     onLoad(scope.parse(text)); 

    }, onProgress, onError); 

    // here I return the request further back to my own application 
    return request; 

}, 

И, наконец, в моем собственном коде:

var modelViewer = { 
    request: {}, 
    ... 
} 

modelViewer.destroy_old = function(canvas_selector){ 
    if (!$.isEmptyObject(this.request)){ 
     this.request.abort(); 
    } 
    ... 
} 

modelViewer.init = function(part, canvas_selector){ 
    ... 
    function loadModel(url){ 
     ... 
     self.request = self.loader.load(url, function(geometry){ 
     ... 
     } 
    } 
} 
+0

Я уже создал запрос на вытягивание для трехjs, чтобы объект 'request' возвращался на th e загрузчик по умолчанию. Поэтому он, надеюсь, будет доступен всем в следующем выпуске ThreeJs, и всем, кто хочет этой функции, не придется редактировать файлы three.js. [ссылка на соответствующую проблему] (https://github.com/mrdoob/three.js/issues/6641) –

Смежные вопросы