/** * The image factory takes care that we only make requests for Image URLs which we have not already started downloading * @param graphics * @param apiImageFactory * @param progressCallback * @returns {R3.D3.ImageFactory} * @constructor */ R3.D3.ImageFactory = function ( graphics, apiImageFactory, progressCallback ) { graphics.isNotThreeThrow(); this.graphics = graphics; if (R3.Utils.UndefinedOrNull(apiImageFactory)) { apiImageFactory = {}; } if (apiImageFactory instanceof R3.D3.ImageFactory) { return apiImageFactory; } R3.D3.API.ImageFactory.call( this, apiImageFactory.id, apiImageFactory.name, apiImageFactory.baseUrl, apiImageFactory.parentEntity ); if (R3.Utils.UndefinedOrNull(progressCallback)) { progressCallback = null; } this.progressCallback = progressCallback; R3.Component.call( this, R3.Component.COMPONENT_IMAGE_FACTORY ); this.promiseList = {}; }; R3.D3.ImageFactory.prototype = Object.create(R3.D3.API.ImageFactory.prototype); R3.D3.ImageFactory.prototype.constructor = R3.D3.ImageFactory; R3.D3.ImageFactory.prototype.createInstance = function(update) { if (!this.loaded) { console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); return null; } var instance = null; if (update) { instance = this.instance; } else { instance = new THREE.ImageLoader(); } instance.crossOrigin = ''; return instance; }; /** * Update instance */ R3.D3.ImageFactory.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; /** * Loads an image, either returns the image immediately if already loaded, or a promise to load the image * @param imagePath * @returns {*} * @constructor */ R3.D3.ImageFactory.prototype.loadImage = function( imagePath, force ) { imagePath = imagePath.replace(new RegExp('\/*'), '/'); if (!imagePath) { console.log('Attempted to download bad URL : ' + imagePath); throw new Error('Bad URL : ' + imagePath); } if (!force && this.promiseList[imagePath]) { return this.promiseList[imagePath]; } var defer = Q.defer(); this.promiseList[imagePath] = defer.promise; this.instance.load( this.baseUrl + imagePath + '?ts=' + Date.now(), function (image) { R3.Event.Emit( R3.Event.IMAGE_LOADED, { imagePath : imagePath, imageInstance : image } ); defer.resolve(image); }.bind(this), function onProgress(xhr) { if (this.progressCallback) { this.progressCallback((xhr.loaded / xhr.total * 100)); } }.bind(this), function onError() { defer.reject('Failed to download image : ' + this.baseUrl + imagePath); }.bind(this) ); return this.promiseList[imagePath]; }; /** * Converts a R3.D3.ImageFactory to a R3.D3.API.ImageFactory * @returns {R3.D3.API.ImageFactory} */ R3.D3.ImageFactory.prototype.toApiObject = function() { return new R3.D3.API.ImageFactory( this.id, this.name, this.baseUrl, R3.Utils.IdOrNull(this.parentEntity) ); }; /** * Returns a new R3.D3.ImageFactory from a R3.D3.API.ImageFactory * @param graphics R3.D3.Graphics * @param objectImageFactory R3.D3.API.ImageFactory * @returns {R3.D3.ImageFactory} */ R3.D3.ImageFactory.FromObject = function(graphics, objectImageFactory) { return new R3.D3.ImageFactory( graphics, R3.D3.API.ImageFactory.FromObject(objectImageFactory) ); };