Skip to content

Commit

Permalink
Merge pull request #185 from AnalyticalGraphicsInc/khr_materials_common
Browse files Browse the repository at this point in the history
Added command line generation of KHR_materials_common
  • Loading branch information
lilleyse authored Dec 5, 2016
2 parents fd7011b + 965677f commit 2493bc7
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Change Log
==========

### Next Release
* `modelMaterialsCommon` renamed to `processModelMaterialsCommon`.
* Added `generateModelMaterialsCommon` and command line `kmc` flags for generating models with the `KHR_materials_common` extension.

### 0.1.0-alpha6 - 2016-11-18

* Fixed `combinePrimitives` stage and re-added it to the pipeline. [#108](https://github.com/AnalyticalGraphicsInc/gltf-pipeline/issues/108)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ node ./bin/gltf-pipeline.js -i ./specs/data/boxTexturedUnoptimized/CesiumTexture
|`--removeNormals`, `-r`|Strips off existing normals, allowing them to be regenerated.|No, default `false`|
|`--faceNormals`, `-f`|If normals are missing, they should be generated using the face normal.|No, default `false`|
|`--cesium`, `-c`|Optimize the glTF for Cesium by using the sun as a default light source.|No, default `false`|
|`--kmc.enable`|Materials should be expressed using the KHR_materials_common extension. If other `kmc` flags are enabled, this is implicitly true.|No, default `false`|
|`--kmc.doubleSided`|Declares whether backface culling should be disabled.|No, default `false`|
|`--kmc.technique`|The lighting model to use.|No, default `PHONG`|
|`--ao.enable`|Bake ambient occlusion (to vertex data by default). If other `ao` flags are enabled, this is implicitly true. Advanced settings in `lib/bakeAmbientOcclusion.js`|No, default `false`|
|`--ao.toTexture`|Bake AO to existing diffuse textures instead of to vertices. Does not modify shaders.|No, default `false`|
|`--ao.groundPlane`|Simulate a groundplane at the lowest point of the model when baking AO.|No, default `false`|
Expand Down
8 changes: 8 additions & 0 deletions lib/Pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var compressTextureCoordinates = require('./compressTextureCoordinates');
var combinePrimitives = require('./combinePrimitives');
var convertDagToTree = require('./convertDagToTree');
var encodeImages = require('./encodeImages');
var generateModelMaterialsCommon = require('./generateModelMaterialsCommon');
var generateNormals = require('./generateNormals');
var loadGltfUris = require('./loadGltfUris');
var mergeDuplicateVertices = require('./mergeDuplicateVertices');
Expand Down Expand Up @@ -132,6 +133,13 @@ Pipeline.processJSONWithExtras = function(gltfWithExtras, options) {
quantizeAttributes(gltfWithExtras, quantizedOptions);
}
return encodeImages(gltfWithExtras);
})
.then(function() {
var kmcOptions = options.kmcOptions;
if (defined(kmcOptions) && kmcOptions.enable) {
generateModelMaterialsCommon(gltfWithExtras, options.kmcOptions);
}
return gltfWithExtras;
});
};

Expand Down
4 changes: 2 additions & 2 deletions lib/addDefaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var WebGLConstants = Cesium.WebGLConstants;

var addExtensionsUsed = require('./addExtensionsUsed');
var findAccessorMinMax = require('./findAccessorMinMax');
var modelMaterialsCommon = require('./modelMaterialsCommon');
var processModelMaterialsCommon = require('./processModelMaterialsCommon');

module.exports = addDefaults;

Expand Down Expand Up @@ -552,7 +552,7 @@ function addDefaults(gltf, options) {
skinDefaults(gltf);
textureDefaults(gltf);

modelMaterialsCommon(gltf, options);
processModelMaterialsCommon(gltf, options);

return gltf;
}
2 changes: 1 addition & 1 deletion lib/cesiumGeometryToGltfPrimitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ function cesiumGeometryToGltfPrimitive(gltf, primitive, geometry) {
var indicesId = primitive.indices;
var indicesAccessor = gltf.accessors[indicesId];
writeAccessor(gltf, indicesAccessor, geometry.indices);
mergeBuffers(gltf, 'buffer_0');
mergeBuffers(gltf);
uninterleaveAndPackBuffers(gltf);
}
160 changes: 160 additions & 0 deletions lib/generateModelMaterialsCommon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
'use strict';
var Cesium = require('cesium');
var addExtensionsUsed = require('./addExtensionsUsed');

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

module.exports = generateModelMaterialsCommon;

/**
* Converts materials to use the KHR_materials_common extension and deletes
* techniques, programs and shaders.
*
* The glTF asset must be initialized for the pipeline.
*
* @param {Object} gltf A javascript object containing a glTF asset.
* @param {Object} [kmcOptions] KHR_materials_common options for material generation.
* @returns {Object} The glTF asset using the KHR_materials_common extension.
*
* @see addPipelineExtras
* @see loadGltfUris
*/
function generateModelMaterialsCommon(gltf, kmcOptions) {
kmcOptions = defaultValue(kmcOptions, {});
kmcOptions.doubleSided = defaultValue(kmcOptions.doubleSided, false);
kmcOptions.technique = defaultValue(kmcOptions.technique, 'PHONG');
addExtensionsUsed(gltf, 'KHR_materials_common');
var materialsCommon;
var materials = gltf.materials;
var nodes = gltf.nodes;
var techniques = gltf.techniques;
var jointCountForMaterialId = getJointCountForMaterials(gltf);

var gltfExtensions = gltf.extensions;
if (!defined(gltfExtensions)) {
gltfExtensions = {};
gltf.extensions = gltfExtensions;
}
materialsCommon = {};
gltfExtensions.KHR_materials_common = materialsCommon;
var lights = {};
materialsCommon.lights = lights;

for (var materialId in materials) {
if (materials.hasOwnProperty(materialId)) {
var material = materials[materialId];
var technique = techniques[material.technique];
var techniqueParameters = technique.parameters;
if (defined(techniqueParameters.ambient) && !defined(lights.defaultAmbient)) {
lights.defaultAmbient = {
ambient: {
color: [1, 1, 1]
},
name: 'defaultAmbient',
type: 'ambient'
};
}
for (var parameterId in techniqueParameters) {
if (techniqueParameters.hasOwnProperty(parameterId)) {
if (parameterId.indexOf('light') === 0 && parameterId.indexOf('Transform') >= 0) {
var lightId = parameterId.substring(0, parameterId.indexOf('Transform'));
var lightTransform = techniqueParameters[parameterId];
var lightNodeId = lightTransform.node;
var lightNode = nodes[lightNodeId];
var nodeExtensions = lightNode.extensions;
if (!defined(nodeExtensions)) {
nodeExtensions = {};
lightNode.extensions = nodeExtensions;
}
materialsCommon = {};
nodeExtensions.KHR_materials_common = materialsCommon;
materialsCommon.light = lightId;
var lightColor = techniqueParameters[lightId + 'Color'];
var light = {
name : lightId,
type : 'directional',
directional : {
color : defaultValue(lightColor.value, [1, 1, 1])
}
};
lights[lightId] = light;
}
}
}

delete material.technique;
var extensions = material.extensions;
if (!defined(extensions)) {
extensions = {};
material.extensions = extensions;
}
materialsCommon = {};
extensions.KHR_materials_common = materialsCommon;
for (var kmcOption in kmcOptions) {
if (kmcOptions.hasOwnProperty(kmcOption) && kmcOption !== 'enable') {
materialsCommon[kmcOption] = kmcOptions[kmcOption];
}
}
var jointCount = jointCountForMaterialId[materialId];
if (defined(jointCount)) {
materialsCommon.jointCount = jointCount;
}
materialsCommon.values = material.values;
delete material.values;
}
}
delete gltf.techniques;
delete gltf.programs;
delete gltf.shaders;
return gltf;
}

function getJointCountForMaterials(gltf) {
var accessors = gltf.accessors;
var meshes = gltf.meshes;
var nodes = gltf.nodes;
var skins = gltf.skins;
var jointCountForMaterialId = {};

var nodesForSkinId = {};
for (var nodeId in nodes) {
if (nodes.hasOwnProperty(nodeId)) {
var node = nodes[nodeId];
if (defined(node.skin)) {
if (!defined(nodesForSkinId[node.skin])) {
nodesForSkinId[node.skin] = [];
}
nodesForSkinId[node.skin].push(node);
}
}
}

for (var skinId in skins) {
if (skins.hasOwnProperty(skinId)) {
var skin = skins[skinId];
var jointCount = 1;
if (defined(skin.inverseBindMatrices)) {
jointCount = accessors[skin.inverseBindMatrices].count;
}
var skinnedNodes = nodesForSkinId[skinId];
var skinnedNodesLength = skinnedNodes.length;
for (var i = 0; i < skinnedNodesLength; i++) {
var skinnedNode = skinnedNodes[i];
var nodeMeshes = skinnedNode.meshes;
var nodeMeshesLength = nodeMeshes.length;
for (var j = 0; j < nodeMeshesLength; j++) {
var meshId = nodeMeshes[j];
var mesh = meshes[meshId];
var primitives = mesh.primitives;
var primitivesLength = primitives.length;
for (var k = 0; k < primitivesLength; k++) {
var primitive = primitives[k];
jointCountForMaterialId[primitive.material] = jointCount;
}
}
}
}
}
return jointCountForMaterialId;
}
4 changes: 2 additions & 2 deletions lib/generateNormals.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var gltfPrimitiveToCesiumGeometry = require('./gltfPrimitiveToCesiumGeometry');
var getPrimitiveAttributeSemantics = require('./getPrimitiveAttributeSemantics');
var getUniqueId = require('./getUniqueId');
var mergeBuffers = require('./mergeBuffers');
var modelMaterialsCommon = require('./modelMaterialsCommon');
var processModelMaterialsCommon = require('./processModelMaterialsCommon');
var packArray = require('./packArray');
var readAccessor = require('./readAccessor');
var techniqueParameterForSemantic = require('./techniqueParameterForSemantic');
Expand Down Expand Up @@ -65,7 +65,7 @@ function generateNormals(gltf, options) {
removeBufferViews(gltf);
removeBuffers(gltf);
mergeBuffers(gltf);
modelMaterialsCommon(gltf, options);
processModelMaterialsCommon(gltf, options);
return gltf;
}

Expand Down
10 changes: 7 additions & 3 deletions lib/mergeBuffers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ module.exports = mergeBuffers;
* @see loadGltfUris
*/
function mergeBuffers(gltf, bufferId) {
if (!defined(bufferId)) {
bufferId = getUniqueId(gltf, 'buffer');
}
var buffers = gltf.buffers;
var bufferViews = gltf.bufferViews;
var bufferViewsForBuffers = getBufferViewsForBuffers(gltf);
Expand All @@ -32,6 +29,9 @@ function mergeBuffers(gltf, bufferId) {
if (buffers.hasOwnProperty(gltfBufferId)) {
//Add the buffer to the merged source
var buffer = buffers[gltfBufferId];
if (!defined(bufferId)) {
bufferId = gltfBufferId;
}
var bufferViewIds = bufferViewsForBuffers[gltfBufferId];
for (var bufferViewId in bufferViewIds) {
if (bufferViewIds.hasOwnProperty(bufferViewId)) {
Expand All @@ -44,6 +44,10 @@ function mergeBuffers(gltf, bufferId) {
}
}

if (!defined(bufferId)) {
bufferId = getUniqueId(gltf, 'buffer');
}

//Replace existing buffer with new merged buffer
gltf.buffers = {};
gltf.buffers[bufferId] = {
Expand Down
34 changes: 30 additions & 4 deletions lib/parseArguments.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,42 @@ function parseArguments(args) {
describe: 'Optimize the glTF for Cesium by using the sun as a default light source.',
type: 'boolean'
},
'kmc.enable': {
default: false,
describe: 'Materials should be expressed using the KHR_materials_common extension. If other `kmc` flags are enabled, this is implictly true.',
group: 'Options: KHR_materials_common',
type: 'boolean'
},
'kmc.doubleSided': {
default: false,
describe: 'Declares whether backface culling should be disabled.',
group: 'Options: KHR_materials_common',
type: 'boolean'
},
'kmc.technique': {
choices: ['CONSTANT', 'BLINN', 'PHONG', 'LAMBERT'],
default: 'PHONG',
describe: 'The lighting model to use.',
group: 'Options: KHR_materials_common',
type: 'string'
},
'ao.enable': {
default: false,
describe: 'Bake ambient occlusion (to vertex data by default). If other `ao` flags are enabled, this is implicitly true.',
group: 'Options: Ambient Occlusion'
group: 'Options: Ambient Occlusion',
type: 'boolean'
},
'ao.toTexture': {
default: false,
describe: 'Bake AO to existing diffuse textures instead of vertices. Does not modify shaders.',
group: 'Options: Ambient Occlusion'
group: 'Options: Ambient Occlusion',
type: 'boolean'
},
'ao.groundPlane': {
default: false,
describe: 'Simulate a ground plane at the lowest point of the model when baking AO.',
group: 'Options: Ambient Occlusion'
group: 'Options: Ambient Occlusion',
type: 'boolean'
},
'ao.ambientShadowContribution': {
default: 0.5,
Expand All @@ -111,13 +133,16 @@ function parseArguments(args) {
}
}).parse(args);

// If any raw ao parameters were specified, ao is enabled
// If any raw ao or kmc parameters were specified, they are enabled
var nargs = process.argv.length;
for (var i = 0; i < nargs; i++) {
var arg = process.argv[i];
if (arg.indexOf('ao') >= 0) {
argv.ao.enable = true;
}
if (arg.indexOf('kmc') >= 0) {
argv.kmc.enable = true;
}
}

var gltfPath = defaultValue(argv.i, argv._[0]);
Expand Down Expand Up @@ -151,6 +176,7 @@ function parseArguments(args) {
encodeNormals: argv.n,
faceNormals: argv.f,
inputPath: gltfPath,
kmcOptions: argv.kmc,
removeNormals: argv.r,
optimizeForCesium: argv.cesium,
outputPath: outputPath,
Expand Down
File renamed without changes.
Loading

0 comments on commit 2493bc7

Please sign in to comment.