Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gltf-pipeline

Package Overview
Dependencies
Maintainers
5
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gltf-pipeline - npm Package Compare versions

Comparing version 2.1.3 to 2.1.4

7

bin/gltf-pipeline.js

@@ -72,2 +72,7 @@ #!/usr/bin/env node

},
keepUnusedElements: {
describe: 'Keep unused materials, nodes and meshes.',
type: 'boolean',
default: defaults.keepUnusedElements
},
'draco.compressMeshes': {

@@ -186,3 +191,3 @@ alias: 'd',

for (const relativePath in separateResources) {
if (separateResources.hasOwnProperty(relativePath)) {
if (Object.prototype.hasOwnProperty.call(separateResources, relativePath)) {
const resource = separateResources[relativePath];

@@ -189,0 +194,0 @@ const resourcePath = path.join(outputDirectory, relativePath);

Change Log
==========
### 2.1.4 - 2019-10-04
* Added removal of unused materials, nodes and meshes. [#465](https://github.com/AnalyticalGraphicsInc/gltf-pipeline/pull/465)
* Added `keepUnusedElements` flag to keep unused materials, nodes and meshes. [#465](https://github.com/AnalyticalGraphicsInc/gltf-pipeline/pull/465)
### 2.1.3 - 2019-03-21

@@ -5,0 +10,0 @@

2

lib/compressDracoMeshes.js

@@ -229,3 +229,3 @@ 'use strict';

}
removeUnusedElements(gltf);
removeUnusedElements(gltf, ['accessor', 'bufferView', 'buffer']);

@@ -232,0 +232,0 @@ if (uncompressedFallback) {

@@ -26,3 +26,3 @@ 'use strict';

for (const objectId in objects) {
if (objects.hasOwnProperty(objectId)) {
if (Object.prototype.hasOwnProperty.call(objects, objectId)) {
const object = objects[objectId];

@@ -194,3 +194,3 @@ const value = handler(object, objectId);

for (const type in compressedImages) {
if (compressedImages.hasOwnProperty(type)) {
if (Object.prototype.hasOwnProperty.call(compressedImages, type)) {
const compressedImage = compressedImages[type];

@@ -218,3 +218,3 @@ const value = handler(compressedImage, type);

for (const name in values) {
if (values.hasOwnProperty(name)) {
if (Object.prototype.hasOwnProperty.call(values, name)) {
const value = handler(values[name], name);

@@ -251,3 +251,3 @@

for (const semantic in attributes) {
if (attributes.hasOwnProperty(semantic)) {
if (Object.prototype.hasOwnProperty.call(attributes, semantic)) {
const value = handler(attributes[semantic], semantic);

@@ -278,3 +278,3 @@

for (const semantic in target) {
if (target.hasOwnProperty(semantic)) {
if (Object.prototype.hasOwnProperty.call(target, semantic)) {
const accessorId = target[semantic];

@@ -356,6 +356,21 @@ const value = handler(accessorId, semantic);

ForEach.skinJoint = function(skin, handler) {
const joints = skin.joints;
if (defined(joints)) {
const jointsLength = joints.length;
for (let i = 0; i < jointsLength; i++) {
const joint = joints[i];
const value = handler(joint);
if (defined(value)) {
return value;
}
}
}
};
ForEach.techniqueAttribute = function(technique, handler) {
const attributes = technique.attributes;
for (const attributeName in attributes) {
if (attributes.hasOwnProperty(attributeName)) {
if (Object.prototype.hasOwnProperty.call(attributes, attributeName)) {
const value = handler(attributes[attributeName], attributeName);

@@ -373,3 +388,3 @@

for (const uniformName in uniforms) {
if (uniforms.hasOwnProperty(uniformName)) {
if (Object.prototype.hasOwnProperty.call(uniforms, uniformName)) {
const value = handler(uniforms[uniformName], uniformName);

@@ -387,3 +402,3 @@

for (const parameterName in parameters) {
if (parameters.hasOwnProperty(parameterName)) {
if (Object.prototype.hasOwnProperty.call(parameters, parameterName)) {
const value = handler(parameters[parameterName], parameterName);

@@ -390,0 +405,0 @@

@@ -33,2 +33,4 @@ 'use strict';

return '.crn';
} else if (header.equals(Buffer.from([0x73, 0x42]))) {
return '.basis';
} else if (webpHeaderRIFFChars.equals(Buffer.from([0x52, 0x49, 0x46, 0x46])) && webpHeaderWEBPChars.equals(Buffer.from([0x57, 0x45, 0x42, 0x50]))) {

@@ -35,0 +37,0 @@ // See https://developers.google.com/speed/webp/docs/riff_container#webp_file_header

@@ -81,3 +81,3 @@ 'use strict';

for (const mergedName in buffersToMerge) {
if (buffersToMerge.hasOwnProperty(mergedName)) {
if (Object.prototype.hasOwnProperty.call(buffersToMerge, mergedName)) {
const buffers = buffersToMerge[mergedName].buffers;

@@ -84,0 +84,0 @@ const byteLength = buffersToMerge[mergedName].byteLength;

@@ -10,2 +10,3 @@ 'use strict';

const removePipelineExtras = require('./removePipelineExtras');
const removeUnusedElements = require('./removeUnusedElements');
const updateVersion = require('./updateVersion');

@@ -86,2 +87,7 @@ const writeResources = require('./writeResources');

}
if (!options.keepUnusedElements) {
stages.push(function(gltf, options) {
removeUnusedElements(gltf);
});
}
return stages;

@@ -119,2 +125,8 @@ }

/**
* Keep unused 'node', 'mesh' and 'material' elements.
* @type Boolean
* @default false
*/
keepUnusedElements: false,
/**
* Gets or sets whether to compress the meshes using Draco. Adds the KHR_draco_mesh_compression extension.

@@ -121,0 +133,0 @@ * @type Boolean

@@ -58,3 +58,3 @@ 'use strict';

for (const key in object) {
if (object.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
removeExtensionAndTraverse(object[key], extension);

@@ -61,0 +61,0 @@ }

@@ -6,2 +6,3 @@ 'use strict';

const defaultValue = Cesium.defaultValue;
const defined = Cesium.defined;

@@ -11,14 +12,19 @@

const allElementTypes = ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'];
/**
* Removes unused elements from gltf.
* This function currently only works for accessors, buffers, and bufferViews.
*
* @param {Object} gltf A javascript object containing a glTF asset.
* @param {String[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored.
*
* @private
*/
function removeUnusedElements(gltf) {
removeUnusedElementsByType(gltf, 'accessor');
removeUnusedElementsByType(gltf, 'bufferView');
removeUnusedElementsByType(gltf, 'buffer');
function removeUnusedElements(gltf, elementTypes) {
elementTypes = defaultValue(elementTypes, allElementTypes);
allElementTypes.forEach(function(type) {
if (elementTypes.indexOf(type) > -1) {
removeUnusedElementsByType(gltf, type);
}
});
return gltf;

@@ -30,3 +36,6 @@ }

buffer: 'buffers',
bufferView: 'bufferViews'
bufferView: 'bufferViews',
node: 'nodes',
material: 'materials',
mesh: 'meshes'
};

@@ -151,4 +160,4 @@

if (hasExtension(gltf, 'KHR_draco_mesh_compression')) {
ForEach.mesh(gltf, function (mesh) {
ForEach.meshPrimitive(mesh, function (primitive) {
ForEach.mesh(gltf, function(mesh) {
ForEach.meshPrimitive(mesh, function(primitive) {
if (defined(primitive.extensions) &&

@@ -165,2 +174,84 @@ defined(primitive.extensions.KHR_draco_mesh_compression)) {

Remove.mesh = function(gltf, meshId) {
const meshes = gltf.meshes;
meshes.splice(meshId, 1);
ForEach.node(gltf, function(node) {
if (defined(node.mesh)) {
if (node.mesh > meshId) {
node.mesh--;
} else if (node.mesh === meshId) {
// Remove reference to deleted mesh
delete node.mesh;
}
}
});
};
Remove.node = function(gltf, nodeId) {
const nodes = gltf.nodes;
nodes.splice(nodeId, 1);
// Shift all node references
ForEach.skin(gltf, function(skin) {
if (defined(skin.skeleton) && skin.skeleton > nodeId) {
skin.skeleton--;
}
skin.joints = skin.joints.map(function(x) {
return x > nodeId ? x - 1 : x;
});
});
ForEach.animation(gltf, function(animation) {
ForEach.animationChannel(animation, function(channel) {
if (defined(channel.target) && defined(channel.target.node) && (channel.target.node > nodeId)) {
channel.target.node--;
}
});
});
ForEach.technique(gltf, function(technique) {
ForEach.techniqueUniform(technique, function(uniform) {
if (defined(uniform.node) && uniform.node > nodeId) {
uniform.node--;
}
});
});
ForEach.node(gltf, function(node) {
if (!defined(node.children)) {
return;
}
node.children = node.children
.filter(function(x) {
return x !== nodeId; // Remove
})
.map(function(x) {
return x > nodeId ? x - 1 : x; // Shift indices
});
});
ForEach.scene(gltf, function(scene) {
scene.nodes = scene.nodes
.filter(function(x) {
return x !== nodeId; // Remove
})
.map(function(x) {
return x > nodeId ? x - 1 : x; // Shift indices
});
});
};
Remove.material = function(gltf, materialId) {
const materials = gltf.materials;
materials.splice(materialId, 1);
// Shift other material ids
ForEach.mesh(gltf, function(mesh) {
ForEach.meshPrimitive(mesh, function(primitive) {
if (defined(primitive.material) && primitive.material > materialId) {
primitive.material--;
}
});
});
};
/**

@@ -268,1 +359,79 @@ * Contains functions for getting a list of element ids in use by the glTF asset.

};
getListOfElementsIdsInUse.mesh = function(gltf) {
const usedMeshIds = {};
ForEach.node(gltf, function(node) {
if (defined(node.mesh && defined(gltf.meshes))) {
const mesh = gltf.meshes[node.mesh];
if (defined(mesh) && defined(mesh.primitives) && (mesh.primitives.length > 0)) {
usedMeshIds[node.mesh] = true;
}
}
});
return usedMeshIds;
};
// Check if node is empty. It is considered empty if neither referencing
// mesh, camera, extensions and has no children
function nodeIsEmpty(gltf, node) {
if (defined(node.mesh) || defined(node.camera) || defined(node.skin)
|| defined(node.weights) || defined(node.extras)
|| (defined(node.extensions) && node.extensions.length !== 0)) {
return false;
}
// Empty if no children or children are all empty nodes
return !defined(node.children)
|| node.children.filter(function(n) {
return !nodeIsEmpty(gltf, gltf.nodes[n]);
}).length === 0;
}
getListOfElementsIdsInUse.node = function(gltf) {
const usedNodeIds = {};
ForEach.node(gltf, function(node, nodeId) {
if (!nodeIsEmpty(gltf, node)) {
usedNodeIds[nodeId] = true;
}
});
ForEach.skin(gltf, function(skin) {
if (defined(skin.skeleton)) {
usedNodeIds[skin.skeleton] = true;
}
ForEach.skinJoint(skin, function(joint) {
usedNodeIds[joint] = true;
});
});
ForEach.animation(gltf, function(animation) {
ForEach.animationChannel(animation, function(channel) {
if (defined(channel.target) && defined(channel.target.node)) {
usedNodeIds[channel.target.node] = true;
}
});
});
ForEach.technique(gltf, function(technique) {
ForEach.techniqueUniform(technique, function(uniform) {
if (defined(uniform.node)) {
usedNodeIds[uniform.node] = true;
}
});
});
return usedNodeIds;
};
getListOfElementsIdsInUse.material = function(gltf) {
const usedMaterialIds = {};
ForEach.mesh(gltf, function(mesh) {
ForEach.meshPrimitive(mesh, function(primitive) {
if (defined(primitive.material)) {
usedMaterialIds[primitive.material] = true;
}
});
});
return usedMaterialIds;
};

@@ -47,3 +47,3 @@ 'use strict';

for (const semantic in dracoAttributes) {
if (dracoAttributes.hasOwnProperty(semantic)) {
if (Object.prototype.hasOwnProperty.call(dracoAttributes, semantic)) {
const attributeAccessor = gltf.accessors[primitive.attributes[semantic]];

@@ -50,0 +50,0 @@ attributeAccessor.count = dracoEncodedBuffer.numberOfPoints;

@@ -67,3 +67,3 @@ 'use strict';

for (hash in primitivesWithSharedAttributes) {
if (primitivesWithSharedAttributes.hasOwnProperty(hash)) {
if (Object.prototype.hasOwnProperty.call(primitivesWithSharedAttributes, hash)) {
primitives = primitivesWithSharedAttributes[hash];

@@ -85,3 +85,3 @@ primitivesLength = primitives.length;

for (hash in duplicatePrimitives) {
if (duplicatePrimitives.hasOwnProperty(hash)) {
if (Object.prototype.hasOwnProperty.call(duplicatePrimitives, hash)) {
const primitiveToCopy = hashPrimitives[hash];

@@ -95,3 +95,3 @@ primitives = duplicatePrimitives[hash];

}
removeUnusedElements(gltf);
removeUnusedElements(gltf, ['accessor', 'bufferView', 'buffer']);
}

@@ -154,3 +154,3 @@

for (const index in mappedIndices) {
if (mappedIndices.hasOwnProperty(index)) {
if (Object.prototype.hasOwnProperty.call(mappedIndices, index)) {
const mappedIndex = mappedIndices[index];

@@ -157,0 +157,0 @@ for (let i = 0; i < numberOfComponents; ++i) {

@@ -58,3 +58,3 @@ 'use strict';

// Invalid version
if (!updateFunctions.hasOwnProperty(version)) {
if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) {
// Try truncating trailing version numbers, could be a number as well if it is 0.8

@@ -65,3 +65,3 @@ if (defined(version)) {

// Default to 1.0 if it cannot be determined
if (!updateFunctions.hasOwnProperty(version)) {
if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) {
version = '1.0';

@@ -87,3 +87,3 @@ }

for (const materialId in materials) {
if (materials.hasOwnProperty(materialId)) {
if (Object.prototype.hasOwnProperty.call(materials, materialId)) {
const material = materials[materialId];

@@ -103,3 +103,3 @@ const instanceTechnique = material.instanceTechnique;

for (const meshId in meshes) {
if (meshes.hasOwnProperty(meshId)) {
if (Object.prototype.hasOwnProperty.call(meshes, meshId)) {
const mesh = meshes[meshId];

@@ -125,3 +125,3 @@ const primitives = mesh.primitives;

for (const nodeId in nodes) {
if (nodes.hasOwnProperty(nodeId)) {
if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
const node = nodes[nodeId];

@@ -154,3 +154,3 @@ if (defined(node.rotation)) {

for (const animationId in animations) {
if (animations.hasOwnProperty(animationId)) {
if (Object.prototype.hasOwnProperty.call(animations, animationId)) {
const animation = animations[animationId];

@@ -198,3 +198,3 @@ const channels = animation.channels;

for (const techniqueId in techniques) {
if (techniques.hasOwnProperty(techniqueId)) {
if (Object.prototype.hasOwnProperty.call(techniques, techniqueId)) {
const technique = techniques[techniqueId];

@@ -204,3 +204,3 @@ const passes = technique.passes;

const passName = defaultValue(technique.pass, 'defaultPass');
if (passes.hasOwnProperty(passName)) {
if (Object.prototype.hasOwnProperty.call(passes, passName)) {
const pass = passes[passName];

@@ -272,3 +272,3 @@ const instanceProgram = pass.instanceProgram;

for (const animationId in animations) {
if (animations.hasOwnProperty(animationId)) {
if (Object.prototype.hasOwnProperty.call(animations, animationId)) {
const animation = animations[animationId];

@@ -279,3 +279,3 @@ const parameters = animation.parameters;

for (const samplerId in samplers) {
if (samplers.hasOwnProperty(samplerId)) {
if (Object.prototype.hasOwnProperty.call(samplers, samplerId)) {
const sampler = samplers[samplerId];

@@ -295,3 +295,3 @@ sampler.input = parameters[sampler.input];

for (const id in object) {
if (object.hasOwnProperty(id)) {
if (Object.prototype.hasOwnProperty.call(object, id)) {
const value = object[id];

@@ -334,3 +334,3 @@ mapping[id] = array.length;

for (const id in nodes) {
if (nodes.hasOwnProperty(id)) {
if (Object.prototype.hasOwnProperty.call(nodes, id)) {
jointName = nodes[id].jointName;

@@ -345,3 +345,3 @@ if (defined(jointName)) {

for (const topLevelId in gltf) {
if (gltf.hasOwnProperty(topLevelId) && defined(globalMapping[topLevelId])) {
if (Object.prototype.hasOwnProperty.call(gltf, topLevelId) && defined(globalMapping[topLevelId])) {
const objectMapping = {};

@@ -356,3 +356,3 @@ const object = gltf[topLevelId];

for (jointName in jointNameToId) {
if (jointNameToId.hasOwnProperty(jointName)) {
if (Object.prototype.hasOwnProperty.call(jointNameToId, jointName)) {
jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]];

@@ -587,3 +587,3 @@ }

for (const topLevelId in gltf) {
if (gltf.hasOwnProperty(topLevelId)) {
if (Object.prototype.hasOwnProperty.call(gltf, topLevelId)) {
const array = gltf[topLevelId];

@@ -709,3 +709,3 @@ if (isArray(array) && array.length === 0) {

for (const semantic in mappedSemantics) {
if (mappedSemantics.hasOwnProperty(semantic)) {
if (Object.prototype.hasOwnProperty.call(mappedSemantics, semantic)) {
const mappedSemantic = mappedSemantics[semantic];

@@ -793,3 +793,3 @@ const accessorId = primitive.attributes[semantic];

for (const bufferViewId in bufferViewMap) {
if (bufferViewMap.hasOwnProperty(bufferViewId)) {
if (Object.prototype.hasOwnProperty.call(bufferViewMap, bufferViewId)) {
bufferView = bufferViews[bufferViewId];

@@ -834,3 +834,3 @@ const accessors = bufferViewMap[bufferViewId];

// Remove unused buffer views
removeUnusedElements(gltf);
removeUnusedElements(gltf, ['accessor', 'bufferView', 'buffer']);
}

@@ -837,0 +837,0 @@

@@ -20,2 +20,5 @@ 'use strict';

// .basis is not a supported mime type, so add it
mime.define({'image/basis': ['basis']}, true);
module.exports = writeResources;

@@ -59,3 +62,3 @@

// Buffers need to be written last because images and shaders may write to new buffers
removeUnusedElements(gltf);
removeUnusedElements(gltf, ['acessor', 'bufferView', 'buffer']);
mergeBuffers(gltf, options.name);

@@ -177,5 +180,6 @@

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

@@ -182,0 +186,0 @@ return relativePath;

{
"name": "gltf-pipeline",
"version": "2.1.3",
"version": "2.1.4",
"description": "Content pipeline tools for optimizing glTF assets.",

@@ -29,23 +29,23 @@ "license": "Apache-2.0",

"dependencies": {
"bluebird": "^3.5.3",
"cesium": "^1.54.0",
"bluebird": "^3.5.5",
"cesium": "^1.58.1",
"draco3d": "^1.3.4",
"fs-extra": "^7.0.1",
"mime": "^2.4.0",
"fs-extra": "^8.0.1",
"mime": "^2.4.4",
"object-hash": "^1.3.1",
"uuid": "^3.3.2",
"yargs": "^13.2.0"
"yargs": "^13.2.4"
},
"devDependencies": {
"cloc": "^2.4.0",
"coveralls": "^3.0.2",
"cloc": "^2.5.0",
"coveralls": "^3.0.4",
"dependency-tree": "^7.0.2",
"eslint": "^5.13.0",
"eslint-config-cesium": "^6.0.1",
"gulp": "^4.0.0",
"jasmine": "^3.3.1",
"eslint": "^6.0.0",
"eslint-config-cesium": "^7.0.0",
"gulp": "^4.0.2",
"jasmine": "^3.4.0",
"jasmine-spec-reporter": "^4.2.1",
"jsdoc": "^3.5.5",
"nyc": "^13.3.0",
"open": "^0.0.5",
"jsdoc": "^3.6.2",
"nyc": "^14.1.1",
"open": "^6.3.0",
"requirejs": "^2.3.6"

@@ -52,0 +52,0 @@ },

@@ -128,2 +128,3 @@ # glTF Pipeline

|`--stats`|Print statistics to console for output glTF file.|No, default `false`|
|`--keepUnusedElements`|Keep unused materials, nodes and meshes.|No, default `false`|
|`--draco.compressMeshes`, `-d`|Compress the meshes using Draco. Adds the KHR_draco_mesh_compression extension.|No, default `false`|

@@ -130,0 +131,0 @@ |`--draco.compressionLevel`|Draco compression level [0-10], most is 10, least is 0. A value of 0 will apply sequential encoding and preserve face order.|No, default `7`|

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc