mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2024-11-23 16:44:05 -05:00
126 lines
3.8 KiB
JavaScript
126 lines
3.8 KiB
JavaScript
'use strict';
|
|
var fsExtra = require('fs-extra');
|
|
var mime = require('mime');
|
|
var path = require('path');
|
|
var Promise = require('bluebird');
|
|
|
|
var fsExtraOutputFile = Promise.promisify(fsExtra.outputFile);
|
|
|
|
module.exports = writeUris;
|
|
|
|
/**
|
|
* Write glTF resources as embedded data uris or external files.
|
|
*
|
|
* @param {Object} gltf The glTF asset.
|
|
* @param {String} gltfPath Path where the glTF will be saved.
|
|
* @param {Boolean} separateBuffers Writes out separate buffers.
|
|
* @param {Boolean} separateTextures Writes out separate textures.
|
|
* @returns {Promise} A promise that resolves to the glTF asset.
|
|
*
|
|
* @private
|
|
*/
|
|
function writeUris(gltf, gltfPath, separateBuffers, separateTextures) {
|
|
var promises = [];
|
|
|
|
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
|
var bufferByteLength = buffer.extras._obj2gltf.source.length;
|
|
|
|
var texturesByteLength = 0;
|
|
var images = gltf.images;
|
|
for (var id in images) {
|
|
if (images.hasOwnProperty(id)) {
|
|
texturesByteLength += images[id].extras._obj2gltf.source.length;
|
|
}
|
|
}
|
|
|
|
// Buffers larger than ~192MB cannot be base64 encoded due to a NodeJS limitation. Source: https://github.com/nodejs/node/issues/4266
|
|
var exceedsMaximum = (texturesByteLength + bufferByteLength > 201326580);
|
|
|
|
if (exceedsMaximum) {
|
|
console.log('Buffers and textures are too large to encode in the glTF, saving as separate resources.');
|
|
}
|
|
|
|
if (separateBuffers || exceedsMaximum) {
|
|
promises.push(writeSeparateBuffer(gltf, gltfPath));
|
|
} else {
|
|
writeEmbeddedBuffer(gltf);
|
|
}
|
|
|
|
if (separateTextures || exceedsMaximum) {
|
|
promises.push(writeSeparateTextures(gltf, gltfPath));
|
|
} else {
|
|
writeEmbeddedTextures(gltf);
|
|
}
|
|
|
|
return Promise.all(promises)
|
|
.then(function() {
|
|
deleteExtras(gltf);
|
|
return gltf;
|
|
});
|
|
}
|
|
|
|
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 writeUris._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(writeUris._outputFile(imagePath, extras.source));
|
|
}
|
|
}
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
function writeEmbeddedBuffer(gltf) {
|
|
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
|
var source = buffer.extras._obj2gltf.source;
|
|
buffer.uri = 'data:application/octet-stream;base64,' + source.toString('base64');
|
|
}
|
|
|
|
function writeEmbeddedTextures(gltf) {
|
|
var promises = [];
|
|
var images = gltf.images;
|
|
for (var id in images) {
|
|
if (images.hasOwnProperty(id)) {
|
|
var image = images[id];
|
|
var extras = image.extras._obj2gltf;
|
|
image.uri = 'data:' + mime.lookup(extras.extension) + ';base64,' + extras.source.toString('base64');
|
|
}
|
|
}
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
/**
|
|
* Exposed for testing.
|
|
*
|
|
* @private
|
|
*/
|
|
writeUris._outputFile = fsExtraOutputFile;
|