Skip to content

Commit

Permalink
Started tests for writeResources, improved naming of external resources
Browse files Browse the repository at this point in the history
  • Loading branch information
lilleyse committed Apr 23, 2018
1 parent 7c220f0 commit c803238
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 17 deletions.
7 changes: 4 additions & 3 deletions bin/gltf-pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ var inputPath = argv.input;
var outputPath = argv.output;

var inputDirectory = path.dirname(inputPath);
var inputName = path.basename(inputPath, path.extname(inputPath));
var inputExtension = path.extname(inputPath).toLowerCase();
if (inputExtension !== '.gltf' && inputExtension !== '.glb') {
console.log('Error: unrecognized file extension "' + inputExtension + '".');
Expand All @@ -98,12 +99,11 @@ if (!defined(outputPath)) {
} else {
outputExtension = inputExtension;
}
var inputName = path.basename(inputPath, inputExtension);
outputPath = path.join(inputDirectory, inputName + '-processed' + outputExtension);
}

var outputDirectory = path.dirname(outputPath);
outputExtension = path.extname(outputPath).toLowerCase();
var outputName = path.basename(outputPath, outputExtension);
if (outputExtension !== '.gltf' && outputExtension !== '.glb') {
console.log('Error: unrecognized file extension "' + outputExtension + '".');
return;
Expand All @@ -115,7 +115,8 @@ var options = {
separateTextures : argv.separateTextures,
secure : argv.secure,
checkTransparency : argv.checkTransparency,
stats : argv.stats
stats : argv.stats,
name : outputName
};

var inputIsBinary = inputExtension === '.glb';
Expand Down
1 change: 0 additions & 1 deletion lib/addPipelineExtras.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ module.exports = addPipelineExtras;
* @private
*/
function addPipelineExtras(gltf) {
// TODO KHR_technique_webgl
ForEach.shaderLegacy(gltf, function(shader) {
addExtras(shader);
});
Expand Down
1 change: 1 addition & 0 deletions lib/processGltf.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = processGltf;
* @param {Object} gltf A javascript object containing a glTF asset.
* @param {Object} [options] An object with the following properties:
* @param {String} [options.resourceDirectory] The path for reading separate resources.
* @param {String} [options.name] The name of the glTF asset, for writing separate resources.
* @param {Boolean} [options.separate = false] Write separate buffers, shaders, and textures instead of embedding them in the glTF.
* @param {Boolean} [options.separateTextures = false] Write out separate textures only.
* @param {Boolean} [options.checkTransparency = false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
Expand Down
5 changes: 5 additions & 0 deletions lib/readResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ function readFile(object, uri, options) {
absolutePath = path.join(resourceDirectory, uri);
}

if (!defined(object.name)) {
var extension = path.extname(uri);
object.name = path.basename(uri, extension);
}

object.extras._pipeline.absolutePath = absolutePath;
object.extras._pipeline.relativePath = relativePath;
return fsExtra.readFile(absolutePath);
Expand Down
85 changes: 74 additions & 11 deletions lib/writeResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Jimp.prototype.getBufferAsync = Promise.promisify(Jimp.prototype.getBuffer);

var defaultValue = Cesium.defaultValue;
var defined = Cesium.defined;
var WebGLConstants = Cesium.WebGLConstants;

// .crn (Crunch) is not a supported mime type, so add it
mime.define({'image/crn': ['crn']}, true);
Expand All @@ -20,17 +21,23 @@ mime.define({'text/plain': ['glsl']}, true);

module.exports = writeResources;


// TODO : need to supply a name here so that resources are saved.
// Command line can pass the name through easily, but programmatically will need to be done with processGltf kind
// of like how it has resourceDirectory

/**
* Write glTF resources as data uris, buffer views, or files.
*
* @param {Object} gltf A javascript object containing a glTF asset.
* @param {Object} options Object with the following properties:
* @param {Object} options.externalResources A dictionary containing external resources.
* @param {Object} [options] Object with the following properties:
* @param {String} [options.name] The name of the glTF asset, for writing separate resources.
* @param {Boolean} [options.separateBuffers=false] Whether to save buffers as separate files.
* @param {Boolean} [options.separateShaders=false] Whether to save shaders as separate files.
* @param {Boolean} [options.separateTextures=false] Whether to save images as separate files.
* @param {Boolean} [options.dataUris=false] Write embedded resources as data uris instead of buffer views.
* @param {Object} [options.bufferStorage] When defined, the glTF buffer's underlying Buffer object will be saved here instead of encoded as a data uri.
* @param {Object} [options.bufferStorage] When defined, the glTF buffer's underlying Buffer object will be saved here instead of encoded as a data uri or saved as an external resource.
* @param {Object} [options.externalResources] When defined, buffers of separate resources will be saved here.
* @returns {Promise} A promise that resolves to the glTF asset.
*
* @private
Expand Down Expand Up @@ -94,7 +101,7 @@ function writeShader(gltf, shader, i, options) {

function writeResource(gltf, object, index, separate, dataUris, extension, options) {
if (separate) {
return writeFile(object, index, extension, options);
return writeFile(gltf, object, index, extension, options);
} else if (dataUris) {
return Promise.resolve(writeDataUri(object, extension));
}
Expand Down Expand Up @@ -137,18 +144,74 @@ function writeBufferView(gltf, object) {
});
}

function writeFile(object, index, extension, options) {
delete object.bufferView;
function getProgram(gltf, shaderIndex) {
ForEach.program(gltf, function(program, index) {
if (program.fragmentShader === shaderIndex || program.vertexShader === shaderIndex) {
return {
program : program,
index : index
};
}
});
}

function getName(gltf, object, index, extension, options) {
var gltfName = options.name;
var objectName = object.name;

if (defined(objectName)) {
return objectName;
} else if (extension === '.bin') {
if (defined(gltfName)) {
return gltfName;
}
return 'buffer';
} else if (extension === '.glsl') {
var programInfo = getProgram(gltf, index);
var program = programInfo.program;
var programIndex = programInfo.index;
var programName = program.name;
var shaderType = object.type === WebGLConstants.FRAGMENT_SHADER ? 'FS' : 'VS';
if (defined(programName)) {
return programName + shaderType;
} else if (defined(gltfName)) {
return gltfName + shaderType + programIndex;
}
return shaderType.toLowerCase() + programIndex;
}

// Otherwise is an image
if (defined(gltfName)) {
return gltfName + index;
}
return 'image' + index;
}

function getRelativePath(gltf, object, index, extension, options) {
var pipelineExtras = object.extras._pipeline;
var source = pipelineExtras.source;
var relativePath = pipelineExtras.relativePath;
if (defined(relativePath)) {
return relativePath.replace(/\\/g, '/');
}

if (!defined(relativePath)) {
relativePath = defaultValue(object.name, index) + extension;
var name = getName(gltf, object, index, extension, options);
relativePath = name + extension;

// Check if a file of the same name already exists, and if so, append a number
var number = 1;
while (defined(options.externalResources[relativePath])) {
relativePath = name + '_' + number + extension;
}
return relativePath;
}

object.uri = relativePath.replace(/\\/g, '/');
options.externalResources[relativePath] = source;
function writeFile(gltf, object, index, extension, options) {
delete object.bufferView;
var source = object.extras._pipeline.source;
var relativePath = getRelativePath(gltf, object, index, extension, options);
if (defined(options.externalResources)) {
options.externalResources[relativePath] = source;
}
}

function writeJimpImage(image, extension) {
Expand Down
1 change: 1 addition & 0 deletions specs/lib/readResourcesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function checkPaths(object, resourceDirectory) {
var relativePath = pipelineExtras.relativePath;
expect(path.basename(relativePath)).toBe(relativePath);
expect(absolutePath).toBe(path.join(resourceDirectory, relativePath));
expect(object.name).toBe(path.basename(relativePath, path.extname(relativePath)));
}

function readsResources(gltfPath, binary, separate, done) {
Expand Down
62 changes: 60 additions & 2 deletions specs/lib/writeResourcesSpec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,65 @@
'use strict';
var fsExtra = require('fs-extra');
var Promise = require('bluebird');
var addPipelineExtras = require('../../lib/addPipelineExtras');
var dataUriToBuffer = require('../../lib/dataUriToBuffer');
var ForEach = require('../../lib/ForEach');
var readResources = require('../../lib/readResources');
var writeResources = require('../../lib/writeResources');

describe('writeResources', function() {
it('writeResources', function() {
var gltfPath = 'specs/data/2.0/box-textured-embedded/box-textured-embedded.gltf';
var gltf;
// separateBuffer writes separate buffers (and nothing else)
// separateShaders writes separate shaders (and nothing else)
// separateTextures writes separate textures (and nothing else)
// dataUri is used instead of bfferviews
// bufferstorage supplied,
// external resources supplied (part of above really)

// TODO : test for shaders

fdescribe('writeResources', function() {
beforeEach(function(done) {
var gltfLoaded = fsExtra.readJsonSync(gltfPath);
return Promise.all([
addPipelineExtras(gltfLoaded),
readResources(gltfLoaded)
]).then(function() {
gltf = gltfLoaded;
done();
});
});

it('writes embedded resources', function(done) {
expect(writeResources(gltf)
.then(function(gltf) {
ForEach.image(gltf, function(image) {
expect(image.bufferView).toBeDefined();
expect(image.uri).toBeUndefined();
});
expect(gltf.buffers.length).toBe(1);
var buffer = gltf.buffers[0];
var contents = dataUriToBuffer(buffer.uri);
expect(contents.byteLength).toBe(buffer.byteLength);
}), done).toResolve();
});

it('writes external resources', function(done) {
var options = {
separateBuffers : true,
separateShaders : true,
separateTextures : true,
externalResources : {}
};
expect(writeResources(gltf, options)
.then(function(gltf) {
ForEach.image(gltf, function(image) {
expect(image.bufferView).toBeUndefined();
expect(image.uri).toBe('cesium.png');
});
expect(gltf.buffers.length).toBe(1);
var buffer = gltf.buffers[0];
expect(buffer.uri).toBe('0.bin'); // TODO : don't actually name 0.bin
}), done).toResolve();
});
});

0 comments on commit c803238

Please sign in to comment.