Skip to content

Commit

Permalink
Output separate resources even when --bypassPipeline is set
Browse files Browse the repository at this point in the history
  • Loading branch information
lilleyse committed Mar 14, 2017
1 parent cf27c8b commit 41956dd
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`|
Expand Down
4 changes: 2 additions & 2 deletions bin/obj2gltf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
82 changes: 64 additions & 18 deletions lib/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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) {
Expand All @@ -97,27 +97,73 @@ function convert(objPath, gltfPath, options) {
});
}

/**
* Exposed for testing
*
* @private
*/
convert._outputJson = fsExtraOutputJson;

function saveExternalBuffer(gltf, gltfPath) {
function deleteExtras(gltf) {
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
if (defined(buffer.uri)) {
return Promise.resolve(gltf);
delete buffer.extras;

var images = gltf.images;
for (var id in images) {
if (images.hasOwnProperty(id)) {
var image = images[id];
delete image.extras;
}
}
}

var binary = buffer.extras._obj2gltf.binary;
delete buffer.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 fxExtraOutputFile(bufferPath, binary)
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
*
* @private
*/
convert._outputJson = fsExtraOutputJson;

/**
* Exposed for testing
*
* @private
*/
convert._outputFile = fsExtraOutputFile;
24 changes: 13 additions & 11 deletions lib/gltf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -312,7 +318,12 @@ function createGltf(objData) {

gltf.buffers[bufferId] = {
byteLength : buffer.byteLength,
uri : bufferUri
uri : bufferUri,
extras : {
_obj2gltf : {
source : buffer
}
}
};

gltf.bufferViews[vertexBufferViewId] = {
Expand All @@ -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;
}
3 changes: 2 additions & 1 deletion lib/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ function loadImage(imagePath) {
channels : 3,
data : data,
uri : uri,
format : getFormat(3)
format : getFormat(3),
extension : extension
};

if (extension === '.png') {
Expand Down
6 changes: 4 additions & 2 deletions specs/lib/convertSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -83,6 +84,7 @@ describe('convert', function() {
textureCompressionOptions : textureCompressionOptions,
preserve : false
});
expect(spy2.calls.count()).toBe(2); // Saves out .png and .bin
}), done).toResolve();
});

Expand Down
15 changes: 15 additions & 0 deletions specs/lib/gltfSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 41956dd

Please sign in to comment.