Output separate resources even when --bypassPipeline is set

This commit is contained in:
Sean Lilley 2017-03-14 16:42:42 -04:00
parent cf27c8b69d
commit 41956dd70d
7 changed files with 105 additions and 39 deletions

View File

@ -40,7 +40,7 @@ Using obj2gltf as a command-line tool:
|`-i`|Path to the obj file.| :white_check_mark: Yes|
|`-o`|Path of the converted glTF file.|No|
|`-b`|Save as binary glTF.|No, default `false`|
|`-s`|Writes out separate geometry/animation data files, shader files, and textures instead of embedding them in the glTF file.|No, default `false`|
|`-s`|Writes out separate geometry data files, shader files, and textures instead of embedding them in the glTF file.|No, default `false`|
|`-t`|Write out separate textures only.|No, default `false`|
|`-c`|Quantize positions, compress texture coordinates, and oct-encode normals.|No, default `false`|
|`-z`|Use the optimization stages in the glTF pipeline.|No, default `false`|

View File

@ -37,11 +37,11 @@ var argv = yargs
},
'separate': {
alias: 's',
describe: 'Write separate geometry/animation data files, shader files, and textures instead of embedding them in the glTF.',
describe: 'Write separate geometry data files, shader files, and textures instead of embedding them in the glTF.',
type: 'boolean',
default: false
},
'separateTexture': {
'separateTextures': {
alias: 't',
describe: 'Write out separate textures only.',
type: 'boolean',

View File

@ -7,7 +7,7 @@ var Promise = require('bluebird');
var createGltf = require('./gltf');
var loadObj = require('./obj');
var fxExtraOutputFile = Promise.promisify(fsExtra.outputFile);
var fsExtraOutputFile = Promise.promisify(fsExtra.outputFile);
var fsExtraOutputJson = Promise.promisify(fsExtra.outputJson);
var defaultValue = Cesium.defaultValue;
@ -23,7 +23,7 @@ module.exports = convert;
* @param {String} gltfPath Path of the converted glTF file.
* @param {Object} [options] An object with the following properties:
* @param {Boolean} [options.binary=false] Save as binary glTF.
* @param {Boolean} [options.separate=false] Writes out separate geometry/animation data files, shader files, and textures instead of embedding them in the glTF.
* @param {Boolean} [options.separate=false] Writes out separate geometry data files, shader files, and textures instead of embedding them in the glTF.
* @param {Boolean} [options.separateTextures=false] Write out separate textures only.
* @param {Boolean} [options.compress=false] Quantize positions, compress texture coordinates, and oct-encode normals.
* @param {Boolean} [options.optimize=false] Use the optimization stages in the glTF pipeline.
@ -38,7 +38,7 @@ function convert(objPath, gltfPath, options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var binary = defaultValue(options.binary, false);
var separate = defaultValue(options.separate, false);
var separateTextures = defaultValue(options.separateTextures, 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);
@ -70,7 +70,7 @@ function convert(objPath, gltfPath, options) {
basePath : basePath,
binary : binary,
embed : !separate,
embedImage : !separate && !separateTextures,
embedImage : !separateTextures,
quantize : compress,
compressTextureCoordinates : compress,
encodeNormals : compress,
@ -86,7 +86,7 @@ function convert(objPath, gltfPath, options) {
return createGltf(objData);
})
.then(function(gltf) {
return saveExternalBuffer(gltf, gltfPath);
return writeSeparateResources(gltf, gltfPath, separate, separateTextures);
})
.then(function(gltf) {
if (bypassPipeline) {
@ -97,6 +97,63 @@ function convert(objPath, gltfPath, options) {
});
}
function deleteExtras(gltf) {
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
delete buffer.extras;
var images = gltf.images;
for (var id in images) {
if (images.hasOwnProperty(id)) {
var image = images[id];
delete image.extras;
}
}
}
function writeSeparateBuffer(gltf, gltfPath) {
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
var source = buffer.extras._obj2gltf.source;
var bufferName = path.basename(gltfPath, path.extname(gltfPath));
var bufferUri = bufferName + '.bin';
buffer.uri = bufferUri;
var bufferPath = path.join(path.dirname(gltfPath), bufferUri);
return convert._outputFile(bufferPath, source);
}
function writeSeparateTextures(gltf, gltfPath) {
var promises = [];
var images = gltf.images;
for (var id in images) {
if (images.hasOwnProperty(id)) {
var image = images[id];
var extras = image.extras._obj2gltf;
var imageUri = image.name + extras.extension;
image.uri = imageUri;
var imagePath = path.join(path.dirname(gltfPath), imageUri);
promises.push(convert._outputFile(imagePath, extras.source));
}
}
return Promise.all(promises);
}
function writeSeparateResources(gltf, gltfPath, separate, separateTextures) {
var promises = [];
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
if (separate || !defined(buffer.uri)) {
promises.push(writeSeparateBuffer(gltf, gltfPath));
}
if (separateTextures) {
promises.push(writeSeparateTextures(gltf, gltfPath));
}
deleteExtras(gltf);
return Promise.all(promises)
.then(function() {
return gltf;
});
}
/**
* Exposed for testing
*
@ -104,20 +161,9 @@ function convert(objPath, gltfPath, options) {
*/
convert._outputJson = fsExtraOutputJson;
function saveExternalBuffer(gltf, gltfPath) {
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
if (defined(buffer.uri)) {
return Promise.resolve(gltf);
}
var binary = buffer.extras._obj2gltf.binary;
delete buffer.extras;
var bufferName = path.basename(gltfPath, path.extname(gltfPath));
var bufferUri = bufferName + '.bin';
buffer.uri = bufferUri;
var bufferPath = path.join(path.dirname(gltfPath), bufferUri);
return fxExtraOutputFile(bufferPath, binary)
.then(function() {
return gltf;
});
}
/**
* Exposed for testing
*
* @private
*/
convert._outputFile = fsExtraOutputFile;

View File

@ -130,7 +130,13 @@ function createGltf(objData) {
gltf.images[imageId] = {
name : imageId,
uri : image.uri
uri : image.uri,
extras : {
_obj2gltf : {
source : image.data,
extension : image.extension
}
}
};
gltf.textures[textureId] = {
format : image.format,
@ -312,7 +318,12 @@ function createGltf(objData) {
gltf.buffers[bufferId] = {
byteLength : buffer.byteLength,
uri : bufferUri
uri : bufferUri,
extras : {
_obj2gltf : {
source : buffer
}
}
};
gltf.bufferViews[vertexBufferViewId] = {
@ -329,14 +340,5 @@ function createGltf(objData) {
target : WebGLConstants.ELEMENT_ARRAY_BUFFER
};
// Save the binary to be outputted as a .bin file in convert.js.
if (!defined(bufferUri)) {
gltf.buffers[bufferId].extras = {
_obj2gltf : {
binary : buffer
}
};
}
return gltf;
}

View File

@ -30,7 +30,8 @@ function loadImage(imagePath) {
channels : 3,
data : data,
uri : uri,
format : getFormat(3)
format : getFormat(3),
extension : extension
};
if (extension === '.png') {

View File

@ -47,7 +47,8 @@ describe('convert', function() {
});
it('sets options', function(done) {
var spy = spyOn(GltfPipeline, 'processJSONToDisk');
var spy1 = spyOn(GltfPipeline, 'processJSONToDisk');
var spy2 = spyOn(convert, '_outputFile');
var textureCompressionOptions = {
format : 'dxt1',
quality : 10
@ -66,7 +67,7 @@ describe('convert', function() {
expect(convert(objPath, gltfPath, options)
.then(function() {
var args = spy.calls.first().args;
var args = spy1.calls.first().args;
var options = args[2];
expect(options).toEqual({
createDirectory : false,
@ -83,6 +84,7 @@ describe('convert', function() {
textureCompressionOptions : textureCompressionOptions,
preserve : false
});
expect(spy2.calls.count()).toBe(2); // Saves out .png and .bin
}), done).toResolve();
});

View File

@ -19,6 +19,19 @@ var groupGltfUrl = 'specs/data/box-objects-groups-materials/box-objects-groups-m
var diffuseTextureUrl = 'specs/data/box-textured/cesium.png';
var transparentDiffuseTextureUrl = 'specs/data/box-complex-material/diffuse.png';
function deleteExtras(gltf) {
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
delete buffer.extras;
var images = gltf.images;
for (var id in images) {
if (images.hasOwnProperty(id)) {
var image = images[id];
delete image.extras;
}
}
}
describe('gltf', function() {
var boxObjData;
var groupObjData;
@ -59,12 +72,14 @@ describe('gltf', function() {
it('simple gltf', function() {
var objData = clone(boxObjData, true);
var gltf = createGltf(objData);
deleteExtras(gltf);
expect(gltf).toEqual(boxGltf);
});
it('multiple nodes, meshes, and primitives', function() {
var objData = clone(groupObjData, true);
var gltf = createGltf(objData);
deleteExtras(gltf);
expect(gltf).toEqual(groupGltf);
expect(Object.keys(gltf.materials).length).toBe(3);