mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2025-02-07 07:22:51 -05:00
Merge pull request #62 from AnalyticalGraphicsInc/single-bin
Don't save out two bins
This commit is contained in:
commit
f9c0e130aa
@ -2,8 +2,10 @@
|
|||||||
var Cesium = require('cesium');
|
var Cesium = require('cesium');
|
||||||
var fsExtra = require('fs-extra');
|
var fsExtra = require('fs-extra');
|
||||||
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
||||||
|
var os = require('os');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var Promise = require('bluebird');
|
var Promise = require('bluebird');
|
||||||
|
var uuid = require('uuid');
|
||||||
var createGltf = require('./createGltf');
|
var createGltf = require('./createGltf');
|
||||||
var loadObj = require('./loadObj');
|
var loadObj = require('./loadObj');
|
||||||
var writeUris = require('./writeUris');
|
var writeUris = require('./writeUris');
|
||||||
@ -77,7 +79,6 @@ function obj2gltf(objPath, gltfPath, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var extension = path.extname(gltfPath).toLowerCase();
|
var extension = path.extname(gltfPath).toLowerCase();
|
||||||
var basePath = path.dirname(gltfPath);
|
|
||||||
var modelName = path.basename(gltfPath, path.extname(gltfPath));
|
var modelName = path.basename(gltfPath, path.extname(gltfPath));
|
||||||
if (extension === '.glb') {
|
if (extension === '.glb') {
|
||||||
binary = true;
|
binary = true;
|
||||||
@ -88,13 +89,14 @@ function obj2gltf(objPath, gltfPath, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);
|
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);
|
||||||
|
var resourcesDirectory = options.bypassPipeline ? path.dirname(gltfPath) : obj2gltf._getTempDirectory();
|
||||||
|
|
||||||
var aoOptions = ao ? {} : undefined;
|
var aoOptions = ao ? {} : undefined;
|
||||||
var kmcOptions = kmc ? {} : undefined;
|
var kmcOptions = kmc ? {} : undefined;
|
||||||
|
|
||||||
var pipelineOptions = {
|
var pipelineOptions = {
|
||||||
createDirectory : false,
|
createDirectory : false,
|
||||||
basePath : basePath,
|
basePath : resourcesDirectory,
|
||||||
binary : binary,
|
binary : binary,
|
||||||
embed : !separate,
|
embed : !separate,
|
||||||
embedImage : !separateTextures,
|
embedImage : !separateTextures,
|
||||||
@ -114,7 +116,7 @@ function obj2gltf(objPath, gltfPath, options) {
|
|||||||
return createGltf(objData);
|
return createGltf(objData);
|
||||||
})
|
})
|
||||||
.then(function(gltf) {
|
.then(function(gltf) {
|
||||||
return writeUris(gltf, gltfPath, options);
|
return writeUris(gltf, gltfPath, resourcesDirectory, options);
|
||||||
})
|
})
|
||||||
.then(function(gltf) {
|
.then(function(gltf) {
|
||||||
if (bypassPipeline) {
|
if (bypassPipeline) {
|
||||||
@ -122,9 +124,21 @@ function obj2gltf(objPath, gltfPath, options) {
|
|||||||
} else {
|
} else {
|
||||||
return GltfPipeline.processJSONToDisk(gltf, gltfPath, pipelineOptions);
|
return GltfPipeline.processJSONToDisk(gltf, gltfPath, pipelineOptions);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
return cleanup(resourcesDirectory, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanup(resourcesDirectory, options) {
|
||||||
|
if (!options.bypassPipeline && options.separate) {
|
||||||
|
fsExtra.remove(resourcesDirectory, function () {
|
||||||
|
// Don't fail simply because we couldn't
|
||||||
|
// clean up the temporary files.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default values that will be used when calling obj2gltf(options) unless specified in the options object.
|
* Default values that will be used when calling obj2gltf(options) unless specified in the options object.
|
||||||
*/
|
*/
|
||||||
@ -229,6 +243,15 @@ obj2gltf.defaults = {
|
|||||||
*/
|
*/
|
||||||
obj2gltf._outputJson = fsExtraOutputJson;
|
obj2gltf._outputJson = fsExtraOutputJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposed for testing
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
obj2gltf._getTempDirectory = function () {
|
||||||
|
return path.join(os.tmpdir(), uuid());
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback function that logs messages.
|
* A callback function that logs messages.
|
||||||
* @callback Logger
|
* @callback Logger
|
||||||
|
@ -16,6 +16,7 @@ module.exports = writeUris;
|
|||||||
*
|
*
|
||||||
* @param {Object} gltf The glTF asset.
|
* @param {Object} gltf The glTF asset.
|
||||||
* @param {String} gltfPath Path where the glTF will be saved.
|
* @param {String} gltfPath Path where the glTF will be saved.
|
||||||
|
* @param {String} resourcesDirectory Path where separate resources will be saved.
|
||||||
* @param {Object} options An object with the following properties:
|
* @param {Object} options An object with the following properties:
|
||||||
* @param {Boolean} options.separate Writes out separate buffers.
|
* @param {Boolean} options.separate Writes out separate buffers.
|
||||||
* @param {Boolean} options.separateTextures Write out separate textures only.
|
* @param {Boolean} options.separateTextures Write out separate textures only.
|
||||||
@ -23,7 +24,7 @@ module.exports = writeUris;
|
|||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function writeUris(gltf, gltfPath, options) {
|
function writeUris(gltf, gltfPath, resourcesDirectory, options) {
|
||||||
var separate = options.separate;
|
var separate = options.separate;
|
||||||
var separateTextures = options.separateTextures;
|
var separateTextures = options.separateTextures;
|
||||||
|
|
||||||
@ -44,17 +45,19 @@ function writeUris(gltf, gltfPath, options) {
|
|||||||
var exceedsMaximum = (texturesByteLength + bufferByteLength > 201326580);
|
var exceedsMaximum = (texturesByteLength + bufferByteLength > 201326580);
|
||||||
|
|
||||||
if (exceedsMaximum && !separate) {
|
if (exceedsMaximum && !separate) {
|
||||||
return Promise.reject(new RuntimeError('Buffers and textures are too large to encode in the glTF, saving as separate resources.'));
|
return Promise.reject(new RuntimeError('Buffers and textures are too large to encode in the glTF. Use the --separate flag instead.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var name = path.basename(gltfPath, path.extname(gltfPath));
|
||||||
|
|
||||||
if (separate) {
|
if (separate) {
|
||||||
promises.push(writeSeparateBuffer(gltf, gltfPath));
|
promises.push(writeSeparateBuffer(gltf, resourcesDirectory, name));
|
||||||
} else {
|
} else {
|
||||||
writeEmbeddedBuffer(gltf);
|
writeEmbeddedBuffer(gltf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (separateTextures) {
|
if (separateTextures) {
|
||||||
promises.push(writeSeparateTextures(gltf, gltfPath));
|
promises.push(writeSeparateTextures(gltf, resourcesDirectory));
|
||||||
} else {
|
} else {
|
||||||
writeEmbeddedTextures(gltf);
|
writeEmbeddedTextures(gltf);
|
||||||
}
|
}
|
||||||
@ -79,24 +82,23 @@ function deleteExtras(gltf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSeparateBuffer(gltf, gltfPath) {
|
function writeSeparateBuffer(gltf, resourcesDirectory, name) {
|
||||||
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
||||||
var source = buffer.extras._obj2gltf.source;
|
var source = buffer.extras._obj2gltf.source;
|
||||||
var bufferName = path.basename(gltfPath, path.extname(gltfPath));
|
var bufferUri = name + '.bin';
|
||||||
var bufferUri = bufferName + '.bin';
|
|
||||||
buffer.uri = bufferUri;
|
buffer.uri = bufferUri;
|
||||||
var bufferPath = path.join(path.dirname(gltfPath), bufferUri);
|
var bufferPath = path.join(resourcesDirectory, bufferUri);
|
||||||
return writeUris._outputFile(bufferPath, source);
|
return writeUris._outputFile(bufferPath, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSeparateTextures(gltf, gltfPath) {
|
function writeSeparateTextures(gltf, resourcesDirectory) {
|
||||||
var images = gltf.images;
|
var images = gltf.images;
|
||||||
return Promise.map(Object.keys(images), function(id) {
|
return Promise.map(Object.keys(images), function(id) {
|
||||||
var image = images[id];
|
var image = images[id];
|
||||||
var extras = image.extras._obj2gltf;
|
var extras = image.extras._obj2gltf;
|
||||||
var imageUri = image.name + extras.extension;
|
var imageUri = image.name + extras.extension;
|
||||||
image.uri = imageUri;
|
image.uri = imageUri;
|
||||||
var imagePath = path.join(path.dirname(gltfPath), imageUri);
|
var imagePath = path.join(resourcesDirectory, imageUri);
|
||||||
return writeUris._outputFile(imagePath, extras.source);
|
return writeUris._outputFile(imagePath, extras.source);
|
||||||
}, {concurrency : 10});
|
}, {concurrency : 10});
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"gltf-pipeline": "^0.1.0-alpha11",
|
"gltf-pipeline": "^0.1.0-alpha11",
|
||||||
"mime": "^1.3.4",
|
"mime": "^1.3.4",
|
||||||
"pngjs": "^3.0.1",
|
"pngjs": "^3.0.1",
|
||||||
|
"uuid": "^3.0.1",
|
||||||
"yargs": "^7.0.1"
|
"yargs": "^7.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -70,7 +70,7 @@ describe('createGltf', function() {
|
|||||||
|
|
||||||
it('simple gltf', function(done) {
|
it('simple gltf', function(done) {
|
||||||
var gltf = createGltf(boxObjData);
|
var gltf = createGltf(boxObjData);
|
||||||
expect(writeUris(gltf, boxGltfUrl, defaultOptions)
|
expect(writeUris(gltf, boxGltfUrl, path.dirname(boxGltfUrl), defaultOptions)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
expect(gltf).toEqual(boxGltf);
|
expect(gltf).toEqual(boxGltf);
|
||||||
}), done).toResolve();
|
}), done).toResolve();
|
||||||
@ -79,7 +79,7 @@ describe('createGltf', function() {
|
|||||||
it('multiple nodes, meshes, and primitives', function(done) {
|
it('multiple nodes, meshes, and primitives', function(done) {
|
||||||
var gltf = createGltf(groupObjData);
|
var gltf = createGltf(groupObjData);
|
||||||
|
|
||||||
expect(writeUris(gltf, groupGltfUrl, defaultOptions)
|
expect(writeUris(gltf, groupGltfUrl, path.dirname(groupGltfUrl), defaultOptions)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
expect(gltf).toEqual(groupGltf);
|
expect(gltf).toEqual(groupGltf);
|
||||||
expect(Object.keys(gltf.materials).length).toBe(3);
|
expect(Object.keys(gltf.materials).length).toBe(3);
|
||||||
|
@ -64,6 +64,10 @@ function getImagePath(objPath, relativePath) {
|
|||||||
var defaultOptions = obj2gltf.defaults;
|
var defaultOptions = obj2gltf.defaults;
|
||||||
|
|
||||||
describe('loadObj', function() {
|
describe('loadObj', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
spyOn(console, 'log');
|
||||||
|
});
|
||||||
|
|
||||||
it('loads obj with positions, normals, and uvs', function(done) {
|
it('loads obj with positions, normals, and uvs', function(done) {
|
||||||
expect(loadObj(objUrl, defaultOptions)
|
expect(loadObj(objUrl, defaultOptions)
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
@ -272,7 +276,6 @@ describe('loadObj', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('loads obj with missing mtllib', function(done) {
|
it('loads obj with missing mtllib', function(done) {
|
||||||
spyOn(console, 'log');
|
|
||||||
expect(loadObj(objMissingMtllibUrl, defaultOptions)
|
expect(loadObj(objMissingMtllibUrl, defaultOptions)
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
expect(data.materials).toEqual({});
|
expect(data.materials).toEqual({});
|
||||||
@ -290,8 +293,6 @@ describe('loadObj', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not load resources outside of the obj directory when secure is true', function(done) {
|
it('does not load resources outside of the obj directory when secure is true', function(done) {
|
||||||
spyOn(console, 'log');
|
|
||||||
|
|
||||||
var options = clone(defaultOptions);
|
var options = clone(defaultOptions);
|
||||||
options.secure = true;
|
options.secure = true;
|
||||||
|
|
||||||
@ -316,7 +317,6 @@ describe('loadObj', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('loads obj with missing texture', function(done) {
|
it('loads obj with missing texture', function(done) {
|
||||||
spyOn(console, 'log');
|
|
||||||
expect(loadObj(objMissingTextureUrl, defaultOptions)
|
expect(loadObj(objMissingTextureUrl, defaultOptions)
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
var imagePath = getImagePath(objMissingTextureUrl, 'cesium.png');
|
var imagePath = getImagePath(objMissingTextureUrl, 'cesium.png');
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var fsExtra = require('fs-extra');
|
||||||
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
||||||
|
var os = require('os');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
var Promise = require('bluebird');
|
||||||
var obj2gltf = require('../../lib/obj2gltf');
|
var obj2gltf = require('../../lib/obj2gltf');
|
||||||
var writeUris = require('../../lib/writeUris');
|
var writeUris = require('../../lib/writeUris');
|
||||||
|
|
||||||
@ -10,28 +13,34 @@ var glbPath = 'specs/data/box-textured/box-textured.glb';
|
|||||||
var objPathNonExistent = 'specs/data/non-existent.obj';
|
var objPathNonExistent = 'specs/data/non-existent.obj';
|
||||||
|
|
||||||
describe('obj2gltf', function() {
|
describe('obj2gltf', function() {
|
||||||
|
var tempDirectory;
|
||||||
|
|
||||||
|
beforeAll(function() {
|
||||||
|
expect(obj2gltf._getTempDirectory()).toContain(os.tmpdir());
|
||||||
|
tempDirectory = path.join(os.tmpdir(), 'testPath');
|
||||||
|
spyOn(obj2gltf, '_getTempDirectory').and.returnValue(tempDirectory);
|
||||||
|
spyOn(obj2gltf, '_outputJson');
|
||||||
|
spyOn(writeUris, '_outputFile');
|
||||||
|
spyOn(fsExtra, 'remove');
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
spyOn(GltfPipeline, 'processJSONToDisk').and.returnValue(Promise.resolve());
|
||||||
|
});
|
||||||
|
|
||||||
it('converts an obj to gltf', function(done) {
|
it('converts an obj to gltf', function(done) {
|
||||||
var spy = spyOn(GltfPipeline, 'processJSONToDisk');
|
|
||||||
expect(obj2gltf(objPath, gltfPath)
|
expect(obj2gltf(objPath, gltfPath)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var args = spy.calls.first().args;
|
var args = GltfPipeline.processJSONToDisk.calls.first().args;
|
||||||
var gltf = args[0];
|
var gltf = args[0];
|
||||||
var outputPath = args[1];
|
var outputPath = args[1];
|
||||||
|
var options = args[2];
|
||||||
expect(path.normalize(outputPath)).toEqual(path.normalize(gltfPath));
|
expect(path.normalize(outputPath)).toEqual(path.normalize(gltfPath));
|
||||||
expect(gltf).toBeDefined();
|
expect(gltf).toBeDefined();
|
||||||
expect(gltf.images.cesium).toBeDefined();
|
expect(gltf.images.cesium).toBeDefined();
|
||||||
}), done).toResolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses default gltf-pipeline options', function(done) {
|
|
||||||
var spy = spyOn(GltfPipeline, 'processJSONToDisk');
|
|
||||||
expect(obj2gltf(objPath, gltfPath)
|
|
||||||
.then(function() {
|
|
||||||
var args = spy.calls.first().args;
|
|
||||||
var options = args[2];
|
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
|
basePath : tempDirectory,
|
||||||
createDirectory : false,
|
createDirectory : false,
|
||||||
basePath : path.dirname(objPath),
|
|
||||||
binary : false,
|
binary : false,
|
||||||
embed : true,
|
embed : true,
|
||||||
embedImage : true,
|
embedImage : true,
|
||||||
@ -49,8 +58,6 @@ describe('obj2gltf', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets options', function(done) {
|
it('sets options', function(done) {
|
||||||
var spy = spyOn(GltfPipeline, 'processJSONToDisk');
|
|
||||||
spyOn(writeUris, '_outputFile');
|
|
||||||
var textureCompressionOptions = {
|
var textureCompressionOptions = {
|
||||||
format : 'dxt1',
|
format : 'dxt1',
|
||||||
quality : 10
|
quality : 10
|
||||||
@ -75,11 +82,11 @@ describe('obj2gltf', function() {
|
|||||||
|
|
||||||
expect(obj2gltf(objPath, gltfPath, options)
|
expect(obj2gltf(objPath, gltfPath, options)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var args = spy.calls.first().args;
|
var args = GltfPipeline.processJSONToDisk.calls.first().args;
|
||||||
var options = args[2];
|
var options = args[2];
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
|
basePath : tempDirectory,
|
||||||
createDirectory : false,
|
createDirectory : false,
|
||||||
basePath : path.dirname(objPath),
|
|
||||||
binary : true,
|
binary : true,
|
||||||
embed : false,
|
embed : false,
|
||||||
embedImage : false,
|
embedImage : false,
|
||||||
@ -98,18 +105,15 @@ describe('obj2gltf', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('saves as binary if gltfPath has a .glb extension', function(done) {
|
it('saves as binary if gltfPath has a .glb extension', function(done) {
|
||||||
var spy = spyOn(GltfPipeline, 'processJSONToDisk');
|
|
||||||
expect(obj2gltf(objPath, glbPath)
|
expect(obj2gltf(objPath, glbPath)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var args = spy.calls.first().args;
|
var args = GltfPipeline.processJSONToDisk.calls.first().args;
|
||||||
var options = args[2];
|
var options = args[2];
|
||||||
expect(options.binary).toBe(true);
|
expect(options.binary).toBe(true);
|
||||||
}), done).toResolve();
|
}), done).toResolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('bypassPipeline flag bypasses gltf-pipeline', function(done) {
|
it('bypassPipeline flag bypasses gltf-pipeline', function(done) {
|
||||||
spyOn(obj2gltf, '_outputJson');
|
|
||||||
spyOn(GltfPipeline, 'processJSONToDisk');
|
|
||||||
var options = {
|
var options = {
|
||||||
bypassPipeline : true
|
bypassPipeline : true
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user