-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Added Draco support to point clouds #6559
Conversation
@lilleyse, thanks for the pull request! Maintainers, we have a signed CLA from @lilleyse, so you can review this at any time.
I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome. 🌍 🌎 🌏 |
068629e
to
9cfba49
Compare
Source/Workers/decodeDraco.js
Outdated
dracoDecoder.GetAttributeInt32ForAllPoints(dracoGeometry, attribute, attributeData); | ||
var vertexArray = new Uint16Array(vertexArrayLength); | ||
var attributeData = new draco.DracoUInt16Array(); | ||
dracoDecoder.GetAttributeUInt16ForAllPoints(dracoGeometry, attribute, attributeData); |
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.
While working on decodeDracoPointCloud
I realized my suggestion to use Int16Array
for oct-encoded attributes was incorrect, so I fixed it here as well.
} | ||
|
||
dracoModule(wasmConfig).then(function (compiledModule) { | ||
initWorker(compiledModule); |
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.
What happens if we are decoding a Draco model and a Draco point cloud at the same time? Since it's a fairly large module, do we want to load it twice?
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.
Hm that's a good point.
I guess caching the binary is an option but I'll see if combining decodeDraco
and decodeDracoPointCloud
into the same worker is doable. That would also address https://github.com/AnalyticalGraphicsInc/cesium/pull/6559/files/c5870f8cd097b235f67e2e460e7430d8c4506bc4#r185930196.
Source/Workers/decodeDraco.js
Outdated
}; | ||
} | ||
draco.destroy(transform); | ||
|
||
transform = new draco.AttributeOctahedronTransform(); | ||
if (transform.InitFromAttribute(attribute)) { | ||
quantization = { | ||
quantizationBits : transform.quantization_bits(), | ||
octEncoded : 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.
ModelUtility.modifyShaderForQuantizedAttributes
will need to be updated accordingly.
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 also explains the test failures. I'll add octEncoded
back in.
attributeData = new draco.DracoFloat32Array(); | ||
vertexArray = new Float32Array(vertexArrayLength); | ||
dracoDecoder.GetAttributeFloatForAllPoints(dracoGeometry, attribute, attributeData); | ||
break; |
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 seems like a lot of duplicate code with decodeDraco
, and this function in particular is identical. Can we share this somehow?
CHANGES.md
Outdated
@@ -7,6 +7,10 @@ Change Log | |||
|
|||
* Fixed a bug causing custom TilingScheme classes to not be able to use a GeographicProjection. [#6524](https://github.com/AnalyticalGraphicsInc/cesium/pull/6524) | |||
|
|||
##### Additions :tada: | |||
|
|||
* Added support for loading Draco encoded Point Cloud tiles [#6559](https://github.com/AnalyticalGraphicsInc/cesium/pull/6559) |
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.
Add a tad more detail, e.g., "compressed", not "encoded", and something like "up to 10x" or whatever compression.
throw new RuntimeError('DRACO.semantics, DRACO.byteOffset, and DRACO.byteLength must be defined'); | ||
} | ||
|
||
var dracoHasPositions = dracoSemantics.indexOf('POSITION') >= 0; |
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.
Here and below, maybe put the righthand side in parentheses.
u_quantizedVolumeScaleAndOctEncodedRange : function() { | ||
var scratch = scratchQuantizedVolumeScaleAndOctEncodedRange; | ||
if (defined(content._quantizedVolumeScale)) { | ||
scratch.x = content._quantizedVolumeScale.x; |
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.
Use Cartesian3.clone
?
5803b15
to
a79b93f
Compare
fded814
to
8e551be
Compare
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.
Only the wasm
decoder file was updated? Does the fallback js module also need an update?
hasNormals = defined(dracoFeatureTableProperties.NORMAL); | ||
hasBatchIds = defined(dracoFeatureTableProperties.BATCH_ID); | ||
isTranslucent = defined(dracoFeatureTableProperties.RGBA); | ||
isQuantizedDraco = hasPositions && content._dequantizeInShader; |
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.
With the model implementation, we determine per attribute if quantization (and oct-encoding) is is available using AttributeQuantizationTransform.initFromAttribute rather than assuming it's present. Is that an approach we want to take here?
@@ -0,0 +1,27 @@ | |||
{ | |||
"asset": { | |||
"version": "0.0" |
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.
Change to 1.0
}, | ||
"geometricError": 0, | ||
"content": { | ||
"url": "pointCloudDraco.pnts" |
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.
url
-> uri
@@ -0,0 +1,27 @@ | |||
{ | |||
"asset": { | |||
"version": "0.0" |
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.
1.0
}, | ||
"geometricError": 0, | ||
"content": { | ||
"url": "pointCloudDracoBatched.pnts" |
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.
url
-> uri
@@ -0,0 +1,27 @@ | |||
{ | |||
"asset": { | |||
"version": "0.0" |
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.
1.0
}, | ||
"geometricError": 0, | ||
"content": { | ||
"url": "pointCloudDracoPartial.pnts" |
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.
url
-> uri
|
||
if (parameters.dequantizeInShader) { | ||
dracoDecoder.SkipAttributeTransform(draco.POSITION); | ||
dracoDecoder.SkipAttributeTransform(draco.NORMAL); |
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.
Do we want to include generic attributes here, for RGB
, RGBA
, etc?
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 didn't include them because the other attributes like RGB
, RGBA
, intensity, and classification usually decode to 8-bit values and decoding to quantized form won't provide any GPU memory savings.
|
||
quantization = undefined; | ||
function decodePointCloud(parameters) { | ||
var dracoDecoder = new draco.Decoder(); |
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 don't think we are destroying the decoder anywhere once we're done.
var scale = quantization.range / (1 << quantization.quantizationBits); | ||
content._quantizedVolumeScale = Cartesian3.fromElements(scale, scale, scale); | ||
content._quantizedVolumeOffset = Cartesian3.unpack(quantization.minValues); | ||
content._quantizedRange = (1 << quantization.quantizationBits) - 1.0; |
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.
._quantizedRange
!== quantization.range
? Maybe clarify terminology 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.
Yeah this is kind of confusing. I'll add a comment to the code in #6721 because the behavior changed slightly:
https://github.com/AnalyticalGraphicsInc/cesium/pull/6721/files#diff-e12a976367111c8fb95abea65e0b6ab0R1228
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.
Comment added here: 6161a96
|
||
PointCloud3DTileContent.prototype.update = function(tileset, frameState) { | ||
var context = frameState.context; | ||
var decoding = decodeDraco(this, context); |
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 be written more concisely as
if (decodeDraco(this, context)) {
return;
}
As part of this, should we also finish up CesiumGS/3d-tiles#310 ? |
Yes! I need to get back to that. |
This happens in master too. At a glance the bounding volumes look correct but it's almost like it's using the wrong one for the zoom. I'm not sure if it's a model problem or a decode problem, but I don't think it's related to this PR. Maybe we should open a separate issue to investigate it? |
Good point, and I think there has been another Draco release since then. I'll update the files tonight. |
Opened a 3d-tiles-tools PR for the sample tilesets: CesiumGS/3d-tiles-validator#150 |
@ggetz updated the Draco files to 1.3.3. |
} | ||
|
||
content._parsedContent = { | ||
positions : positions, | ||
colors : colors, | ||
normals : normals, | ||
batchIds : batchIds, | ||
styleableProperties : styleableProperties | ||
styleableProperties : styleableProperties, | ||
draco : { |
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 draco
property should probably remain undefined unless the extension is used.
Yeah we should open an issue if it's happening master. |
@lilleyse besides those two comments, this looks looks good, thanks! |
Opened #6784 for the zooming bug. Updated. |
Yup, should be ready to review now. |
Adds support for reading Draco encoded pnts files.
Merge #6558 first - one of the tests here fails without that fix.
To-do: