Cleanup overriding images

This commit is contained in:
Sean Lilley 2017-07-28 16:56:28 -04:00
parent e54f3af37f
commit 3da691df62
9 changed files with 227 additions and 147 deletions

View File

@ -131,10 +131,34 @@ if (!defined(gltfPath)) {
gltfPath = path.join(path.dirname(objPath), modelName + extension);
}
var overridingImages = {
metallicRoughnessOcclusionTexture : argv.metallicRoughnessOcclusionTexture,
specularGlossinessTexture : argv.specularGlossinessTexture,
occlusionTexture : argv.occlusionTexture,
normalTexture : argv.normalTexture,
baseColorTexture : argv.baseColorTexture,
emissiveTexture : argv.emissiveTexture
};
var options = {
binary : argv.binary,
separate : argv.separate,
separateTextures : argv.separateTextures,
checkTransparency : argv.checkTransparency,
secure : argv.secure,
inputUpAxis : argv.inputUpAxis,
outputUpAxis : argv.outputUpAxis,
packOcclusion : argv.packOcclusion,
metallicRoughness : argv.metallicRoughness,
specularGlossiness : argv.specularGlossiness,
materialsCommon : argv.materialsCommon,
overridingImages : overridingImages
};
console.time('Total');
try {
obj2gltf(objPath, gltfPath, argv)
obj2gltf(objPath, gltfPath, options)
.then(function() {
console.timeEnd('Total');
})

18
lib/Image.js Normal file
View File

@ -0,0 +1,18 @@
'use strict';
module.exports = Image;
/**
* Stores image data and properties.
*
* @private
*/
function Image() {
this.transparent = false;
this.source = undefined;
this.extension = undefined;
this.path = undefined;
this.decoded = undefined;
this.width = undefined;
this.height = undefined;
}

View File

@ -2,6 +2,7 @@
var Cesium = require('cesium');
var path = require('path');
var getBufferPadded = require('./getBufferPadded');
var Image = require('./Image');
var Material = require('./Material');
var CesiumMath = Cesium.Math;
@ -20,13 +21,13 @@ module.exports = createGltf;
* @param {Boolean} options.metallicRoughness The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} options.specularGlossiness The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} options.materialsCommon The glTF will be saved with the KHR_materials_common extension.
* @param {Object[]} options.overridingImages An array of images that override images in the .mtl file.
* @param {String} [options.metallicRoughnessOcclusionTexture] Path to the metallic-roughness-occlusion texture used by the model, where occlusion is stored in the red channel, roughness is stored in the green channel, and metallic is stored in the blue channel. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. The model will be saved with a pbrMetallicRoughness material.
* @param {String} [options.specularGlossinessTexture] Path to the specular-glossiness texture used by the model, where specular color is stored in the red, green, and blue channels and specular glossiness is stored in the alpha channel. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. The model will be saved with a material using the KHR_materials_pbrSpecularGlossiness extension.
* @param {String} [options.occlusionTexture] Path to the occlusion texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. Ignored if metallicRoughnessOcclusionTexture is also set.
* @param {String} [options.normalTexture] Path to the normal texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {String} [options.baseColorTexture] Path to the baseColor/diffuse texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {String} [options.emissiveTexture] Path to the emissive texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {Object} [options.overridingImages] An object containing image paths that override material values defined in the .mtl file. This is often convenient in workflows where the .mtl does not exist or is not set up to use PBR materials. Intended for models with a single material.
* @param {String} [options.overridingImages.metallicRoughnessOcclusionTexture] Path to the metallic-roughness-occlusion texture, where occlusion is stored in the red channel, roughness is stored in the green channel, and metallic is stored in the blue channel. The model will be saved with a pbrMetallicRoughness material.
* @param {String} [options.overridingImages.specularGlossinessTexture] Path to the specular-glossiness texture, where specular color is stored in the red, green, and blue channels and specular glossiness is stored in the alpha channel. The model will be saved with a material using the KHR_materials_pbrSpecularGlossiness extension.
* @param {String} [options.overridingImages.occlusionTexture] Path to the occlusion texture. Ignored if metallicRoughnessOcclusionTexture is also set.
* @param {String} [options.overridingImages.normalTexture] Path to the normal texture.
* @param {String} [options.overridingImages.baseColorTexture] Path to the baseColor/diffuse texture.
* @param {String} [options.overridingImages.emissiveTexture] Path to the emissive texture.
* @param {Boolean} options.logger A callback function for handling logged messages. Defaults to console.log.
* @returns {Object} A glTF asset.
*
@ -158,9 +159,10 @@ function addBuffers(gltf, bufferState) {
});
}
function getImage(images, imagePath, overrideImagePath, options) {
images = options.overridingImages.concat(images);
imagePath = defaultValue(overrideImagePath, imagePath);
function getImage(images, imagePath, overridingImage) {
if (defined(overridingImage)) {
return overridingImage;
}
var imagesLength = images.length;
for (var i = 0; i < imagesLength; ++i) {
var image = images[i];
@ -383,15 +385,12 @@ function createMetallicRoughnessTexture(gltf, metallicImage, roughnessImage, occ
}
var imageName = imageNames.join('_');
var image = {
transparent : false,
source : undefined,
extension : '.png',
path : imageName,
decoded : pixels,
width : width,
height : height
};
var image = new Image();
image.extension = '.png';
image.path = imageName;
image.decoded = pixels;
image.width = width;
image.height = height;
return getTexture(gltf, image);
}
@ -448,15 +447,12 @@ function createSpecularGlossinessTexture(gltf, specularImage, glossinessImage, o
}
var imageName = imageNames.join('_');
var image = {
transparent : true,
source : undefined,
extension : '.png',
path : imageName,
decoded : pixels,
width : width,
height : height
};
var image = new Image();
image.extension = '.png';
image.path = imageName;
image.decoded = pixels;
image.width = width;
image.height = height;
return getTexture(gltf, image);
}
@ -465,12 +461,13 @@ function createSpecularGlossinessMaterial(gltf, images, material, options) {
var materialName = material.name;
// The texture paths supplied in the .mtl may be overriden by the texture paths supplied in options
var emissiveImage = getImage(images, material.emissiveTexture, options.emissiveTexture, options);
var normalImage = getImage(images, material.normalTexture, options.normalTexture, options);
var occlusionImage = getImage(images, material.ambientTexture, options.occlusionTexture, options);
var diffuseImage = getImage(images, material.diffuseTexture, options.baseColorTexture, options);
var specularImage = getImage(images, material.specularTexture, options.specularGlossinessTexture, options);
var glossinessImage = getImage(images, material.specularShininessTexture, options.specularGlossinessTexture, options);
var overridingImages = options.overridingImages;
var emissiveImage = getImage(images, material.emissiveTexture, overridingImages.emissiveTexture, options);
var normalImage = getImage(images, material.normalTexture, overridingImages.normalTexture, options);
var occlusionImage = getImage(images, material.ambientTexture, overridingImages.occlusionTexture, options);
var diffuseImage = getImage(images, material.diffuseTexture, overridingImages.baseColorTexture, options);
var specularImage = getImage(images, material.specularTexture, overridingImages.specularGlossinessTexture, options);
var glossinessImage = getImage(images, material.specularShininessTexture, overridingImages.specularGlossinessTexture, options);
var emissiveTexture = getTexture(gltf, emissiveImage);
var normalTexture = getTexture(gltf, normalImage);
@ -478,7 +475,7 @@ function createSpecularGlossinessMaterial(gltf, images, material, options) {
var diffuseTexture = getTexture(gltf, diffuseImage);
var specularGlossinessTexture;
if (defined(options.specularGlossinessTexture)) {
if (defined(overridingImages.specularGlossinessTexture)) {
specularGlossinessTexture = getTexture(gltf, specularImage);
} else {
specularGlossinessTexture = createSpecularGlossinessTexture(gltf, specularImage, glossinessImage, options);
@ -542,26 +539,27 @@ function createSpecularGlossinessMaterial(gltf, images, material, options) {
function createMetallicRoughnessMaterial(gltf, images, material, options) {
var materialName = material.name;
// The texture paths supplied in the .mtl may be overriden by the texture paths supplied in options
var emissiveImage = getImage(images, material.emissiveTexture, options.emissiveTexture, options);
var normalImage = getImage(images, material.normalTexture, options.normalTexture, options);
var occlusionImage = getImage(images, material.ambientTexture, options.metallicRoughnessOcclusionTexture, options);
var baseColorImage = getImage(images, material.diffuseTexture, options.baseColorTexture, options);
var metallicImage = getImage(images, material.specularTexture, options.metallicRoughnessOcclusionTexture, options);
var roughnessImage = getImage(images, material.specularShininessTexture, options.metallicRoughnessOcclusionTexture, options);
// The texture paths supplied in the .mtl may be over var overridingImages = options.overridingImages;
var overridingImages = options.overridingImages;
var emissiveImage = getImage(images, material.emissiveTexture, overridingImages.emissiveTexture);
var normalImage = getImage(images, material.normalTexture, overridingImages.normalTexture);
var occlusionImage = getImage(images, material.ambientTexture, overridingImages.metallicRoughnessOcclusionTexture);
var baseColorImage = getImage(images, material.diffuseTexture, overridingImages.baseColorTexture);
var metallicImage = getImage(images, material.specularTexture, overridingImages.metallicRoughnessOcclusionTexture);
var roughnessImage = getImage(images, material.specularShininessTexture, overridingImages.metallicRoughnessOcclusionTexture);
var emissiveTexture = getTexture(gltf, emissiveImage);
var normalTexture = getTexture(gltf, normalImage);
var baseColorTexture = getTexture(gltf, baseColorImage);
var metallicRoughnessTexture;
if (defined(options.metallicRoughnessOcclusionTexture)) {
if (defined(overridingImages.metallicRoughnessOcclusionTexture)) {
metallicRoughnessTexture = getTexture(gltf, metallicImage);
} else {
metallicRoughnessTexture = createMetallicRoughnessTexture(gltf, metallicImage, roughnessImage, occlusionImage, options);
}
var packOcclusion = (defined(occlusionImage) && options.packOcclusion) || defined(options.metallicRoughnessOcclusionTexture);
var packOcclusion = (defined(occlusionImage) && options.packOcclusion) || defined(overridingImages.metallicRoughnessOcclusionTexture);
var occlusionTexture = packOcclusion ? metallicRoughnessTexture : getTexture(gltf, occlusionImage);
var emissiveFactor = getEmissiveFactor(material);

View File

@ -5,6 +5,7 @@ var jpeg = require('jpeg-js');
var path = require('path');
var PNG = require('pngjs').PNG;
var Promise = require('bluebird');
var Image = require('./Image');
var defaultValue = Cesium.defaultValue;
var defined = Cesium.defined;
@ -12,13 +13,13 @@ var defined = Cesium.defined;
module.exports = loadImage;
/**
* Load an image file and get information about it.
* Load an image file.
*
* @param {String} imagePath Path to the image file.
* @param {Object} options An object with the following properties:
* @param {Boolean} [options.checkTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @param {Boolean} [options.decode=false] Decode image.
* @returns {Promise} A promise resolving to the image information, or undefined if the file doesn't exist.
* @returns {Promise} A promise resolving to an Image object.
*
* @private
*/
@ -30,30 +31,29 @@ function loadImage(imagePath, options) {
return fsExtra.readFile(imagePath)
.then(function(data) {
var extension = path.extname(imagePath).toLowerCase();
var image = new Image();
image.source = data;
image.extension = extension;
image.path = imagePath;
var info = {
transparent : false,
source : data,
extension : extension,
path : imagePath,
decoded : undefined,
width : undefined,
height : undefined
};
var decodePromise;
if (extension === '.png') {
return getPngInfo(data, info, options);
decodePromise = decodePng(image, options);
} else if (extension === '.jpg' || extension === '.jpeg') {
return getJpegInfo(data, info, options);
decodePromise = decodeJpeg(image, options);
}
return info;
if (defined(decodePromise)) {
return decodePromise.thenReturn(image);
}
return image;
});
}
function hasTransparency(info) {
var pixels = info.decoded;
var pixelsLength = info.width * info.height;
function hasTransparency(image) {
var pixels = image.decoded;
var pixelsLength = image.width * image.height;
for (var i = 0; i < pixelsLength; ++i) {
if (pixels[i * 4 + 3] < 255) {
return true;
@ -89,35 +89,34 @@ function parsePng(data) {
});
}
function getPngInfo(data, info, options) {
function decodePng(image, options) {
// Color type is encoded in the 25th bit of the png
var colorType = data[25];
var source = image.source;
var colorType = source[25];
var channels = getChannels(colorType);
var checkTransparency = (channels === 4 && options.checkTransparency);
var decode = options.decode || checkTransparency;
if (decode) {
return parsePng(data)
return parsePng(source)
.then(function(decodedResults) {
info.decoded = decodedResults.data;
info.width = decodedResults.width;
info.height = decodedResults.height;
image.decoded = decodedResults.data;
image.width = decodedResults.width;
image.height = decodedResults.height;
if (checkTransparency) {
info.transparent = hasTransparency(info);
image.transparent = hasTransparency(image);
}
return info;
});
}
return info;
}
function getJpegInfo(data, info, options) {
function decodeJpeg(image, options) {
if (options.decode) {
var decodedResults = jpeg.decode(data);
info.decoded = decodedResults.data;
info.width = decodedResults.width;
info.height = decodedResults.height;
var source = image.source;
var decodedResults = jpeg.decode(source);
image.decoded = decodedResults.data;
image.width = decodedResults.width;
image.height = decodedResults.height;
}
return info;
}

View File

@ -11,7 +11,7 @@ module.exports = loadMtl;
* @param {String} mtlPath Path to the mtl file.
* @param {Object} options An object with the following properties:
* @param {Boolean} options.metallicRoughness The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @returns {Promise} A promise resolving to the materials.
* @returns {Promise} A promise resolving to an array of materials.
*
* @private
*/

View File

@ -32,12 +32,13 @@ module.exports = obj2gltf;
* @param {Boolean} [options.metallicRoughness=false] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.specularGlossiness=false] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.materialsCommon=false] The glTF will be saved with the KHR_materials_common extension.
* @param {String} [options.metallicRoughnessOcclusionTexture] Path to the metallic-roughness-occlusion texture used by the model, where occlusion is stored in the red channel, roughness is stored in the green channel, and metallic is stored in the blue channel. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. The model will be saved with a pbrMetallicRoughness material.
* @param {String} [options.specularGlossinessTexture] Path to the specular-glossiness texture used by the model, where specular color is stored in the red, green, and blue channels and specular glossiness is stored in the alpha channel. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. The model will be saved with a material using the KHR_materials_pbrSpecularGlossiness extension.
* @param {String} [options.occlusionTexture] Path to the occlusion texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material. Ignored if metallicRoughnessOcclusionTexture is also set.
* @param {String} [options.normalTexture] Path to the normal texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {String} [options.baseColorTexture] Path to the baseColor/diffuse texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {String} [options.emissiveTexture] Path to the emissive texture used by the model. This may be used instead of setting texture paths in the .mtl file, and is intended for models that use one material.
* @param {Object} [options.overridingImages] An object containing image paths that override material values defined in the .mtl file. This is often convenient in workflows where the .mtl does not exist or is not set up to use PBR materials. Intended for models with a single material.
* @param {String} [options.overridingImages.metallicRoughnessOcclusionTexture] Path to the metallic-roughness-occlusion texture, where occlusion is stored in the red channel, roughness is stored in the green channel, and metallic is stored in the blue channel. The model will be saved with a pbrMetallicRoughness material.
* @param {String} [options.overridingImages.specularGlossinessTexture] Path to the specular-glossiness texture, where specular color is stored in the red, green, and blue channels and specular glossiness is stored in the alpha channel. The model will be saved with a material using the KHR_materials_pbrSpecularGlossiness extension.
* @param {String} [options.overridingImages.occlusionTexture] Path to the occlusion texture. Ignored if metallicRoughnessOcclusionTexture is also set.
* @param {String} [options.overridingImages.normalTexture] Path to the normal texture.
* @param {String} [options.overridingImages.baseColorTexture] Path to the baseColor/diffuse texture.
* @param {String} [options.overridingImages.emissiveTexture] Path to the emissive texture.
* @param {Logger} [options.logger] A callback function for handling logged messages. Defaults to console.log.
* @return {Promise} A promise that resolves when the glTF file is saved.
@ -57,6 +58,7 @@ function obj2gltf(objPath, gltfPath, options) {
var metallicRoughness = defaultValue(options.metallicRoughness, defaults.metallicRoughness);
var specularGlossiness = defaultValue(options.specularGlossiness, defaults.specularGlossiness);
var materialsCommon = defaultValue(options.materialsCommon, defaults.materialsCommon);
var overridingImages = defaultValue(options.overridingImages, defaultValue.EMPTY_OBJECT);
var logger = defaultValue(options.logger, defaults.logger);
options.separate = separate;
@ -69,6 +71,7 @@ function obj2gltf(objPath, gltfPath, options) {
options.metallicRoughness = metallicRoughness;
options.specularGlossiness = specularGlossiness;
options.materialsCommon = materialsCommon;
options.overridingImages = overridingImages;
options.logger = logger;
if (!defined(objPath)) {
@ -83,17 +86,17 @@ function obj2gltf(objPath, gltfPath, options) {
throw new DeveloperError('Only one material type may be set from [--metallicRoughness, --specularGlossiness, --materialsCommon].');
}
if (defined(options.metallicRoughnessOcclusionTexture) && defined(options.specularGlossinessTexture)) {
throw new DeveloperError('options.metallicRoughnessOcclusionTexture and options.specularGlossinessTexture cannot both be defined.');
if (defined(overridingImages.metallicRoughnessOcclusionTexture) && defined(overridingImages.specularGlossinessTexture)) {
throw new DeveloperError('options.overridingImages.metallicRoughnessOcclusionTexture and options.overridingImages.specularGlossinessTexture cannot both be defined.');
}
if (defined(options.metallicRoughnessOcclusionTexture)) {
if (defined(overridingImages.metallicRoughnessOcclusionTexture)) {
options.metallicRoughness = true;
options.specularGlossiness = false;
options.materialsCommon = false;
}
if (defined(options.specularGlossinessTexture)) {
if (defined(overridingImages.specularGlossinessTexture)) {
options.metallicRoughness = false;
options.specularGlossiness = true;
options.materialsCommon = false;
@ -131,17 +134,31 @@ function obj2gltf(objPath, gltfPath, options) {
}
function loadOverridingImages(options) {
// The texture paths supplied in the .mtl may be overriden by the texture path supplied in options
var checkTransparencyOptions = {
var overridingImages = options.overridingImages;
var promises = [];
for (var imageName in overridingImages) {
if (overridingImages.hasOwnProperty(imageName)) {
promises.push(loadOverridingImage(imageName, overridingImages, options));
}
}
return Promise.all(promises);
}
function loadOverridingImage(imageName, overridingImages, options) {
var imagePath = overridingImages[imageName];
var imageOptions;
if (imageName === 'baseColorTexture') {
imageOptions = {
checkTransparency : options.checkTransparency
};
var imagePaths = [options.metallicRoughnessOcclusionTexture, options.specularGlossinessTexture, options.occlusionTexture, options.normalTexture, options.baseColorTexture, options.emissiveTexture];
imagePaths = imagePaths.filter(function(imagePath) {return defined(imagePath);});
return Promise.map(imagePaths, function(imagePath) {
var imageOptions = (imagePath === options.baseColorTexture) ? checkTransparencyOptions : undefined;
return loadImage(imagePath, imageOptions);
}).then(function(images) {
options.overridingImages = images;
}
return loadImage(imagePath, imageOptions)
.then(function(image) {
overridingImages[imageName] = image;
})
.catch(function() {
delete overridingImages[imageName];
options.logger('Could not read image file at ' + imagePath + '. This image will be ignored.');
});
}

View File

@ -21,7 +21,7 @@ var metallicTextureUrl = 'specs/data/box-complex-material/specular.jpeg';
var roughnessTextureUrl = 'specs/data/box-complex-material/shininess.png';
var defaultOptions = clone(obj2gltf.defaults);
defaultOptions.overridingImages = [];
defaultOptions.overridingImages = {};
var checkTransparencyOptions = clone(defaultOptions);
checkTransparencyOptions.checkTransparency = true;
var decodeOptions = clone(defaultOptions);

View File

@ -11,66 +11,66 @@ var transparentImage = 'specs/data/box-complex-material/diffuse.png';
describe('loadImage', function() {
it('loads png image', function(done) {
expect(loadImage(pngImage)
.then(function(info) {
expect(info.transparent).toBe(false);
expect(info.source).toBeDefined();
expect(info.extension).toBe('.png');
expect(info.path).toBe(pngImage);
expect(info.decoded).toBeUndefined();
expect(info.width).toBeUndefined();
expect(info.height).toBeUndefined();
.then(function(image) {
expect(image.transparent).toBe(false);
expect(image.source).toBeDefined();
expect(image.extension).toBe('.png');
expect(image.path).toBe(pngImage);
expect(image.decoded).toBeUndefined();
expect(image.width).toBeUndefined();
expect(image.height).toBeUndefined();
}), done).toResolve();
});
it('loads jpg image', function(done) {
expect(loadImage(jpgImage)
.then(function(info) {
expect(info.transparent).toBe(false);
expect(info.source).toBeDefined();
expect(info.extension).toBe('.jpg');
expect(info.decoded).toBeUndefined();
expect(info.width).toBeUndefined();
expect(info.height).toBeUndefined();
.then(function(image) {
expect(image.transparent).toBe(false);
expect(image.source).toBeDefined();
expect(image.extension).toBe('.jpg');
expect(image.decoded).toBeUndefined();
expect(image.width).toBeUndefined();
expect(image.height).toBeUndefined();
}), done).toResolve();
});
it('loads jpeg image', function(done) {
expect(loadImage(jpegImage)
.then(function(info) {
expect(info.transparent).toBe(false);
expect(info.source).toBeDefined();
expect(info.extension).toBe('.jpeg');
expect(info.decoded).toBeUndefined();
expect(info.width).toBeUndefined();
expect(info.height).toBeUndefined();
.then(function(image) {
expect(image.transparent).toBe(false);
expect(image.source).toBeDefined();
expect(image.extension).toBe('.jpeg');
expect(image.decoded).toBeUndefined();
expect(image.width).toBeUndefined();
expect(image.height).toBeUndefined();
}), done).toResolve();
});
it('loads gif image', function(done) {
expect(loadImage(gifImage)
.then(function(info) {
expect(info.transparent).toBe(false);
expect(info.source).toBeDefined();
expect(info.extension).toBe('.gif');
expect(info.decoded).toBeUndefined();
expect(info.width).toBeUndefined();
expect(info.height).toBeUndefined();
.then(function(image) {
expect(image.transparent).toBe(false);
expect(image.source).toBeDefined();
expect(image.extension).toBe('.gif');
expect(image.decoded).toBeUndefined();
expect(image.width).toBeUndefined();
expect(image.height).toBeUndefined();
}), done).toResolve();
});
it('loads grayscale image', function(done) {
expect(loadImage(grayscaleImage)
.then(function(info) {
expect(info.transparent).toBe(false);
expect(info.source).toBeDefined();
expect(info.extension).toBe('.png');
.then(function(image) {
expect(image.transparent).toBe(false);
expect(image.source).toBeDefined();
expect(image.extension).toBe('.png');
}), done).toResolve();
});
it('loads image with alpha channel', function(done) {
expect(loadImage(transparentImage)
.then(function(info) {
expect(info.transparent).toBe(false);
.then(function(image) {
expect(image.transparent).toBe(false);
}), done).toResolve();
});
@ -80,8 +80,8 @@ describe('loadImage', function() {
};
expect(loadImage(transparentImage, options)
.then(function(info) {
expect(info.transparent).toBe(true);
.then(function(image) {
expect(image.transparent).toBe(true);
}), done).toResolve();
});
@ -91,10 +91,10 @@ describe('loadImage', function() {
};
expect(loadImage(pngImage, options)
.then(function(info) {
expect(info.decoded).toBeDefined();
expect(info.width).toBe(211);
expect(info.height).toBe(211);
.then(function(image) {
expect(image.decoded).toBeDefined();
expect(image.width).toBe(211);
expect(image.height).toBe(211);
}), done).toResolve();
});
@ -104,10 +104,10 @@ describe('loadImage', function() {
};
expect(loadImage(jpegImage, options)
.then(function(info) {
expect(info.decoded).toBeDefined();
expect(info.width).toBe(211);
expect(info.height).toBe(211);
.then(function(image) {
expect(image.decoded).toBeDefined();
expect(image.width).toBe(211);
expect(image.height).toBe(211);
}), done).toResolve();
});
});

View File

@ -9,6 +9,10 @@ var gltfPath = 'specs/data/box-textured/box-textured.gltf';
var glbPath = 'specs/data/box-textured/box-textured.glb';
var objPathNonExistent = 'specs/data/non-existent.obj';
var complexMaterialObjPath = 'specs/data/box-complex-material/box-complex-material.obj';
var complexMaterialGltfPath = 'specs/data/box-complex-material/box-complex-material.gltf';
var textureUrl = 'specs/data/box-textured/cesium.png';
describe('obj2gltf', function() {
beforeEach(function() {
spyOn(fsExtra, 'outputJson').and.returnValue(Promise.resolve());
@ -66,6 +70,26 @@ describe('obj2gltf', function() {
}), done).toResolve();
});
it('sets overriding images', function(done) {
var options = {
overridingImages : {
metallicRoughnessOcclusionTexture : textureUrl,
normalTexture : textureUrl,
baseColorTexture : textureUrl,
emissiveTexture : textureUrl
},
separateTextures : true
};
expect(obj2gltf(complexMaterialObjPath, complexMaterialGltfPath, options)
.then(function() {
var args = fsExtra.outputFile.calls.allArgs();
var length = args.length;
for (var i = 0; i < length; ++i) {
expect(path.basename(args[i][0])).toBe(path.basename(textureUrl));
}
}), done).toResolve();
});
it('rejects if obj path does not exist', function(done) {
expect(obj2gltf(objPathNonExistent, gltfPath), done).toRejectWith(Error);
});