Transparency and other updates

This commit is contained in:
Sean Lilley 2017-03-21 14:37:52 -04:00
parent e48320572b
commit 83e7723b1c
8 changed files with 60 additions and 43 deletions

View File

@ -48,7 +48,7 @@ Using obj2gltf as a command-line tool:
|`--cesium`|Optimize the glTF for Cesium by using the sun as a default light source.|No, default `false`|
|`--ao`|Apply ambient occlusion to the converted model.|No, default `false`|
|`--bypassPipeline`|Bypass the gltf-pipeline for debugging purposes. This option overrides many of the options above and will save the glTF with the KHR_materials_common extension.|No, default `false`|
|`--checkTextureAlpha`|Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures with an alpha channel are considered to be transparent.|No, default `false`|
|`--hasTransparency`|Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures with an alpha channel are considered to be transparent.|No, default `false`|
## Build Instructions

View File

@ -80,7 +80,7 @@ var argv = yargs
type: 'boolean',
default: false
},
'checkTextureAlpha': {
'hasTransparency': {
describe: 'Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures with an alpha channel are considered to be transparent.',
type: 'boolean',
default: false
@ -111,7 +111,7 @@ var options = {
ao : argv.ao,
optimizeForCesium : argv.cesium,
bypassPipeline : argv.bypassPipeline,
checkTextureAlpha : argv.checkTextureAlpha
hasTransparency : argv.hasTransparency
};
console.time('Total');

View File

@ -32,7 +32,7 @@ module.exports = convert;
* @param {Boolean} [options.ao=false] Apply ambient occlusion to the converted model.
* @param {Boolean} [options.textureCompressionOptions] Options sent to the compressTextures stage of gltf-pipeline.
* @param {Boolean} [options.bypassPipeline=false] Bypass the gltf-pipeline for debugging purposes. This option overrides many of the options above and will save the glTF with the KHR_materials_common extension.
* @param {Boolean} [options.checkTextureAlpha=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @param {Boolean} [options.hasTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
*/
function convert(objPath, gltfPath, options) {
@ -61,6 +61,10 @@ function convert(objPath, gltfPath, options) {
var extension = path.extname(gltfPath);
if (extension === '.glb') {
binary = true;
if (bypassPipeline) {
console.log('--bypassPipeline does not convert to binary glTF, saving as .gltf');
extension = '.gltf';
}
}
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);

View File

@ -1,11 +1,11 @@
'use strict';
var Cesium = require('cesium');
var fs = require('fs-extra');
var fsExtra = require('fs-extra');
var path = require('path');
var PNG = require('pngjs').PNG;
var Promise = require('bluebird');
var fsReadFile = Promise.promisify(fs.readFile);
var fsExtraReadFile = Promise.promisify(fsExtra.readFile);
var defaultValue = Cesium.defaultValue;
var WebGLConstants = Cesium.WebGLConstants;
@ -17,16 +17,16 @@ module.exports = loadImage;
*
* @param {String} imagePath Path to the image file.
* @param {Object} [options] An object with the following properties:
* @param {Boolean} [options.checkTextureAlpha=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @param {Boolean} [options.hasTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @returns {Promise} A promise resolving to the image information, or undefined if the file doesn't exist.
*
* @private
*/
function loadImage(imagePath, options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var checkTextureAlpha = defaultValue(options.checkTextureAlpha, false);
var hasTransparency = defaultValue(options.hasTransparency, false);
return fsReadFile(imagePath)
return fsExtraReadFile(imagePath)
.then(function(data) {
var extension = path.extname(imagePath);
@ -44,10 +44,13 @@ function loadImage(imagePath, options) {
info.format = getFormat(channels);
if (channels === 4) {
if (checkTextureAlpha) {
info.transparent = isTransparent(data);
} else {
info.transparent = true;
info.transparent = true;
if (hasTransparency) {
return isTransparent(data)
.then(function(transparent) {
info.transparent = transparent;
return info;
});
}
}
}
@ -61,15 +64,22 @@ function loadImage(imagePath, options) {
}
function isTransparent(data) {
var decoded = PNG.sync.read(data);
var pixels = decoded.data;
var pixelsLength = decoded.width * decoded.height;
for (var i = 0; i < pixelsLength; ++i) {
if (pixels[i * 4 + 3] < 255) {
return true;
}
}
return false;
return new Promise(function(resolve, reject) {
new PNG().parse(data, function(error, data) {
if (error) {
reject(error);
}
var pixels = data.data;
var pixelsLength = data.width * data.height;
for (var i = 0; i < pixelsLength; ++i) {
if (pixels[i * 4 + 3] < 255) {
resolve(true);
return;
}
}
resolve(false);
});
});
}
function getChannels(colorType) {

View File

@ -52,7 +52,7 @@ var facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(
*
* @param {String} objPath Path to the obj file.
* @param {Object} [options] An object with the following properties:
* @param {Boolean} [options.checkTextureAlpha=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @param {Boolean} [options.hasTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @returns {Promise} A promise resolving to the obj data.
* @exception {RuntimeError} The file does not have any geometry information in it.
*

View File

@ -52,10 +52,9 @@ function writeUris(gltf, gltfPath, separateBuffers, separateTextures) {
writeEmbeddedTextures(gltf);
}
deleteExtras(gltf);
return Promise.all(promises)
.then(function() {
deleteExtras(gltf);
return gltf;
});
}

View File

@ -57,30 +57,34 @@ describe('gltf', function() {
]).then(done);
});
it('simple gltf', function() {
it('simple gltf', function(done) {
var objData = clone(boxObjData, true);
var gltf = createGltf(objData);
writeUris(gltf, boxGltfUrl, false, false);
expect(gltf).toEqual(boxGltf);
expect(writeUris(gltf, boxGltfUrl, false, false)
.then(function() {
expect(gltf).toEqual(boxGltf);
}), done).toResolve();
});
it('multiple nodes, meshes, and primitives', function() {
it('multiple nodes, meshes, and primitives', function(done) {
var objData = clone(groupObjData, true);
var gltf = createGltf(objData);
writeUris(gltf, groupGltfUrl, false, false);
expect(gltf).toEqual(groupGltf);
expect(Object.keys(gltf.materials).length).toBe(3);
expect(Object.keys(gltf.nodes).length).toBe(1);
expect(Object.keys(gltf.meshes).length).toBe(3);
expect(writeUris(gltf, groupGltfUrl, false, false)
.then(function() {
expect(gltf).toEqual(groupGltf);
expect(Object.keys(gltf.materials).length).toBe(3);
expect(Object.keys(gltf.nodes).length).toBe(1);
expect(Object.keys(gltf.meshes).length).toBe(3);
// Check for two primitives in each mesh
for (var id in gltf.meshes) {
if (gltf.meshes.hasOwnProperty(id)) {
var mesh = gltf.meshes[id];
expect(mesh.primitives.length).toBe(2);
}
}
// Check for two primitives in each mesh
for (var id in gltf.meshes) {
if (gltf.meshes.hasOwnProperty(id)) {
var mesh = gltf.meshes[id];
expect(mesh.primitives.length).toBe(2);
}
}
}), done).toResolve();
});
it('sets default material values', function() {

View File

@ -82,9 +82,9 @@ describe('image', function() {
}), done).toResolve();
});
it('loads image with fully opaque alpha channel with checkTextureAlpha flag', function(done) {
it('loads image with fully opaque alpha channel with hasTransparency flag', function(done) {
var options = {
checkTextureAlpha : true
hasTransparency : true
};
expect(loadImage(opaqueAlphaImage, options)
.then(function(info) {