diff --git a/src/game-lib-material.js b/src/game-lib-material.js index 5cd7a91..efd4015 100644 --- a/src/game-lib-material.js +++ b/src/game-lib-material.js @@ -408,6 +408,26 @@ GameLib.D3.Material = function( } this.envMapIntensity = envMapIntensity; + /** + * @type GameLib.D3.Material.ImageLoadedCallback[] + */ + this.OnImageLoadedCallbacks = []; +}; + +/** + * Assigns a copy of the loaded texture map to the instance material + * @param instanceMaterial + * @param instanceMapId + * @returns {Function} + * @constructor + */ +GameLib.D3.Material.ImageLoadedCallback = function( + instanceMaterial, + instanceMapId +) { + return function(texture) { + instanceMaterial[instanceMapId] = texture.clone(); + }; }; /** @@ -508,75 +528,145 @@ GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial"; /** * Creates an instance Material from a GameLib.D3.Material - * @param gameLibMaterial GameLib.D3.Material + * @param apiMaterial GameLib.D3.Material * @param graphics GameLib.D3.Graphics - * @param uploadUrl String - * @param progressCallback + * @param imageLoader GameLib.D3.Texture */ GameLib.D3.Material.CreateInstanceMaterial = function( - gameLibMaterial, + apiMaterial, graphics, - uploadUrl, - progressCallback + imageLoader ) { - - var defer = Q.defer(); + var gameLibMaterial = new GameLib.D3.Material( + apiMaterial.id, + apiMaterial.name, + apiMaterial.materialType, + apiMaterial.opacity, + apiMaterial.side, + apiMaterial.transparent, + apiMaterial.maps, + new GameLib.D3.Color( + apiMaterial.specular.r, + apiMaterial.specular.g, + apiMaterial.specular.b, + apiMaterial.specular.a + ), + apiMaterial.lightMapIntensity, + apiMaterial.aoMapIntensity, + new GameLib.D3.Color( + apiMaterial.color.r, + apiMaterial.color.g, + apiMaterial.color.b, + apiMaterial.color.a + ), + new GameLib.D3.Color( + apiMaterial.emissive.r, + apiMaterial.emissive.g, + apiMaterial.emissive.b, + apiMaterial.emissive.a + ), + apiMaterial.emissiveIntensity, + apiMaterial.combine, + apiMaterial.shininess, + apiMaterial.reflectivity, + apiMaterial.refractionRatio, + apiMaterial.fog, + apiMaterial.wireframe, + apiMaterial.wireframeLineWidth, + apiMaterial.wireframeLineCap, + apiMaterial.wireframeLineJoin, + apiMaterial.vertexColors, + apiMaterial.skinning, + apiMaterial.morphTargets, + apiMaterial.morphNormals, + apiMaterial.lineWidth, + apiMaterial.lineCap, + apiMaterial.lineJoin, + apiMaterial.dashSize, + apiMaterial.gapWidth, + apiMaterial.blending, + apiMaterial.blendSrc, + apiMaterial.blendDst, + apiMaterial.blendEquation, + apiMaterial.depthTest, + apiMaterial.depthFunc, + apiMaterial.depthWrite, + apiMaterial.polygonOffset, + apiMaterial.polygonOffsetFactor, + apiMaterial.polygonOffsetUnits, + apiMaterial.alphaTest, + apiMaterial.clippingPlanes, + apiMaterial.clipShadows, + apiMaterial.visible, + apiMaterial.overdraw, + apiMaterial.shading, + apiMaterial.bumpScale, + apiMaterial.normalScale, + apiMaterial.displacementScale, + apiMaterial.displacementBias, + apiMaterial.roughness, + apiMaterial.metalness, + apiMaterial.pointSize, + apiMaterial.pointSizeAttenuation, + apiMaterial.spriteRotation, + apiMaterial.envMapIntensity + ); var instanceMaterial = null; var blenderMaps = []; - if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { + if (apiMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { instanceMaterial = new graphics.instance.MeshStandardMaterial({ - 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, + 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, color: new graphics.instance.Color( - gameLibMaterial.color.r, - gameLibMaterial.color.g, - gameLibMaterial.color.b + apiMaterial.color.r, + apiMaterial.color.g, + apiMaterial.color.b ), - roughness: gameLibMaterial.roughness, - metalness: gameLibMaterial.metalness, - lightMapIntensity: gameLibMaterial.lightMapIntensity, - aoMapIntensity: gameLibMaterial.aoMapIntensity, + roughness: apiMaterial.roughness, + metalness: apiMaterial.metalness, + lightMapIntensity: apiMaterial.lightMapIntensity, + aoMapIntensity: apiMaterial.aoMapIntensity, emissive: new graphics.instance.Color( - gameLibMaterial.emissive.r, - gameLibMaterial.emissive.g, - gameLibMaterial.emissive.b + apiMaterial.emissive.r, + apiMaterial.emissive.g, + apiMaterial.emissive.b ), - 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 + 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 }); blenderMaps.push( @@ -592,62 +682,63 @@ GameLib.D3.Material.CreateInstanceMaterial = function( 'alpha', 'environment' ); - } else if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { + + } else if (apiMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { instanceMaterial = new graphics.instance.MeshPhongMaterial({ - 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, + 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, color: new graphics.instance.Color( - gameLibMaterial.color.r, - gameLibMaterial.color.g, - gameLibMaterial.color.b + apiMaterial.color.r, + apiMaterial.color.g, + apiMaterial.color.b ), specular: new graphics.instance.Color( - gameLibMaterial.specular.r, - gameLibMaterial.specular.g, - gameLibMaterial.specular.b + apiMaterial.specular.r, + apiMaterial.specular.g, + apiMaterial.specular.b ), - shininess: gameLibMaterial.shininess, - lightMapIntensity: gameLibMaterial.lightMapIntensity, - aoMapIntensity: gameLibMaterial.aoMapIntensity, + shininess: apiMaterial.shininess, + lightMapIntensity: apiMaterial.lightMapIntensity, + aoMapIntensity: apiMaterial.aoMapIntensity, emissive: new graphics.instance.Color( - gameLibMaterial.emissive.r, - gameLibMaterial.emissive.g, - gameLibMaterial.emissive.b + apiMaterial.emissive.r, + apiMaterial.emissive.g, + apiMaterial.emissive.b ), - 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 + 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 }); blenderMaps.push( @@ -664,40 +755,16 @@ GameLib.D3.Material.CreateInstanceMaterial = function( ); } else { - console.log("material type is not implemented yet: " + gameLibMaterial.materialType + " - material indexes could be screwed up"); - defer.reject(null); - return defer.promise; + console.log("material type is not implemented yet: " + apiMaterial.materialType + " - material indexes could be screwed up"); } if (blenderMaps.length > 0) { - - var textureMaps = GameLib.D3.Texture.LoadMaps( + imageLoader.setup( gameLibMaterial, - blenderMaps, instanceMaterial, - graphics, - uploadUrl, - progressCallback + blenderMaps ); - - if (textureMaps.length > 0) { - Q.all(textureMaps).then( - function onFulfilled(map){ - defer.resolve(instanceMaterial); - }, - function onRejected(message) { - console.log(message); - defer.reject(message); - }, - function onProgress(progress) { - console.log('progress'); - } - ) - } - - } else { - defer.resolve(instanceMaterial); } - return defer.promise; + return instanceMaterial; }; \ No newline at end of file diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index 91c908d..b1f104c 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -254,9 +254,20 @@ GameLib.D3.Scene.LoadScene = function( console.log("loading scene " + gameLibScene.name); + if (typeof onLoaded == 'undefined') { + console.warn('No on loaded callback has been specified'); + throw new Error('No on loaded callback has been specified'); + } + graphics.isNotThreeThrow(); - var meshQ = []; + var instanceMeshes = []; + + var gameLibTexture = new GameLib.D3.Texture( + graphics, + uploadUrl, + progressCallback + ); for (var m = 0; m < gameLibScene.meshes.length; m++) { @@ -393,148 +404,123 @@ GameLib.D3.Scene.LoadScene = function( geometry.computeVertexNormals(); } - var instanceMaterial = GameLib.D3.Material.CreateInstanceMaterial( + var instanceMaterial = GameLib.D3.Material.CreateInstanceMaterial( materials[0], graphics, - uploadUrl, - progressCallback + gameLibTexture ); - var result = instanceMaterial.then( - - (function(__mesh, __geometry) { - return function(materials) { - - console.log("loaded material : " + materials[0].name); - - /** - * We don't support MultiMaterial atm - it doesn't work with raycasting - */ - var material = materials[0]; - - var instanceMesh = GameLib.D3.Mesh.CreateInstanceMesh( - __mesh, - __geometry, - material, - graphics - ); - instanceMesh.name = __mesh.name; - - instanceMesh.position.x = __mesh.position.x; - instanceMesh.position.y = __mesh.position.y; - instanceMesh.position.z = __mesh.position.z; - - instanceMesh.rotation.x = __mesh.rotation.x; - instanceMesh.rotation.y = __mesh.rotation.y; - instanceMesh.rotation.z = __mesh.rotation.z; - - instanceMesh.scale.x = __mesh.scale.x; - instanceMesh.scale.y = __mesh.scale.y; - instanceMesh.scale.z = __mesh.scale.z; - - instanceMesh.quaternion.x = __mesh.quaternion.x; - instanceMesh.quaternion.y = __mesh.quaternion.y; - instanceMesh.quaternion.z = __mesh.quaternion.z; - instanceMesh.quaternion.w = __mesh.quaternion.w; - - return instanceMesh; - }; - })(mesh, geometry), - function onRejected(message) { - console.log(message); - return null; - }, - function onProgress(progress) { - console.log('material progress'); - } + var instanceMesh = GameLib.D3.Mesh.CreateInstanceMesh( + mesh, + geometry, + instanceMaterial, + graphics ); - meshQ.push(result); + instanceMesh.name = mesh.name; + + instanceMesh.position.x = mesh.position.x; + instanceMesh.position.y = mesh.position.y; + instanceMesh.position.z = mesh.position.z; + + instanceMesh.rotation.x = mesh.rotation.x; + instanceMesh.rotation.y = mesh.rotation.y; + instanceMesh.rotation.z = mesh.rotation.z; + + instanceMesh.scale.x = mesh.scale.x; + instanceMesh.scale.y = mesh.scale.y; + instanceMesh.scale.z = mesh.scale.z; + + instanceMesh.quaternion.x = mesh.quaternion.x; + instanceMesh.quaternion.y = mesh.quaternion.y; + instanceMesh.quaternion.z = mesh.quaternion.z; + instanceMesh.quaternion.w = mesh.quaternion.w; + + instanceMeshes.push(instanceMesh); } - debugger; - console.log('hi'); + console.log("created all meshes"); - Q.all(meshQ).then( - function(instanceMeshes){ - console.log("all meshes have loaded"); - if (typeof onLoaded != 'undefined') { + var instanceLights = []; - var instanceLights = []; + if (gameLibScene.lights && gameLibScene.lights.length > 0) { - for (var sli = 0; sli < gameLibScene.lights.length; sli++) { + for (var glsl = 0; glsl < gameLibScene.lights.length; glsl++) { - var gameLibLight = gameLibScene.lights[sli]; + var gameLibLight = gameLibScene.lights[glsl]; - var light = null; + var light = null; - if (gameLibLight.lightType == 'AmbientLight') { - light = new graphics.instance.AmbientLight(gameLibLight.color, gameLibLight.intensity); - } - - if (gameLibLight.lightType == 'DirectionalLight') { - light = new graphics.instance.DirectionalLight(gameLibLight.color, gameLibLight.intensity); - } - - if (gameLibLight.lightType == 'PointLight') { - light = new graphics.instance.PointLight(gameLibLight.color, gameLibLight.intensity); - light.distance = gameLibLight.distance; - light.decay = gameLibLight.decay; - } - - if (gameLibLight.lightType == 'SpotLight') { - light = new graphics.instance.SpotLight(gameLibLight.color, gameLibLight.intensity); - light.distance = gameLibLight.distance; - light.angle = gameLibLight.angle; - light.penumbra = gameLibLight.penumbra; - light.decay = gameLibLight.decay; - } - - light.position.x = gameLibLight.position.x; - light.position.y = gameLibLight.position.y; - light.position.z = gameLibLight.position.z; - - light.rotation.x = gameLibLight.rotation.x; - light.rotation.y = gameLibLight.rotation.y; - light.rotation.z = gameLibLight.rotation.z; - - if (light == null) { - console.warn('Does not support lights of type :' + gameLibLight.lightType + ', not imported'); - } else { - light.name = gameLibLight.name; - instanceLights.push(light); - } + if (gameLibLight.lightType == 'AmbientLight') { + light = new graphics.instance.AmbientLight(gameLibLight.color, gameLibLight.intensity); } - var instanceScene = new graphics.instance.Scene(); - - instanceScene.name = gameLibScene.name; - - instanceScene.position.x = gameLibScene.position.x; - instanceScene.position.y = gameLibScene.position.y; - instanceScene.position.z = gameLibScene.position.z; - - instanceScene.rotation.x = gameLibScene.rotation.x; - instanceScene.rotation.y = gameLibScene.rotation.y; - instanceScene.rotation.z = gameLibScene.rotation.z; - - instanceScene.scale.x = gameLibScene.scale.x; - instanceScene.scale.y = gameLibScene.scale.y; - instanceScene.scale.z = gameLibScene.scale.z; - - instanceScene.quaternion.x = gameLibScene.quaternion.x; - instanceScene.quaternion.y = gameLibScene.quaternion.y; - instanceScene.quaternion.z = gameLibScene.quaternion.z; - instanceScene.quaternion.w = gameLibScene.quaternion.w; - - for (var m = 0; m < instanceMeshes.length; m++) { - instanceScene.add(instanceMeshes[m]); + if (gameLibLight.lightType == 'DirectionalLight') { + light = new graphics.instance.DirectionalLight(gameLibLight.color, gameLibLight.intensity); } - for (var l = 0; l < instanceLights.length; l++) { - instanceScene.add(instanceLights[l]); + if (gameLibLight.lightType == 'PointLight') { + light = new graphics.instance.PointLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.decay = gameLibLight.decay; } + if (gameLibLight.lightType == 'SpotLight') { + light = new graphics.instance.SpotLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.angle = gameLibLight.angle; + light.penumbra = gameLibLight.penumbra; + light.decay = gameLibLight.decay; + } + + light.position.x = gameLibLight.position.x; + light.position.y = gameLibLight.position.y; + light.position.z = gameLibLight.position.z; + + light.rotation.x = gameLibLight.rotation.x; + light.rotation.y = gameLibLight.rotation.y; + light.rotation.z = gameLibLight.rotation.z; + + if (light == null) { + console.warn('Does not support lights of type :' + gameLibLight.lightType + ', not imported'); + } else { + light.name = gameLibLight.name; + instanceLights.push(light); + } + } + } + + var instanceScene = new graphics.instance.Scene(); + + instanceScene.name = gameLibScene.name; + + instanceScene.position.x = gameLibScene.position.x; + instanceScene.position.y = gameLibScene.position.y; + instanceScene.position.z = gameLibScene.position.z; + + instanceScene.rotation.x = gameLibScene.rotation.x; + instanceScene.rotation.y = gameLibScene.rotation.y; + instanceScene.rotation.z = gameLibScene.rotation.z; + + instanceScene.scale.x = gameLibScene.scale.x; + instanceScene.scale.y = gameLibScene.scale.y; + instanceScene.scale.z = gameLibScene.scale.z; + + instanceScene.quaternion.x = gameLibScene.quaternion.x; + instanceScene.quaternion.y = gameLibScene.quaternion.y; + instanceScene.quaternion.z = gameLibScene.quaternion.z; + instanceScene.quaternion.w = gameLibScene.quaternion.w; + + for (var im = 0; im < instanceMeshes.length; im++) { + instanceScene.add(instanceMeshes[im]); + } + + for (var l = 0; l < instanceLights.length; l++) { + instanceScene.add(instanceLights[l]); + } + + gameLibTexture.start.then( + function onFullfilled() { onLoaded( gameLibScene, { @@ -543,14 +529,13 @@ GameLib.D3.Scene.LoadScene = function( meshes: instanceMeshes } ); - } - }, - function(error) { - console.log(error); - } - ).catch( - function(error){ - console.log(error); + }, + function onRejected(message) { + console.log('Image loading failed with the following message: ' + message); + }, + function onProgress() { + console.log('loading images...'); } ); -}; \ No newline at end of file + +}; diff --git a/src/game-lib-texture.js b/src/game-lib-texture.js index 73a0ba7..6539348 100644 --- a/src/game-lib-texture.js +++ b/src/game-lib-texture.js @@ -240,79 +240,51 @@ GameLib.D3.Texture.LoadMap = function( return defer.promise; } - textureLoader.crossOrigin = ''; - - textureLoader.load( - imagePath, - function(texture) { - /** - * onLoad - */ - instanceMaterial[instanceMaterialMapType] = texture; - instanceMaterial[instanceMaterialMapType].name = gameLibTexture.name; - instanceMaterial[instanceMaterialMapType].anisotropy = gameLibTexture.anisotropy; - instanceMaterial[instanceMaterialMapType].encoding = gameLibTexture.encoding; - instanceMaterial[instanceMaterialMapType].flipY = gameLibTexture.flipY; - /** - * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes - */ - instanceMaterial[instanceMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; - instanceMaterial[instanceMaterialMapType].magFilter = gameLibTexture.magFilter; - instanceMaterial[instanceMaterialMapType].minFilter = gameLibTexture.minFilter; - instanceMaterial[instanceMaterialMapType].mapping = gameLibTexture.mapping; - instanceMaterial[instanceMaterialMapType].mipmaps = gameLibTexture.mipmaps; - instanceMaterial[instanceMaterialMapType].offset = new graphics.instance.Vector2( - gameLibTexture.offset.x, - gameLibTexture.offset.y - ); - instanceMaterial[instanceMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; - instanceMaterial[instanceMaterialMapType].textureType = gameLibTexture.textureType; - instanceMaterial[instanceMaterialMapType].wrapS = gameLibTexture.wrapS; - instanceMaterial[instanceMaterialMapType].wrapT = gameLibTexture.wrapT; - instanceMaterial[instanceMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; - instanceMaterial.needsUpdate = true; - defer.resolve(true); - }, - function(xhr) { - /** - * onProgress - */ - if (progressCallback) { - progressCallback(Math.round(xhr.loaded / xhr.total * 100)); - } - }, - function(error) { - /** - * onError - */ - console.log('Image could not be loaded: ' + imagePath, error); - defer.reject('Image could not be loaded: ' + imagePath); - } - ); + return defer.promise; }; - /** - * Returns an array of image loading Promises - * @param gameLibMaterial - * @param blenderMaps - * @param instanceMaterial + * 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 - * @returns Q[] + * @constructor */ -GameLib.D3.Texture.LoadMaps = function( - gameLibMaterial, - blenderMaps, - instanceMaterial, +GameLib.D3.Texture = function( graphics, uploadUrl, progressCallback ) { - var textureMaps = []; + 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 = []; +}; + + +/** + * 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++) { @@ -328,69 +300,167 @@ GameLib.D3.Texture.LoadMaps = function( blenderTexture.image.filename ) { - var instanceMap = null; + var instanceMapId = null; if (map == 'alpha') { - instanceMap = 'alhpaMap'; + instanceMapId = 'alhpaMap'; } if (map == 'ao') { - instanceMap = 'aoMap'; + instanceMapId = 'aoMap'; } if (map == 'bump') { - instanceMap = 'bumpMap'; + instanceMapId = 'bumpMap'; } if (map == 'displacement') { - instanceMap = 'displacementMap'; + instanceMapId = 'displacementMap'; } if (map == 'emissive') { - instanceMap = 'emissiveMap'; + instanceMapId = 'emissiveMap'; } if (map == 'environment') { - instanceMap = 'envMap'; + instanceMapId = 'envMap'; } if (map == 'light') { - instanceMap = 'lightMap'; + instanceMapId = 'lightMap'; } if (map == 'specular') { - instanceMap = 'specularMap'; + instanceMapId = 'specularMap'; } if (map == 'diffuse') { - instanceMap = 'map'; + instanceMapId = 'map'; } if (map == 'roughness') { - instanceMap = 'roughnessMap'; + instanceMapId = 'roughnessMap'; } if (map == 'metalness') { - instanceMap = 'metalnessMap'; + instanceMapId = 'metalnessMap'; } - if (instanceMap == null) { + if (instanceMapId == null) { console.warn("unsupported map type : " + map); } - textureMaps.push( - GameLib.D3.Texture.LoadMap( - gameLibMaterial.maps[map], + gameLibMaterial.OnImageLoadedCallbacks.push( + new GameLib.D3.Material.ImageLoadedCallback( instanceMaterial, - instanceMap, - graphics, - uploadUrl, - progressCallback + instanceMapId ) ); + + this.notify( + gameLibMaterial, + blenderTexture.image.filename + ); } } } - - return textureMaps; }; + +/** + * 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