obj2gltf/lib/obj2gltf.js

196 lines
8.0 KiB
JavaScript

'use strict';
var Cesium = require('cesium');
var fsExtra = require('fs-extra');
var path = require('path');
var Promise = require('bluebird');
var createGltf = require('./createGltf');
var gltfToGlb = require('./gltfToGlb');
var loadObj = require('./loadObj');
var writeUris = require('./writeUris');
var defaultValue = Cesium.defaultValue;
var defined = Cesium.defined;
var DeveloperError = Cesium.DeveloperError;
var RuntimeError = Cesium.RuntimeError;
module.exports = obj2gltf;
/**
* Converts an obj file to a glTF file.
*
* @param {String} objPath Path to the obj file.
* @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 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.checkTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @param {Boolean} [options.secure=false] Prevent the converter from reading image or mtl files outside of the input obj directory.
* @param {String} [options.inputUpAxis='Y'] Up axis of the obj. Choices are 'X', 'Y', and 'Z'.
* @param {String} [options.outputUpAxis='Y'] Up axis of the converted glTF. Choices are 'X', 'Y', and 'Z'.
* @param {Boolean} [options.packOcclusion=false] Pack the occlusion texture in the red channel of metallic-roughness texture.
* @param {Boolean} [options.metallicRoughness=false] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.specularGlossiness=false] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.materialsCommon=false] The glTF will be saved with the KHR_materials_common extension.
* @param {Logger} [options.logger] A callback function for handling logged messages. Defaults to console.log.
* @return {Promise} A promise that resolves when the glTF file is saved.
*/
function obj2gltf(objPath, gltfPath, options) {
var defaults = obj2gltf.defaults;
options = defaultValue(options, {});
var binary = defaultValue(options.binary, defaults.binary);
var separate = defaultValue(options.separate, defaults.separate);
var separateTextures = defaultValue(options.separateTextures, defaults.separateTextures) || separate;
var checkTransparency = defaultValue(options.checkTransparency, defaults.checkTransparency);
var secure = defaultValue(options.secure, defaults.secure);
var inputUpAxis = defaultValue(options.inputUpAxis, defaults.inputUpAxis);
var outputUpAxis = defaultValue(options.outputUpAxis, defaults.outputUpAxis);
var packOcclusion = defaultValue(options.packOcclusion, defaults.packOcclusion);
var metallicRoughness = defaultValue(options.metallicRoughness, defaults.metallicRoughness);
var specularGlossiness = defaultValue(options.specularGlossiness, defaults.specularGlossiness);
var materialsCommon = defaultValue(options.materialsCommon, defaults.materialsCommon);
var logger = defaultValue(options.logger, defaults.logger);
options.separate = separate;
options.separateTextures = separateTextures;
options.checkTransparency = checkTransparency;
options.secure = secure;
options.inputUpAxis = inputUpAxis;
options.outputUpAxis = outputUpAxis;
options.packOcclusion = packOcclusion;
options.metallicRoughness = metallicRoughness;
options.specularGlossiness = specularGlossiness;
options.materialsCommon = materialsCommon;
options.logger = logger;
if (!defined(objPath)) {
throw new DeveloperError('objPath is required');
}
if (!defined(gltfPath)) {
throw new DeveloperError('gltfPath is required');
}
var extension = path.extname(gltfPath).toLowerCase();
var modelName = path.basename(gltfPath, path.extname(gltfPath));
if (extension === '.glb') {
binary = true;
}
if (binary) {
extension = '.glb';
}
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);
if (metallicRoughness + specularGlossiness + materialsCommon > 1) {
return Promise.reject(new RuntimeError('Only one material type may be set from [--metallicRoughness, --specularGlossiness, --materialsCommon].'));
}
var jsonOptions = {
spaces : 2
};
return loadObj(objPath, options)
.then(function(objData) {
return createGltf(objData, options);
})
.then(function(gltf) {
return writeUris(gltf, gltfPath, options);
})
.then(function(gltf) {
if (binary) {
var glb = gltfToGlb(gltf);
return fsExtra.outputFile(gltfPath, glb);
}
return fsExtra.outputJson(gltfPath, gltf, jsonOptions);
});
}
/**
* Default values that will be used when calling obj2gltf(options) unless specified in the options object.
*/
obj2gltf.defaults = {
/**
* Gets or sets whether the model will be saved as binary glTF.
* @type Boolean
* @default false
*/
binary: false,
/**
* Gets or sets whether to write out separate geometry/animation data files,
* shader files, and textures instead of embedding them in the glTF.
* @type Boolean
* @default false
*/
separate: false,
/**
* Gets or sets whether to write out separate textures only.
* @type Boolean
* @default false
*/
separateTextures: false,
/**
* Gets or sets whether the converter will do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
* @type Boolean
* @default false
*/
checkTransparency: false,
/**
* Gets or sets whether the source model can reference paths outside of its directory.
* @type Boolean
* @default false
*/
secure: false,
/**
* Gets or sets the up axis of the obj.
* @type String
* @default 'Y'
*/
inputUpAxis: 'Y',
/**
* Gets or sets the up axis of the converted glTF.
* @type String
* @default 'Y'
*/
outputUpAxis: 'Y',
/**
* Gets or sets whether to pack the occlusion texture in the red channel of the metallic-roughness texture.
* @type Boolean
* @default false
*/
packOcclusion: false,
/**
* The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @type Boolean
* @default false
*/
metallicRoughness: false,
/**
* The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @type Boolean
* @default false
*/
specularGlossiness: false,
/**
* The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @type Boolean
* @default false
*/
materialsCommon: false,
/**
* @private
*/
logger: function(message) {
console.log(message);
}
};
/**
* A callback function that logs messages.
* @callback Logger
*
* @param {String} message The message to log.
*/