Changed callback code to promises

This commit is contained in:
Robert Taglang 2016-07-22 14:09:13 -04:00
parent 68003e43b7
commit 68582967ac
8 changed files with 229 additions and 209 deletions

View File

@ -40,6 +40,7 @@ var options = {
ao : ao
};
convert(objFile, outputPath, options, function() {
console.timeEnd('Total');
});
convert(objFile, outputPath, options)
.then(function() {
console.timeEnd('Total');
});

View File

@ -9,7 +9,7 @@ var defaultValue = Cesium.defaultValue;
module.exports = convert;
function convert(objFile, outputPath, options, done) {
function convert(objFile, outputPath, options) {
options = defaultValue(options, {});
var binary = defaultValue(options.binary, false);
var embed = defaultValue(options.embed, true);
@ -37,24 +37,21 @@ function convert(objFile, outputPath, options, done) {
extension = binary ? '.glb' : '.gltf';
var gltfFile = path.join(outputPath, modelName + extension);
parseObj(objFile, inputPath, function(data) {
createGltf(data, inputPath, modelName, function(gltf) {
parseObj(objFile, inputPath)
.then(function(data) {
return createGltf(data, inputPath, modelName);
})
.then(function(gltf) {
var aoOptions = ao ? {} : undefined;
var options = {
binary : binary,
embed : embed,
embedImage : embedImage,
quantize : quantize,
aoOptions : aoOptions,
createDirectory : false,
basePath : inputPath
binary: binary,
embed: embed,
embedImage: embedImage,
quantize: quantize,
aoOptions: aoOptions,
createDirectory: false,
basePath: inputPath
};
gltfPipeline.processJSONToDisk(gltf, gltfFile, options, function(error) {
if (error) {
throw error;
}
done();
});
return gltfPipeline.processJSONToDisk(gltf, gltfFile, options);
});
});
}

View File

@ -1,14 +1,18 @@
"use strict";
var Cesium = require('cesium');
var Promise = require('bluebird');
var fs = require('fs-extra');
var path = require('path');
var Cesium = require('cesium');
var defined = Cesium.defined;
var defaultValue = Cesium.defaultValue;
var WebGLConstants = Cesium.WebGLConstants;
var fsWriteFile = Promise.promisify(fs.writeFile);
module.exports = createGltf;
function createGltf(data, inputPath, modelName, done) {
function createGltf(data, inputPath, modelName) {
var vertexCount = data.vertexCount;
var vertexArray = data.vertexArray;
var positionMin = data.positionMin;
@ -328,13 +332,7 @@ function createGltf(data, inputPath, modelName, done) {
if (bufferSeparate) {
var bufferPath = path.join(inputPath, modelName + '.bin');
fs.writeFile(bufferPath, buffer, function(err) {
if (err) {
throw err;
}
done(gltf);
});
} else {
done(gltf);
return fsWriteFile(bufferPath, buffer);
}
return gltf;
}

View File

@ -1,7 +1,10 @@
"use strict";
var Promise = require('bluebird');
var fs = require('fs-extra');
var path = require('path');
var fsReadFile = Promise.promisify(fs.readFile);
module.exports = loadImage;
function getChannels(colorType) {
@ -34,31 +37,27 @@ function getUriType(extension) {
}
}
function loadImage(imagePath, done) {
fs.readFile(imagePath, function(error, data) {
if (error) {
throw(error);
}
function loadImage(imagePath) {
return fsReadFile(imagePath)
.then(function(data) {
var extension = path.extname(imagePath).slice(1);
var uriType = getUriType(extension);
var uri = uriType + ';base64,' + data.toString('base64');
var extension = path.extname(imagePath).slice(1);
var uriType = getUriType(extension);
var uri = uriType + ';base64,' + data.toString('base64');
var info = {
transparent: false,
channels: 3,
data: data,
uri: uri
};
var info = {
transparent: false,
channels: 3,
data: data,
uri: uri
};
if (path.extname(imagePath) === 'png') {
// Color type is encoded in the 25th bit of the png
var colorType = data[25];
var channels = getChannels(colorType);
info.channels = channels;
info.transparent = (channels === 4);
}
done(info);
if (path.extname(imagePath) === 'png') {
// Color type is encoded in the 25th bit of the png
var colorType = data[25];
var channels = getChannels(colorType);
info.channels = channels;
info.transparent = (channels === 4);
}
return info;
});
}

View File

@ -1,7 +1,10 @@
"use strict";
var Promise = require('bluebird');
var fs = require('fs-extra');
var defined = require('cesium').defined;
var fsReadFile = Promise.promisify(fs.readFile);
module.exports = {
getDefault : getDefault,
parse : parse
@ -31,89 +34,84 @@ function getDefault() {
return material;
}
function parse(mtlPath, done) {
fs.readFile(mtlPath, 'utf8', function (error, contents) {
if (error) {
console.log('Could not read material file at ' + mtlPath + '. Using default material instead.');
done({});
return;
}
var materials = {};
var material;
var values;
var value;
var lines = contents.split('\n');
var length = lines.length;
for (var i = 0; i < length; ++i) {
var line = lines[i].trim();
if (/^newmtl /i.test(line)) {
var name = line.substring(7).trim();
material = createMaterial();
materials[name] = material;
} else if (/^Ka /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.ambientColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ke /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.emissionColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Kd /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.diffuseColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ks /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.specularColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ns /i.test(line)) {
value = line.substring(3).trim();
material.specularShininess = parseFloat(value);
} else if (/^d /i.test(line)) {
value = line.substring(2).trim();
material.alpha = parseFloat(value);
} else if (/^Tr /i.test(line)) {
value = line.substring(3).trim();
material.alpha = parseFloat(value);
} else if (/^map_Ka /i.test(line)) {
material.ambientColorMap = line.substring(7).trim();
} else if (/^map_Ke /i.test(line)) {
material.emissionColorMap = line.substring(7).trim();
} else if (/^map_Kd /i.test(line)) {
material.diffuseColorMap = line.substring(7).trim();
} else if (/^map_Ks /i.test(line)) {
material.specularColorMap = line.substring(7).trim();
} else if (/^map_Ns /i.test(line)) {
material.specularShininessMap = line.substring(7).trim();
} else if (/^map_Bump /i.test(line)) {
material.normalMap = line.substring(9).trim();
} else if (/^map_d /i.test(line)) {
material.alphaMap = line.substring(6).trim();
function parse(mtlPath) {
return fsReadFile(mtlPath, 'utf8')
.then(function (contents) {
var materials = {};
var material;
var values;
var value;
var lines = contents.split('\n');
var length = lines.length;
for (var i = 0; i < length; ++i) {
var line = lines[i].trim();
if (/^newmtl /i.test(line)) {
var name = line.substring(7).trim();
material = createMaterial();
materials[name] = material;
} else if (/^Ka /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.ambientColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ke /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.emissionColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Kd /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.diffuseColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ks /i.test(line)) {
values = line.substring(3).trim().split(' ');
material.specularColor = [
parseFloat(values[0]),
parseFloat(values[1]),
parseFloat(values[2]),
1.0
];
} else if (/^Ns /i.test(line)) {
value = line.substring(3).trim();
material.specularShininess = parseFloat(value);
} else if (/^d /i.test(line)) {
value = line.substring(2).trim();
material.alpha = parseFloat(value);
} else if (/^Tr /i.test(line)) {
value = line.substring(3).trim();
material.alpha = parseFloat(value);
} else if (/^map_Ka /i.test(line)) {
material.ambientColorMap = line.substring(7).trim();
} else if (/^map_Ke /i.test(line)) {
material.emissionColorMap = line.substring(7).trim();
} else if (/^map_Kd /i.test(line)) {
material.diffuseColorMap = line.substring(7).trim();
} else if (/^map_Ks /i.test(line)) {
material.specularColorMap = line.substring(7).trim();
} else if (/^map_Ns /i.test(line)) {
material.specularShininessMap = line.substring(7).trim();
} else if (/^map_Bump /i.test(line)) {
material.normalMap = line.substring(9).trim();
} else if (/^map_d /i.test(line)) {
material.alphaMap = line.substring(6).trim();
}
}
}
if (defined(material.alpha)) {
material.diffuseColor[3] = material.alpha;
}
done(materials);
});
if (defined(material.alpha)) {
material.diffuseColor[3] = material.alpha;
}
return materials;
})
.catch(function() {
console.log('Could not read material file at ' + mtlPath + '. Using default material instead.');
});
}

View File

@ -1,11 +1,16 @@
"use strict";
var Cesium = require('cesium');
var Promise = require('bluebird');
var async = require('async');
var byline = require('byline');
var fs = require('fs-extra');
var path = require('path');
var loadImage = require('./image');
var Material = require('./mtl');
var Cesium = require('cesium');
var Cartesian3 = Cesium.Cartesian3;
var defined = Cesium.defined;
@ -13,10 +18,14 @@ module.exports = parseObj;
// OBJ regex patterns are from ThreeJS (https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js)
function parseObj(objFile, inputPath, done) {
getObjInfo(objFile, inputPath, function(info, materials, images) {
processObj(objFile, info, materials, images, done);
});
function parseObj(objFile, inputPath) {
return getObjInfo(objFile, inputPath)
.then(function(result) {
var info = result.info;
var materials = result.materials;
var images = result.images;
return processObj(objFile, info, materials, images);
});
}
function processObj(objFile, info, materials, images, done) {
@ -237,7 +246,7 @@ function processObj(objFile, info, materials, images, done) {
});
}
function getImages(inputPath, materials, done) {
function getImages(inputPath, materials) {
// Collect all the image files from the materials
var images = [];
for (var name in materials) {
@ -259,84 +268,99 @@ function getImages(inputPath, materials, done) {
}
// Load the image files
var promises = [];
var imagesInfo = {};
async.each(images, function (image, callback) {
var imagePath = image;
var imagesLength = images.length;
for (var i = 0; i < imagesLength; i++) {
var imagePath = images[i];
if (!path.isAbsolute(imagePath)) {
imagePath = path.join(inputPath, image);
imagePath = path.join(inputPath, imagePath);
}
loadImage(imagePath, function(info) {
imagesInfo[image] = info;
callback();
});
}, function (error) {
if (error) {
throw error;
promises.push(loadImage(imagePath));
}
Promise.all(promises).then(function(imageInfoArray) {
var imageInfoArrayLength = imageInfoArray.length;
for (var j = 0; j < imageInfoArrayLength; j++) {
var image = images[j];
var imageInfo = imageInfoArray[j];
imagesInfo[image] = imageInfo;
}
done(imagesInfo);
return imagesInfo;
});
}
function getMaterials(mtlPath, hasMaterialGroups, done) {
function getMaterials(mtlPath, hasMaterialGroups) {
if (!hasMaterialGroups) {
done({});
return;
}
if (defined(mtlPath)) {
Material.parse(mtlPath, function(materials) {
done(materials);
});
} else {
done({});
return Material.parse(mtlPath);
}
}
function getObjInfo(objFile, inputPath, done) {
function getObjInfo(objFile, inputPath) {
var mtlPath;
var materials;
var info;
var hasMaterialGroups = false;
var hasPositions = false;
var hasNormals = false;
var hasUVs = false;
var stream = byline(fs.createReadStream(objFile, {encoding: 'utf8'}));
stream.on('data', function(line) {
if (!defined(mtlPath)) {
var mtllibMatches = line.match(/^mtllib.*/gm);
if (mtllibMatches !== null) {
var mtlFile = mtllibMatches[0].substring(7).trim();
mtlPath = mtlFile;
if (!path.isAbsolute(mtlPath)) {
mtlPath = path.join(inputPath, mtlFile);
return new Promise(function(resolve, reject) {
var stream = byline(fs.createReadStream(objFile, {encoding: 'utf8'}));
stream.on('data', function (line) {
if (!defined(mtlPath)) {
var mtllibMatches = line.match(/^mtllib.*/gm);
if (mtllibMatches !== null) {
var mtlFile = mtllibMatches[0].substring(7).trim();
mtlPath = mtlFile;
if (!path.isAbsolute(mtlPath)) {
mtlPath = path.join(inputPath, mtlFile);
}
}
}
}
if (!hasMaterialGroups) {
hasMaterialGroups = /^usemtl/gm.test(line);
}
if (!hasPositions) {
hasPositions = /^v\s/gm.test(line);
}
if (!hasNormals) {
hasNormals = /^vn/gm.test(line);
}
if (!hasUVs) {
hasUVs = /^vt/gm.test(line);
}
});
stream.on('end', function() {
if (!hasPositions) {
throw new Error('Could not process OBJ file, no positions.');
}
var info = {
hasNormals : hasNormals,
hasUVs : hasUVs
};
getMaterials(mtlPath, hasMaterialGroups, function(materials) {
getImages(inputPath, materials, function(images) {
done(info, materials, images);
});
if (!hasMaterialGroups) {
hasMaterialGroups = /^usemtl/gm.test(line);
}
if (!hasPositions) {
hasPositions = /^v\s/gm.test(line);
}
if (!hasNormals) {
hasNormals = /^vn/gm.test(line);
}
if (!hasUVs) {
hasUVs = /^vt/gm.test(line);
}
});
stream.on('error', function(err) {
reject(err);
});
stream.on('end', function () {
if (!hasPositions) {
reject(new Error('Could not process OBJ file, no positions.'));
}
info = {
hasNormals: hasNormals,
hasUVs: hasUVs
};
resolve();
});
})
.then(function() {
return getMaterials(mtlPath, hasMaterialGroups);
})
.then(function(returnedMaterials) {
materials = returnedMaterials;
return getImages(inputPath, materials);
})
.then(function(images) {
return {
info : info,
materials : materials,
images : images
};
});
});
}

View File

@ -27,6 +27,7 @@
},
"dependencies": {
"async": "2.0.0-rc.6",
"bluebird": "^3.4.1",
"byline": "4.2.1",
"cesium": "1.23.0",
"fs-extra": "0.30.0",

View File

@ -1,4 +1,6 @@
'use strict';
var Promise = require('bluebird');
var gltfPipeline = require('gltf-pipeline').gltfPipeline;
var path = require('path');
var convert = require('../../lib/convert');
@ -8,14 +10,14 @@ var gltfFile = './specs/data/BoxTextured/BoxTextured.gltf';
describe('convert', function() {
it('converts an obj to gltf', function(done) {
var spy = spyOn(gltfPipeline, 'processJSONToDisk').and.callFake(function(gltf, gltfFile, options, callback) {
callback();
});
convert(objFile, gltfFile, {}, function() {
var args = spy.calls.first().args;
expect(args[0]).toBeDefined();
expect(path.normalize(args[1])).toEqual(path.normalize(gltfFile));
done();
var spy = spyOn(gltfPipeline, 'processJSONToDisk').and.callFake(function() {
return;
});
expect(convert(objFile, gltfFile, {})
.then(function() {
var args = spy.calls.first().args;
expect(args[0]).toBeDefined();
expect(path.normalize(args[1])).toEqual(path.normalize(gltfFile));
}), done).toResolve();
});
});