diff --git a/bin/obj2gltf.js b/bin/obj2gltf.js index b1657a3..a10ff30 100644 --- a/bin/obj2gltf.js +++ b/bin/obj2gltf.js @@ -130,4 +130,7 @@ console.time('Total'); convert(objPath, gltfPath, options) .then(function() { console.timeEnd('Total'); + }) + .catch(function(error) { + console.log(error.message); }); diff --git a/lib/convert.js b/lib/convert.js index 68a83b5..c309067 100644 --- a/lib/convert.js +++ b/lib/convert.js @@ -48,79 +48,92 @@ var defaultLogger = function(message) { * @param {Logger} [options.logger] A callback function for handling logged messages. Defaults to console.log. */ function convert(objPath, gltfPath, options) { - options = defaultValue(options, {}); - var binary = defaultValue(options.binary, false); - var separate = defaultValue(options.separate, false); - var separateTextures = defaultValue(options.separateTextures, false) || separate; - var compress = defaultValue(options.compress, false); - var optimize = defaultValue(options.optimize, false); - var optimizeForCesium = defaultValue(options.optimizeForCesium, false); - var generateNormals = defaultValue(options.generateNormals, false); - var ao = defaultValue(options.ao, false); - var kmc = defaultValue(options.kmc, false); - var textureCompressionOptions = options.textureCompressionOptions; - var bypassPipeline = defaultValue(options.bypassPipeline, false); - var logger = defaultValue(options.logger, defaultLogger); - options.logger = logger; - options.hasTransparency = defaultValue(options.hasTransparency, false); - options.secure = defaultValue(options.secure, false); + return new Promise(function(resolve, reject) { + options = defaultValue(options, {}); + var binary = defaultValue(options.binary, false); + var separate = defaultValue(options.separate, false); + var separateTextures = defaultValue(options.separateTextures, false) || separate; + var compress = defaultValue(options.compress, false); + var optimize = defaultValue(options.optimize, false); + var optimizeForCesium = defaultValue(options.optimizeForCesium, false); + var generateNormals = defaultValue(options.generateNormals, false); + var ao = defaultValue(options.ao, false); + var kmc = defaultValue(options.kmc, false); + var textureCompressionOptions = options.textureCompressionOptions; + var bypassPipeline = defaultValue(options.bypassPipeline, false); + var logger = defaultValue(options.logger, defaultLogger); + options.logger = logger; + options.hasTransparency = defaultValue(options.hasTransparency, false); + options.secure = defaultValue(options.secure, false); - if (!defined(objPath)) { - throw new DeveloperError('objPath is required'); - } - - if (!defined(gltfPath)) { - throw new DeveloperError('gltfPath is required'); - } - - var basePath = path.dirname(gltfPath); - var modelName = path.basename(gltfPath, path.extname(gltfPath)); - var extension = path.extname(gltfPath); - if (extension === '.glb') { - binary = true; - if (bypassPipeline) { - options.logger('--bypassPipeline does not convert to binary glTF, saving as .gltf'); - extension = '.gltf'; + if (!defined(objPath)) { + throw new DeveloperError('objPath is required'); } - } - gltfPath = path.join(path.dirname(gltfPath), modelName + extension); - var aoOptions = ao ? {} : undefined; + if (!defined(gltfPath)) { + throw new DeveloperError('gltfPath is required'); + } - // TODO: gltf-pipeline uses the same kmc options for each material and doesn't recognize the transparent flag - var kmcOptions = kmc ? {} : undefined; + var objExtension = path.extname(objPath).toLowerCase(); + if (objExtension !== '.obj') { + throw new DeveloperError('Invalid obj path "' + objPath + '"'); + } - var pipelineOptions = { - createDirectory : false, - basePath : basePath, - binary : binary, - embed : !separate, - embedImage : !separateTextures, - quantize : compress, - compressTextureCoordinates : compress, - encodeNormals : compress, - preserve : !optimize, - optimizeForCesium : optimizeForCesium, - smoothNormals : generateNormals, - aoOptions : aoOptions, - kmcOptions : kmcOptions, - textureCompressionOptions : textureCompressionOptions - }; + var extension = path.extname(gltfPath).toLowerCase(); + if (extension !== '.gltf' && extension !== '.glb') { + throw new DeveloperError('Invalid gltf path "' + gltfPath + '"'); + } - return loadObj(objPath, options) - .then(function(objData) { - return createGltf(objData); - }) - .then(function(gltf) { - return writeUris(gltf, gltfPath, separate, separateTextures, logger); - }) - .then(function(gltf) { + var basePath = path.dirname(gltfPath); + var modelName = path.basename(gltfPath, path.extname(gltfPath)); + if (extension === '.glb') { + binary = true; if (bypassPipeline) { - return convert._outputJson(gltfPath, gltf); - } else { - return GltfPipeline.processJSONToDisk(gltf, gltfPath, pipelineOptions); + logger('--bypassPipeline does not convert to binary glTF, saving as .gltf'); + extension = '.gltf'; } - }); + } + gltfPath = path.join(path.dirname(gltfPath), modelName + extension); + + var aoOptions = ao ? {} : undefined; + + // TODO: gltf-pipeline uses the same kmc options for each material and doesn't recognize the transparent flag + var kmcOptions = kmc ? {} : undefined; + + var pipelineOptions = { + createDirectory : false, + basePath : basePath, + binary : binary, + embed : !separate, + embedImage : !separateTextures, + quantize : compress, + compressTextureCoordinates : compress, + encodeNormals : compress, + preserve : !optimize, + optimizeForCesium : optimizeForCesium, + smoothNormals : generateNormals, + aoOptions : aoOptions, + kmcOptions : kmcOptions, + textureCompressionOptions : textureCompressionOptions + }; + + return loadObj(objPath, options) + .then(function(objData) { + return createGltf(objData); + }) + .then(function(gltf) { + return writeUris(gltf, gltfPath, separate, separateTextures, logger); + }) + .then(function(gltf) { + if (bypassPipeline) { + return convert._outputJson(gltfPath, gltf); + } else { + return GltfPipeline.processJSONToDisk(gltf, gltfPath, pipelineOptions); + } + }) + .then(resolve) + .catch(reject); + }); } /** diff --git a/specs/lib/convertSpec.js b/specs/lib/convertSpec.js index 7b4fe0e..35fd0eb 100644 --- a/specs/lib/convertSpec.js +++ b/specs/lib/convertSpec.js @@ -1,12 +1,19 @@ 'use strict'; +var Cesium = require('cesium'); var GltfPipeline = require('gltf-pipeline').Pipeline; var path = require('path'); var convert = require('../../lib/convert'); var writeUris = require('../../lib/writeUris'); +var DeveloperError = Cesium.DeveloperError; + var objPath = 'specs/data/box-textured/box-textured.obj'; var gltfPath = 'specs/data/box-textured/box-textured.gltf'; var glbPath = 'specs/data/box-textured/box-textured.glb'; +var objPathInvalid = 'invalid/'; +var gltfPathInvalid = 'invalid/model.invalid'; +var objPathNonExistent = 'specs/data/non-existent.obj'; +var gltfPathNonExistent = 'specs/data/non-existent.gltf'; var objExternalResourcesPath = 'specs/data/box-external-resources/box-external-resources.obj'; @@ -116,7 +123,7 @@ describe('convert', function() { }), done).toResolve(); }); - it('Uses a custom logger', function(done) { + it('uses a custom logger', function(done) { var spy = spyOn(GltfPipeline, 'processJSONToDisk'); var logCount = 0; var options = { @@ -131,15 +138,23 @@ describe('convert', function() { }), done).toResolve(); }); - it('throws if objPath is undefined', function() { - expect(function() { - convert(undefined, gltfPath); - }).toThrowDeveloperError(); + it('rejects if objPath is undefined', function(done) { + expect(convert(undefined, gltfPath), done).toRejectWith(DeveloperError); }); - it('throws if gltfPath is undefined', function() { - expect(function() { - convert(objPath, undefined); - }).toThrowDeveloperError(); + it('rejects if gltfPath is undefined', function(done) { + expect(convert(objPath, undefined), done).toRejectWith(DeveloperError); + }); + + it('rejects if obj path is invalid', function(done) { + expect(convert(objPathInvalid, gltfPath), done).toRejectWith(DeveloperError); + }); + + it('rejects if gltf path is invalid', function(done) { + expect(convert(objPath, gltfPathInvalid), done).toRejectWith(DeveloperError); + }); + + it('rejects if obj path does not exist', function(done) { + expect(convert(objPathNonExistent, gltfPath), done).toRejectWith(Error); }); });