From c988516f8d954229093a469948da69c9a11e6f0b Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Thu, 3 Nov 2016 14:33:14 +0100 Subject: [PATCH] fixed image loading - tests passing --- src/api-lib.js/api-lib-scene.js | 9 + src/game-lib-material.js | 347 +++++++++++++++++++------------- src/game-lib-scene.js | 253 ++++++++++++++++++----- src/game-lib-texture.js | 265 ++---------------------- 4 files changed, 440 insertions(+), 434 deletions(-) create mode 100644 src/api-lib.js/api-lib-scene.js diff --git a/src/api-lib.js/api-lib-scene.js b/src/api-lib.js/api-lib-scene.js new file mode 100644 index 0000000..c626a41 --- /dev/null +++ b/src/api-lib.js/api-lib-scene.js @@ -0,0 +1,9 @@ +ApiLib = function() { + +}; + +ApiLib.Scene = function( + +) { + +}; \ No newline at end of file diff --git a/src/game-lib-material.js b/src/game-lib-material.js index efd4015..c31d8cf 100644 --- a/src/game-lib-material.js +++ b/src/game-lib-material.js @@ -407,11 +407,6 @@ GameLib.D3.Material = function( envMapIntensity = 1.0; } this.envMapIntensity = envMapIntensity; - - /** - * @type GameLib.D3.Material.ImageLoadedCallback[] - */ - this.OnImageLoadedCallbacks = []; }; /** @@ -530,13 +525,115 @@ GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial"; * Creates an instance Material from a GameLib.D3.Material * @param apiMaterial GameLib.D3.Material * @param graphics GameLib.D3.Graphics - * @param imageLoader GameLib.D3.Texture + * @param gameLibScene GameLib.D3.Scene */ GameLib.D3.Material.CreateInstanceMaterial = function( apiMaterial, graphics, - imageLoader + gameLibScene ) { + var maps = apiMaterial.maps; + + var gameLibTextures = []; + + for (var map in maps) { + if (maps.hasOwnProperty(map)) { + if (maps[map]) { + var instanceMapId = null; + + if (map == 'alpha') { + instanceMapId = 'alhpaMap'; + } + + if (map == 'ao') { + instanceMapId = 'aoMap'; + } + + if (map == 'bump') { + instanceMapId = 'bumpMap'; + } + + if (map == 'displacement') { + instanceMapId = 'displacementMap'; + } + + if (map == 'emissive') { + instanceMapId = 'emissiveMap'; + } + + if (map == 'environment') { + instanceMapId = 'envMap'; + } + + if (map == 'light') { + instanceMapId = 'lightMap'; + } + + if (map == 'specular') { + instanceMapId = 'specularMap'; + } + + if (map == 'diffuse') { + instanceMapId = 'map'; + } + + if (map == 'roughness') { + instanceMapId = 'roughnessMap'; + } + + if (map == 'metalness') { + instanceMapId = 'metalnessMap'; + } + + if (instanceMapId == null) { + console.warn("unsupported map type : " + map); + } + + var apiTexture = maps[map]; + + var apiImage = apiTexture.image; + + var gameLibTexture = new GameLib.D3.Texture( + apiTexture.id, + apiTexture.name, + new GameLib.D3.Image( + apiImage.id, + apiImage.textureLink, + apiImage.filename, + apiImage.size, + apiImage.contentType + ), + apiTexture.wrapS, + apiTexture.wrapT, + new GameLib.D3.Vector2( + apiTexture.repeat.x, + apiTexture.repeat.y + ), + apiTexture.data, + apiTexture.format, + apiTexture.mapping, + apiTexture.magFilter, + apiTexture.minFilter, + apiTexture.textureType, + apiTexture.anisotropy, + new GameLib.D3.Vector2( + apiTexture.offset.x, + apiTexture.offset.y + ), + apiTexture.generateMipmaps, + apiTexture.flipY, + apiTexture.mipmaps, + apiTexture.unpackAlignment, + apiTexture.premultiplyAlpha, + apiTexture.encoding, + instanceMapId + ); + + gameLibTextures.push(gameLibTexture); + } + } + } + var gameLibMaterial = new GameLib.D3.Material( apiMaterial.id, apiMaterial.name, @@ -544,7 +641,7 @@ GameLib.D3.Material.CreateInstanceMaterial = function( apiMaterial.opacity, apiMaterial.side, apiMaterial.transparent, - apiMaterial.maps, + gameLibTextures, new GameLib.D3.Color( apiMaterial.specular.r, apiMaterial.specular.g, @@ -614,156 +711,134 @@ GameLib.D3.Material.CreateInstanceMaterial = function( var instanceMaterial = null; - var blenderMaps = []; - - if (apiMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { + if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { instanceMaterial = new graphics.instance.MeshStandardMaterial({ - name: apiMaterial.name, - opacity: apiMaterial.opacity, - transparent: apiMaterial.transparent, - blending: apiMaterial.blending, - blendSrc: apiMaterial.blendSrc, - blendDst: apiMaterial.blendDst, - blendEquation: apiMaterial.blendEquation, - depthTest: apiMaterial.depthTest, - depthFunc: apiMaterial.depthFunc, - depthWrite: apiMaterial.depthWrite, - polygonOffset: apiMaterial.polygonOffset, - polygonOffsetFactor: apiMaterial.polygonOffsetFactor, - polygonOffsetUnits: apiMaterial.polygonOffsetUnits, - alphaTest: apiMaterial.alphaTest, - clippingPlanes: apiMaterial.clippingPlanes, - clipShadows: apiMaterial.clipShadows, - overdraw: apiMaterial.overdraw, - visible: apiMaterial.visible, - side: apiMaterial.side, + name: gameLibMaterial.name, + opacity: gameLibMaterial.opacity, + transparent: gameLibMaterial.transparent, + blending: gameLibMaterial.blending, + blendSrc: gameLibMaterial.blendSrc, + blendDst: gameLibMaterial.blendDst, + blendEquation: gameLibMaterial.blendEquation, + depthTest: gameLibMaterial.depthTest, + depthFunc: gameLibMaterial.depthFunc, + depthWrite: gameLibMaterial.depthWrite, + polygonOffset: gameLibMaterial.polygonOffset, + polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor, + polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits, + alphaTest: gameLibMaterial.alphaTest, + clippingPlanes: gameLibMaterial.clippingPlanes, + clipShadows: gameLibMaterial.clipShadows, + overdraw: gameLibMaterial.overdraw, + visible: gameLibMaterial.visible, + side: gameLibMaterial.side, color: new graphics.instance.Color( - apiMaterial.color.r, - apiMaterial.color.g, - apiMaterial.color.b + gameLibMaterial.color.r, + gameLibMaterial.color.g, + gameLibMaterial.color.b ), - roughness: apiMaterial.roughness, - metalness: apiMaterial.metalness, - lightMapIntensity: apiMaterial.lightMapIntensity, - aoMapIntensity: apiMaterial.aoMapIntensity, + roughness: gameLibMaterial.roughness, + metalness: gameLibMaterial.metalness, + lightMapIntensity: gameLibMaterial.lightMapIntensity, + aoMapIntensity: gameLibMaterial.aoMapIntensity, emissive: new graphics.instance.Color( - apiMaterial.emissive.r, - apiMaterial.emissive.g, - apiMaterial.emissive.b + gameLibMaterial.emissive.r, + gameLibMaterial.emissive.g, + gameLibMaterial.emissive.b ), - emissiveIntensity: apiMaterial.emissiveIntensity, - bumpScale: apiMaterial.bumpScale, - normalScale: apiMaterial.normalScale, - displacementScale: apiMaterial.displacementScale, - refractionRatio: apiMaterial.refractionRatio, - fog: apiMaterial.fog, - shading: apiMaterial.shading, - wireframe: apiMaterial.wireframe, - wireframeLinewidth: apiMaterial.wireframeLineWidth, - wireframeLinecap: apiMaterial.wireframeLineCap, - wireframeLinejoin: apiMaterial.wireframeLineJoin, - vertexColors: apiMaterial.vertexColors, - skinning: apiMaterial.skinning, - morphTargets: apiMaterial.morphTargets, - morphNormals: apiMaterial.morphNormals + emissiveIntensity: gameLibMaterial.emissiveIntensity, + bumpScale: gameLibMaterial.bumpScale, + normalScale: gameLibMaterial.normalScale, + displacementScale: gameLibMaterial.displacementScale, + refractionRatio: gameLibMaterial.refractionRatio, + fog: gameLibMaterial.fog, + shading: gameLibMaterial.shading, + wireframe: gameLibMaterial.wireframe, + wireframeLinewidth: gameLibMaterial.wireframeLineWidth, + wireframeLinecap: gameLibMaterial.wireframeLineCap, + wireframeLinejoin: gameLibMaterial.wireframeLineJoin, + vertexColors: gameLibMaterial.vertexColors, + skinning: gameLibMaterial.skinning, + morphTargets: gameLibMaterial.morphTargets, + morphNormals: gameLibMaterial.morphNormals }); - blenderMaps.push( - 'diffuse', - 'light', - 'ao', - 'emissive', - 'bump', - 'normal', - 'displacement', - 'roughness', - 'metalness', - 'alpha', - 'environment' - ); - - } else if (apiMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { + } else if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { instanceMaterial = new graphics.instance.MeshPhongMaterial({ - name: apiMaterial.name, - opacity: apiMaterial.opacity, - transparent: apiMaterial.transparent, - blending: apiMaterial.blending, - blendSrc: apiMaterial.blendSrc, - blendDst: apiMaterial.blendDst, - blendEquation: apiMaterial.blendEquation, - depthTest: apiMaterial.depthTest, - depthFunc: apiMaterial.depthFunc, - depthWrite: apiMaterial.depthWrite, - polygonOffset: apiMaterial.polygonOffset, - polygonOffsetFactor: apiMaterial.polygonOffsetFactor, - polygonOffsetUnits: apiMaterial.polygonOffsetUnits, - alphaTest: apiMaterial.alphaTest, - clippingPlanes: apiMaterial.clippingPlanes, - clipShadows: apiMaterial.clipShadows, - overdraw: apiMaterial.overdraw, - visible: apiMaterial.visible, - side: apiMaterial.side, + name: gameLibMaterial.name, + opacity: gameLibMaterial.opacity, + transparent: gameLibMaterial.transparent, + blending: gameLibMaterial.blending, + blendSrc: gameLibMaterial.blendSrc, + blendDst: gameLibMaterial.blendDst, + blendEquation: gameLibMaterial.blendEquation, + depthTest: gameLibMaterial.depthTest, + depthFunc: gameLibMaterial.depthFunc, + depthWrite: gameLibMaterial.depthWrite, + polygonOffset: gameLibMaterial.polygonOffset, + polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor, + polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits, + alphaTest: gameLibMaterial.alphaTest, + clippingPlanes: gameLibMaterial.clippingPlanes, + clipShadows: gameLibMaterial.clipShadows, + overdraw: gameLibMaterial.overdraw, + visible: gameLibMaterial.visible, + side: gameLibMaterial.side, color: new graphics.instance.Color( - apiMaterial.color.r, - apiMaterial.color.g, - apiMaterial.color.b + gameLibMaterial.color.r, + gameLibMaterial.color.g, + gameLibMaterial.color.b ), specular: new graphics.instance.Color( - apiMaterial.specular.r, - apiMaterial.specular.g, - apiMaterial.specular.b + gameLibMaterial.specular.r, + gameLibMaterial.specular.g, + gameLibMaterial.specular.b ), - shininess: apiMaterial.shininess, - lightMapIntensity: apiMaterial.lightMapIntensity, - aoMapIntensity: apiMaterial.aoMapIntensity, + shininess: gameLibMaterial.shininess, + lightMapIntensity: gameLibMaterial.lightMapIntensity, + aoMapIntensity: gameLibMaterial.aoMapIntensity, emissive: new graphics.instance.Color( - apiMaterial.emissive.r, - apiMaterial.emissive.g, - apiMaterial.emissive.b + gameLibMaterial.emissive.r, + gameLibMaterial.emissive.g, + gameLibMaterial.emissive.b ), - emissiveIntensity: apiMaterial.emissiveIntensity, - bumpScale: apiMaterial.bumpScale, - normalScale: apiMaterial.normalScale, - displacementScale: apiMaterial.displacementScale, - combine: apiMaterial.combine, - refractionRatio: apiMaterial.refractionRatio, - fog: apiMaterial.fog, - shading: apiMaterial.shading, - wireframe: apiMaterial.wireframe, - wireframeLinewidth: apiMaterial.wireframeLineWidth, - wireframeLinecap: apiMaterial.wireframeLineCap, - wireframeLinejoin: apiMaterial.wireframeLineJoin, - vertexColors: apiMaterial.vertexColors, - skinning: apiMaterial.skinning, - morphTargets: apiMaterial.morphTargets, - morphNormals: apiMaterial.morphNormals + emissiveIntensity: gameLibMaterial.emissiveIntensity, + bumpScale: gameLibMaterial.bumpScale, + normalScale: gameLibMaterial.normalScale, + displacementScale: gameLibMaterial.displacementScale, + combine: gameLibMaterial.combine, + refractionRatio: gameLibMaterial.refractionRatio, + fog: gameLibMaterial.fog, + shading: gameLibMaterial.shading, + wireframe: gameLibMaterial.wireframe, + wireframeLinewidth: gameLibMaterial.wireframeLineWidth, + wireframeLinecap: gameLibMaterial.wireframeLineCap, + wireframeLinejoin: gameLibMaterial.wireframeLineJoin, + vertexColors: gameLibMaterial.vertexColors, + skinning: gameLibMaterial.skinning, + morphTargets: gameLibMaterial.morphTargets, + morphNormals: gameLibMaterial.morphNormals }); - blenderMaps.push( - 'diffuse', - 'light', - 'ao', - 'emissive', - 'bump', - 'normal', - 'displacement', - 'specular', - 'alpha', - 'environment' - ); - } else { console.log("material type is not implemented yet: " + apiMaterial.materialType + " - material indexes could be screwed up"); } - if (blenderMaps.length > 0) { - imageLoader.setup( - gameLibMaterial, - instanceMaterial, - blenderMaps - ); + /** + * Here we need to notify the scene of all the textures which need to be created once image loading for the + * textures are complete. (this download process will be started at a later stage) + * The Notification objects take care of applying the loaded instance texture(s) to the instance material + * once it is loaded + */ + for (var t = 0; t < gameLibTextures.length; t++) { + gameLibScene.notify( + new GameLib.D3.Texture.Notification( + gameLibTextures[t], + instanceMaterial + ) + ) } return instanceMaterial; diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index b1f104c..7192961 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -1,23 +1,27 @@ /** * Scenes are objects putting meshes into 'world space' - * @param id + * @param id Mongo.ObjectId * @param path String * @param name String + * @param graphics GameLib.D3.Graphics * @param meshes GameLib.D3.Mesh[] - * @param quaternion - * @param position - * @param rotation - * @param scale - * @param parentSceneId - * @param lights - * @param worlds - * @param entities + * @param quaternion GameLib.D3.Vector4 + * @param position GameLib.D3.Vector3 + * @param rotation GameLib.D3.Vector3 + * @param scale GameLib.D3.Vector3 + * @param parentSceneId String + * @param lights GameLib.D3.Light[] + * @param worlds GameLib.D3.World[] + * @param entities GameLib.D3.Entity[] + * @param progressCallback + * @param uploadUrl String * @constructor */ GameLib.D3.Scene = function( id, path, name, + graphics, meshes, quaternion, position, @@ -26,12 +30,23 @@ GameLib.D3.Scene = function( parentSceneId, lights, worlds, - entities + entities, + progressCallback, + uploadUrl ) { this.id = id; this.sceneId = GameLib.D3.Tools.RandomId(); this.path = path; this.name = name; + + this.graphics = graphics; + + if (graphics) { + this.graphics.isNotThreeThrow(); + this.textureLoader = new this.graphics.instance.TextureLoader(); + this.textureLoader.crossOrigin = ''; + } + if (this.name.trim() == "") { this.name = 'unnamed'; } @@ -80,6 +95,142 @@ GameLib.D3.Scene = function( entities = []; } this.entities = entities; + + this.uploadUrl = uploadUrl; + + this.progressCallback = progressCallback; + + this.urls = []; + this.notifications = []; +}; + +/** + * Notification objects manage the links between image filenames, instance texture + * map IDs, and instance materials. + * @param notification GameLib.D3.Texture.Notificatio + * @constructor + */ +GameLib.D3.Scene.prototype.notify = function( + notification +) { + var url = this.uploadUrl + '/' + notification.gameLibTexture.image.filename; + + if (this.urls.indexOf(url) == -1) { + this.urls.push(url); + } + + this.notifications.push(notification); +}; + +/** + * Promises to loads a texture + * @param url + * @returns {promise.promise|jQuery.promise|*|promise|Promise} + */ +GameLib.D3.Scene.prototype.loadTexture = function(url) { + + var defer = Q.defer(); + + this.textureLoader.load( + url, + function onLoad(textureInstance){ + defer.resolve(textureInstance); + }, + function onProgress(xhr){ + if (this.progressCallback) { + this.progressCallback(Math.round(xhr.loaded / xhr.total * 100)) + } + }, + function onError() { + defer.resolve(null); + } + ); + + return defer.promise; +}; + +/** + * Starts a Image Loading Process - when all are done - executes all calbacks registered + * on materials listening for an image load to complete + * @param urls + * @param onLoadedCallback + * @returns {jQuery.promise|promise.promise|*|Promise|promise} + */ +GameLib.D3.Scene.prototype.loadTextures = function(urls, onLoadedCallback) { + + var texturesToLoad = []; + + for (var u = 0; u < urls.length; u++) { + texturesToLoad.push(this.loadTexture(urls[u])); + } + + Q.all(texturesToLoad).then( + + function onFulfilled(textureInstances) { + + var loadedTexturesInstances = []; + + for (var t = 0; t < textureInstances.length; t++) { + + var instanceTexture = textureInstances[t]; + + if (!instanceTexture) { + continue; + } + + for (var n = 0; n < this.notifications.length; n++) { + + var notification = this.notifications[n]; + + var gameLibTexture = notification.gameLibTexture; + + var instanceMaterial = notification.instanceMaterial; + + var instanceMapId = gameLibTexture.instanceMapId; + + var filename = gameLibTexture.image.filename; + + if (instanceTexture.image.src.match(new RegExp(filename + '$'))) { + instanceMaterial[instanceMapId] = new this.graphics.instance.Texture( + instanceTexture.image, + gameLibTexture.mapping, + gameLibTexture.wrapS, + gameLibTexture.wrapT, + gameLibTexture.magFilter, + gameLibTexture.minFilter, + gameLibTexture.format, + gameLibTexture.textureType, + gameLibTexture.anisotropy + ); + + instanceMaterial[instanceMapId].name = gameLibTexture.name; + instanceMaterial[instanceMapId].flipY = gameLibTexture.flipY; + instanceMaterial[instanceMapId].encoding = gameLibTexture.encoding; + instanceMaterial[instanceMapId].flipY = gameLibTexture.flipY; + instanceMaterial[instanceMapId].offset.x = gameLibTexture.offset.x; + instanceMaterial[instanceMapId].offset.y = gameLibTexture.offset.y; + instanceMaterial[instanceMapId].mipmaps = gameLibTexture.mipmaps; + instanceMaterial[instanceMapId].unpackAlignment = gameLibTexture.unpackAlignment; + instanceMaterial[instanceMapId].premultiplyAlpha = gameLibTexture.premultiplyAlpha; + instanceMaterial[instanceMapId].needsUpdate = true; + instanceMaterial.needsUpdate = true; + + loadedTexturesInstances.push(instanceMaterial[instanceMapId]); + } + } + } + + onLoadedCallback(loadedTexturesInstances); + + }.bind(this), + function onRejected(message){ + console.log('Promise failed : ' + message); + }, + function onProgress(){ + console.log('progress'); + } + ); + }; /** @@ -126,7 +277,7 @@ GameLib.D3.Scene.LoadSceneFromApi = function( var scene = response.scene[0]; - var physics3ds = []; + var entities = []; if (scene.worlds && scene.worlds.length > 0) { console.warn('Implement physics worlds code here'); @@ -192,6 +343,7 @@ GameLib.D3.Scene.LoadSceneFromApi = function( scene._id || scene.id, scene.path, scene.name, + graphics, scene.meshes, new GameLib.D3.Vector4( scene.quaternion.x, @@ -216,16 +368,17 @@ GameLib.D3.Scene.LoadSceneFromApi = function( ), scene.parentSceneId, lights3d, - physics3ds + entities, + uploadUrl, + progressCallback, + uploadUrl ); GameLib.D3.Scene.LoadScene( scene3d, onLoaded, false, - graphics, - uploadUrl, - progressCallback + graphics ); } } @@ -240,16 +393,12 @@ GameLib.D3.Scene.LoadSceneFromApi = function( * @param onLoaded callback when all meshes have loaded * @param computeNormals set to true to compute new face and vertex normals during load * @param graphics GameLib.D3.Graphics - * @param uploadUrl - * @param progressCallback */ GameLib.D3.Scene.LoadScene = function( gameLibScene, onLoaded, computeNormals, - graphics, - uploadUrl, - progressCallback + graphics ) { console.log("loading scene " + gameLibScene.name); @@ -263,12 +412,6 @@ GameLib.D3.Scene.LoadScene = function( var instanceMeshes = []; - var gameLibTexture = new GameLib.D3.Texture( - graphics, - uploadUrl, - progressCallback - ); - for (var m = 0; m < gameLibScene.meshes.length; m++) { var mesh = gameLibScene.meshes[m]; @@ -407,7 +550,7 @@ GameLib.D3.Scene.LoadScene = function( var instanceMaterial = GameLib.D3.Material.CreateInstanceMaterial( materials[0], graphics, - gameLibTexture + gameLibScene ); var instanceMesh = GameLib.D3.Mesh.CreateInstanceMesh( @@ -519,23 +662,43 @@ GameLib.D3.Scene.LoadScene = function( instanceScene.add(instanceLights[l]); } - gameLibTexture.start.then( - function onFullfilled() { - onLoaded( - gameLibScene, - { - scene: instanceScene, - lights: instanceLights, - meshes: instanceMeshes - } - ); - }, - function onRejected(message) { - console.log('Image loading failed with the following message: ' + message); - }, - function onProgress() { - console.log('loading images...'); - } - ); + gameLibScene.loadTextures(gameLibScene.urls, function(loadedTextures) { + + console.log('Found image data and applied it to ' + loadedTextures.length + ' textures'); + + onLoaded( + gameLibScene, + { + scene: instanceScene, + lights: instanceLights, + meshes: instanceMeshes + } + ); + }); }; + +GameLib.D3.Scene.FromAPIScene = function( + apiScene, + graphics, + progressCallback, + uploadUrl +) { + return new GameLib.D3.Scene( + apiScene.id, + apiScene.path, + apiScene.name, + graphics, + apiScene.meshes, + apiScene.quaternion, + apiScene.position, + apiScene.rotation, + apiScene.scale, + apiScene.parentSceneId, + apiScene.lights, + apiScene.worlds, + apiScene.entities, + progressCallback, + uploadUrl + ) +}; diff --git a/src/game-lib-texture.js b/src/game-lib-texture.js index 6539348..ce116c3 100644 --- a/src/game-lib-texture.js +++ b/src/game-lib-texture.js @@ -20,6 +20,7 @@ * @param unpackAlignment * @param premultiplyAlpha * @param encoding + * @param instanceMapId * @constructor */ GameLib.D3.Texture = function( @@ -42,7 +43,8 @@ GameLib.D3.Texture = function( mipmaps, unpackAlignment, premultiplyAlpha, - encoding + encoding, + instanceMapId ) { this.id = id; this.name = name; @@ -132,6 +134,8 @@ GameLib.D3.Texture = function( encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING; } this.encoding = encoding; + + this.instanceMapId = instanceMapId; }; /** @@ -204,263 +208,18 @@ GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. /** - * Defers loading of an image and resolves once image is loaded - * @param gameLibTexture GameLib.D3.Texture + * A Notification object stores an association between a gameLibTexture and a instance material map. * @param instanceMaterial - * @param instanceMaterialMapType - * @param graphics GameLib.D3.Graphics - * @param uploadUrl String - * @param progressCallback - * @returns {Promise} + * @param gameLibTexture + * @constructor */ -GameLib.D3.Texture.LoadMap = function( +GameLib.D3.Texture.Notification = function( gameLibTexture, - instanceMaterial, - instanceMaterialMapType, - graphics, - uploadUrl, - progressCallback + instanceMaterial ) { - - var defer = Q.defer(); - - var imagePath = null; - - var textureLoader = new graphics.instance.TextureLoader(); - - if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { - /** - * Else, load from upload source - */ - imagePath = uploadUrl + '/' + gameLibTexture.image.filename; - } - - if (!imagePath) { - defer.reject("No image path"); - return defer.promise; - } - - - - return defer.promise; -}; - -/** - * Image Loader - attempts to reduce image loading calls by only loading the necessary images once - and setting - * them up per material later. - * @param graphics GameLib.D3.Graphics - * @param uploadUrl String - * @param progressCallback - * @constructor - */ -GameLib.D3.Texture = function( - graphics, - uploadUrl, - progressCallback -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - this.textureLoader = new this.graphics.instance.TextureLoader(); - this.textureLoader.crossOrigin = ''; - - this.uploadUrl = uploadUrl; - this.progressCallback = progressCallback; - this.urls = []; - this.gameLibMaterials = []; + this.gameLibTexture = gameLibTexture; + this.instanceMaterial = instanceMaterial; }; -/** - * Sets up the Texture Loader by Notifying it of any images that we intend to download soon - * Instead of starting the download immediately - we should collect all the image URLs and attempt - * to download them only once - then after they have downloaded, we execute any pending OnImageLoaded callbacks - * on the Material - * @param gameLibMaterial - * @param instanceMaterial - * @param blenderMaps - */ -GameLib.D3.Texture.prototype.setup = function( - gameLibMaterial, - instanceMaterial, - blenderMaps -) { - for (var ti = 0; ti < blenderMaps.length; ti++) { - - var map = blenderMaps[ti]; - - if (gameLibMaterial.maps.hasOwnProperty(map)) { - - var blenderTexture = gameLibMaterial.maps[map]; - - if ( - blenderTexture && - blenderTexture.image && - blenderTexture.image.filename - ) { - - var instanceMapId = null; - - if (map == 'alpha') { - instanceMapId = 'alhpaMap'; - } - - if (map == 'ao') { - instanceMapId = 'aoMap'; - } - - if (map == 'bump') { - instanceMapId = 'bumpMap'; - } - - if (map == 'displacement') { - instanceMapId = 'displacementMap'; - } - - if (map == 'emissive') { - instanceMapId = 'emissiveMap'; - } - - if (map == 'environment') { - instanceMapId = 'envMap'; - } - - if (map == 'light') { - instanceMapId = 'lightMap'; - } - - if (map == 'specular') { - instanceMapId = 'specularMap'; - } - - if (map == 'diffuse') { - instanceMapId = 'map'; - } - - if (map == 'roughness') { - instanceMapId = 'roughnessMap'; - } - - if (map == 'metalness') { - instanceMapId = 'metalnessMap'; - } - - if (instanceMapId == null) { - console.warn("unsupported map type : " + map); - } - - gameLibMaterial.OnImageLoadedCallbacks.push( - new GameLib.D3.Material.ImageLoadedCallback( - instanceMaterial, - instanceMapId - ) - ); - - this.notify( - gameLibMaterial, - blenderTexture.image.filename - ); - } - } - } -}; - -/** - * Notifies the texture loader to load the image (if not already started) - * @param gameLibMaterial - * @param fileName - * @constructor - */ -GameLib.D3.Texture.prototype.notify = function( - gameLibMaterial, - fileName -) { - this.gameLibMaterials.push(gameLibMaterial); - this.urls.push(this.uploadUrl + '/' + fileName); -}; - -GameLib.D3.Texture.prototype.loadTexture = function(url, gameLibTexture) { - - var defer = Q.defer(); - - this.textureLoader.load( - url, - function onLoad(textureInstance){ - textureInstance.name = gameLibTexture.name; - textureInstance.anisotropy = gameLibTexture.anisotropy; - textureInstance.encoding = gameLibTexture.encoding; - textureInstance.flipY = gameLibTexture.flipY; - /** - * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes - */ - textureInstance.generateMipmaps = gameLibTexture.generateMipmaps; - textureInstance.magFilter = gameLibTexture.magFilter; - textureInstance.minFilter = gameLibTexture.minFilter; - textureInstance.mapping = gameLibTexture.mapping; - textureInstance.mipmaps = gameLibTexture.mipmaps; - textureInstance.offset = new this.graphics.instance.Vector2( - gameLibTexture.offset.x, - gameLibTexture.offset.y - ); - textureInstance.premultiplyAlpha = gameLibTexture.premultiplyAlpha; - textureInstance.textureType = gameLibTexture.textureType; - textureInstance.wrapS = gameLibTexture.wrapS; - textureInstance.wrapT = gameLibTexture.wrapT; - textureInstance.unpackAlignment = gameLibTexture.unpackAlignment; - textureInstance.needsUpdate = true; - defer.resolve(textureInstance); - }, - function onProgress(xhr){ - if (this.progressCallback) { - this.progressCallback(Math.round(xhr.loaded / xhr.total * 100)) - } - }, - function onError() { - defer.resolve(null); - } - ); - - return defer.promise; -}; - -/** - * Starts a Image Loading Process - when all are done - executes all calbacks registered - * on materials listening for an image load to complete - * @returns {promise.promise|jQuery.promise|*|Promise|promise} - */ -GameLib.D3.Texture.prototype.start = function() { - - var defer = Q.defer(); - - var texturesToLoad = []; - - for (var u = 0; u < this.urls.length; u++) { - texturesToLoad.push(this.loadTexture(url, this.gameLibMaterials[u])); - } - - Q.all(texturesToLoad).then( - function(texture) { - return function onFulfilled(results) { - - for (var r = 0; r < results.length; r++) { - for (var t = 0; t < texture.gameLibMaterials.length; t++) { - for (var cb = 0; cb < texture.gameLibMaterials[t].OnImageLoadedCallbacks.length; cb++) { - texture.gameLibMaterials[t].OnImageLoadedCallbacks(results[r]); - } - } - } - - defer.resolve(results); - }; - }(this), - function onRejected(message){ - defer.reject(message); - }, - function onProgress(){ - console.log('progress'); - } - ); - - return defer.promise; -}; \ No newline at end of file