New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add draco mesh compression #353
Add draco mesh compression #353
Conversation
Awesome @FrankGalligan and @fanzhanggoogle. One of us should have a chance to review pretty soon. Is it possible to clean up the git history a bit? |
Fixes #348 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening this PR. I did a quick 1st pass overview and things generally look pretty good. Mostly just formatting changes for now.
README.md
Outdated
|`--draco.quantizeTexcoord`|Quantization bits for texture coordinate attribute when using Draco compression.|No, default `12`| | ||
|`--draco.quantizeColor`|Quantization bits for color attribute when using Draco compression.|No, default `8`| | ||
|`--draco.quantizeSkin`|Quantization bits for skinning attribute (joint indices and joint weights) when using Draco compression.|No, default `12`| | ||
|`--draco.unifiedQuantization`|Quantize positions of all primitives using the same quantization grid defined by the unified bounding box of all primitives. If this option is not set, quantization is applied on each primitive separately which can result in gaps appearing between different primitives.|No, default `false`| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we shorten the description of this? Probably too long for an options table. We could also put it just before the table with a *
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* | ||
* @private | ||
*/ | ||
function getComponentReader(componentType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does splitting this into it's own module warrant adding tests for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the 2.0
branch doesn't have any unit tests now... but they will come before it is merged into master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I can add tests when needed.
lib/draco_encoder_nodejs.js
Outdated
@@ -0,0 +1,28 @@ | |||
module.exports = CreateDracoModule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Camel case for the filename: draco_encoder_nodejs.js
-> dracoEncoder.js
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this file is copied as-is, but we should format the spacing/tables/empty lines to maintain consistency throughout the project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something it looks like the JS encoder isn't being used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. Removed this file.
lib/compressMeshes.js
Outdated
var Cesium = require('cesium'); | ||
var hashObject = require('object-hash'); | ||
var ForEach = require('./ForEach'); | ||
var numberOfComponentsForType = require('./numberOfComponentsForType'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor pick: Let's order these (including the draco ones below) alphabetically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
|
||
module.exports = compressMeshes; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting: Remove extra empty line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
|
||
|
||
function TypeToName() { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting: Empty function should have brackets in the same line (like you did for Remove
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra empty lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
|
||
return { | ||
numComponents : componentsPerAttribute, | ||
numVertices : accessor.count, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming: Use full words. numComponents
-> numberOfComponents
. Same for numVertices
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
console.log('Found duplicate!'); | ||
// Copy compressed primitive. | ||
copyCompressedExtensionToPrimitive( | ||
primitive, hashPrimitives[hashValue]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting: Combine into same line as the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
const numFaces = indices.length / 3; | ||
const numIndices = indices.length; | ||
|
||
console.log("Num of faces: " + numFaces); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@lilleyse For the history let me see what I can do. I tried to pull your 2.0 branch into my fork and then my "add_draco_mesh_compression" branch on top of that. But this PR does not reflect the history I would have liked. |
ea553d3
to
3df32a5
Compare
The files are created according to the KHR_draco_mesh_compression specification located here: https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md
README.md
Outdated
@@ -105,6 +108,13 @@ processGltf(gltf, options) | |||
|`--separateTextures`, `-t`|Write out separate textures only.|No, default `false`| | |||
|`--checkTransparency`|Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures are considered to be opaque.|No, default `false`| | |||
|`--stats`|Print statistics to console for input and output glTF files.|No, default `false`| | |||
|`--draco.compressionLevel`|Draco compression level [0-10], most is 10, least is 0.|No, default `7`| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add compressMesh
option.here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressMeshes.js
Outdated
if (encodedLen > 0) { | ||
console.log("Encoded size is " + encodedLen); | ||
} else { | ||
console.log("Error: Encoding failed."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These console.log
s should be removed as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
OK, the history looks good. |
- Shorten unifiedQuantization options table text. - Add compressMesh to options table text. This address a comment in CesiumGS#353
CI is failing on ESLint: https://travis-ci.org/AnalyticalGraphicsInc/gltf-pipeline/jobs/354149293#L1718-L1732 |
- Removed parameters from ForEach that were not being used.
Fix comments gltfpipeline 353
@shehzan10 I fixed the lint errors in compressMeshes.js, but the error in updateVersion.js is in code I did not touch and a little harder to fix as it is the first parameter that is not used. So I can add some code like Or I could add a new function to ForEach.js like Any suggestions? |
We received a CLA from @FrankGalligan, thanks again! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. I have mostly small comments and one bigger comment about removing the uncompressed data.
bin/gltf-pipeline.js
Outdated
default : false, | ||
describe: 'Quantize positions of all primitives using the same quantization grid defined by the unified bounding box of all primitives. If this option is not set, quantization is applied on each primitive separately which can result in gaps appearing between different primitives. Default is false.', | ||
type: 'boolean' | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove trailing comma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressDracoMeshes.js
Outdated
addExtensionsRequired(gltf, 'KHR_draco_mesh_compression'); | ||
var hashPrimitives = []; | ||
options = defaultValue(options, {}); | ||
options.dracoOptions= defaultValue(options.dracoOptions, {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small tweak: options.dracoOptions =
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/compressDracoMeshes.js
Outdated
|
||
// Add attributes to mesh. | ||
var attributeToId = {}; | ||
var attributes = primitive.attributes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/removeUnusedElements.js
Outdated
|
||
/** | ||
* Removes unused elements from gltf. | ||
* This function currenlty only works for accessors, buffers, and bufferViews. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currenlty
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/removeUnusedElements.js
Outdated
* Contains functions for getting a list of element ids in use by the glTF asset. | ||
* @constructor | ||
*/ | ||
function getListOfElementsIdsInUse() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks slightly clearer if getListOfElementsIdsInUse
is capitalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So do you want it as 'GetListOfElementsIdsInUse', or 'getListOfElementsIDsInUse', or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it's probably fine as is.
lib/removeUnusedElements.js
Outdated
/** | ||
* Contains functions for getting a list of element ids in use by the glTF asset. | ||
* @constructor | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For each of the new classes mark as @private
so they don't show up in the doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/removeUnusedElements.js
Outdated
|
||
TypeToGltfElementName.bufferView = function() { | ||
return 'bufferViews'; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeToGltfElementName
can be simplified to
var TypeToGltfElementName = {
accessor : 'accessors',
buffer : 'buffers',
bufferView : 'bufferViews'
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/removeUnusedElements.js
Outdated
* This function currenlty only works for accessors, buffers, and bufferViews. | ||
* | ||
* @param {Object} gltf A javascript object containing a glTF asset. | ||
* @returns {Object} The glTF asset with the added pipeline extras. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the description, looks like a copy-paste error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/removeUnusedElements.js
Outdated
ForEach.skin(gltf, function(skin) { | ||
if (defined(skin.inverseBindMatrices)) { | ||
usedAccessorIds[skin.inverseBindMatrices] = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation in this block is slightly off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,235 @@ | |||
'use strict'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the uncompressed data get spliced out of the original buffer in all cases?
It's possible that the uncompressed attributes and a texture may be stored in a buffer, and because that texture's bufferView references the buffer the buffer won't get removed in removeUnusedElements
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently yes. I have another branch that I think should fix this issue here:
https://github.com/FrankGalligan/gltf-pipeline/commits/fix_buffer_packing
I can merge that branch into this branch. I also have some other branches as well that I want to merge. Like a fix for JOINT_ATTRIBUTES not using integer, and a branch that will add support to go from Draco glTF -> glTF.
I was going to make PRs from them after this was landed as I think it would be easier to review, but I can merge them into this this PR if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe open a PR for fix_buffer_packing
that targets this branch? The others can wait for later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This fixes an issue raised in CesiumGS#353 by @shehzan10. - Debug_checks were turned on and the check was wrong in an older version of the JavaScript encoder.
Update draco3d version dependency
@shehzan10 I fixed the issue you were having with the encoder. I updated the npm package, so if you update your dependencies this should compress now. There isstill an issue with the writing of the gltf, which I'm looking into. |
Can confirm that the updates fix the crashing models.
Writing to disk looks ok, I guess. But, it looks like the test model fails to load for compression level 7 and above and works for 6 and lower. |
@shehzan10 Yeah so the decoder has the dcheck as well. It the decoder is using the nodejs modules and they update it should be fine. Otherwise they will have to wait until we push the fixes to github. We are not pushing the changes until the week of 4/16. |
-The old code would turn on Draco compression if the file had the text "draco" in it. -This fixes #18
Fix draco parameter handling
@FrankGalligan can you update this to draco 1.3 and fix the remaining comments from @lilleyse? I think we should be able to merge then. |
- Also fixes some comments in CesiumGS#353
Update draco3d to 1.3.0
@shehzan10 Updated to 1.3. Waiting on one comment form @lilleyse |
The bufferView's for inlined images was not being processed.
Fix inline images
The code changes looks good. We're just going to do some final testing. |
All good here - thanks @FrankGalligan |
The Draco glTF files created with gltf-pipeline will be created according to the KHR_draco_mesh_compression specification located
here:
https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md