Closed lilleyse closed 5 months ago
This issue originally referred to the upgrade from "pre-1.0" to "1.0" tilesets. Some of the bullet points have therefore been addressed already, or are tracked in dedicated issues, or have become obsolete (the latter also insofar that gltf-pipeline
does the actual upgrade of glTF data).
The question of the scope of the upgrade
command is still relevant, though, and maybe now more than before, because it may now refer to upgrading 3D Tiles 1.0 to 1.1.
There is a (somewhat preliminary) set of options in the TilesetUpgrader
class that show what the upgrade is currently doing, and this includes some of the bullet points from above.
Beyond that, one could consider to extend the upgrade
functionality to cover more of what is described in the 3D Tiles 1.0 to 1.1 migration guide for tile formats.
The migration guide gives a few hints about how to "emulate" several features of the previous tile formats in glTF. I'll try to start sorting out which of these steps could be part of an automated process.
On the highest level, the entry point would be to add this functionality to the TilesetUpgrader
. It should be possible to enable/disable the upgrade based on the input type, so there would probably be upgradeB3dmToGlb
, upgradeI3dmToGlb
, and upgradePntsToGlb
flags in the UpgradeOptions
in the TilesetUpgrader
.
(The case of CMPT is special in many ways, and has to be discussed separately)
The actual upgrade functionality would then be implemented in the TilesetUpgrader
. This upgrade will include modifications to the tileset JSON. These modifications will at least be things like changing the content.uri
from .b3dm
to .glb
. But it may be even more, for example, when converting a (single-content) .cmpt
into a (multiple-contents) list of .glb
contents.
(The latter has some constraints, though. It may not be done for implicit tile content, for example....)
A large part of the infrastructure for this kind of modification already exists. For example, the b3dmToGlb
functionality that is currently part of the pipeline content stages could also be applied to do more than just extracting the GLB from the B3DM. So on this level, many migration steps can be boiled down to the seemingly trivial core:
"The migration function receives a B3DM/PNTS/I3DM buffer. It creates an equivalent GLB buffer"
And what "equivalent" means, is sorted out in the following sections
A large part of the features from the legacy tile formats can be migrated automatically. In the first versions, there will be some things that are not migrated yet, but will be migrated in future versions. But there also are cases that can "never" be migrated automatically. One overarching question is how to handle that. A high-level, straightforward approach could be to examine the input data and its Feature Table and Batch Table, and if it contains anything that can not be migrated, then just print a warning and leave the content unmodified.
RTC_CENTER
For all tile formats, the migration guide says
The
RTC_CENTER
can be added to the translation component of the root node of the glTF asset.
There already is a function for replacing the CESIUM_RTC
extension in a glTF with such a node transform (in GtlfUtilities
). Extending that to be a function like applyRootTransform(gltf, center)
would be trivial, and then it could be made part of the upgrade
command. Whatever the input tile format is: We'd parse the Batch Table JSON, extract the RTC_CENTER
, and pass it to that function.
This applies to all tile formats as well. The actual ID can be translated into the EXT_mesh_features
extension. This should not be much more than translating the _BATCHID
into a _FEATURE_ID_0
attribute 🤞
Translating the contents of the Batch Table into glTF may be a bit more tricky. Broadly speaking, it would involve translating the current Batch Table JSON information - specifically, the "binary body references" - into a 3D Metadata representation, and the Batch Table binary data into property attributes, so that they can be represented with the EXT_structural_metadata
extension.
It should be possible to implement that somewhat generically, juggling only with JSON and buffers, and I don't foresee any "large" technical hurdles here - roughly speaking: EXT_structural_metadata
is more powerful/expressive than the Batch Table, so it should be possible to convert everything without losing information, with two caveats:
INT8
or a FLOAT64
has to be based on "guesses" from the actual values. This may involve pseudocode functions like allAreIntegers(data)
, allAreIntegersBetween(data, UINT8.min, UINT8.max)
, and so on.3DTILES_batch_table_hierarchy
. I don't know how widely it is used, and therefore, how important it is to be able to migrate that, and whether it's possible to translate this without losses (and without too obscure quirks) There actually already is code for translating batch tables to glTF metadata in cesium-native
, at https://github.com/CesiumGS/cesium-native/blob/26f54b617984ec3c5c9015aa2927c7fe2688120e/Cesium3DTilesSelection/src/BatchTableToGltfFeatureMetadata.cpp . I haven't looked at the details, in terms on how complete it is, or even which glTF extension it is targeting - it sounds like it's not necessary the latest version of the proposed glTF extensions - but it also includes code that mentions Batch Table Hierarchies, so it might be a good start to get an idea about how this can be translated at all.
This could be easy for the case of plain point cloud data data. For quantized/compressed data, there are some possible (incremental) stages that could be supported.
It's hard to make an estimate about how many PNTS files in the wiled actually use quantized positions, normals, or colors, or certain forms of compression. But assuming that there is a considerable number of PNTS files that do not use quantization or compression, this conversion could be a good candidate for a first upgrade functionality that is offered.
Looking at the point semantics:
VEC4
or VEC3
So these could be handled relatively easily.
The POSITION_QUANTIZED, RGB565, and NORMAL_OCT16P point semantics can not directly be represented in standard glTF. A possible "roadmap" for supporting them could be:
KHR_mesh_quantization
. For normals, one could also consider the EXT_meshopt_compression
octahedral filter(Different test cases for point clouds that contain these features can be found via https://github.com/CesiumGS/cesium/blob/db2669aae149e965a3578fd0343384a33f83543c/Specs/Scene/PointCloud3DTileContentSpec.js#L35-L70)
The PNTS format supports special forms of compression - including Draco compression via 3DTILES_draco_point_compression
. This is currently not supported in glTF, due to https://github.com/KhronosGroup/glTF/issues/1809. Similar to the quantized case, there are possible stages of support:
EXT_meshopt_compression
extension in glTFFor both the compressed and quantized cases, one could consider building some infrastructure that may be useful, even outside of the context of ~"trying to upgrade some particular data". Having generic functions like
const points : IterableIterator<Cartesian3> = readPoints(source);
writePoints(target, points);
that hide the question of whether the "source" and "target" are quantized or compressed could be useful in other areas as well. The degree of generalization (or how much effort to put into that) would have to be decided.
Beyond the batch IDs and Batch Tables (mentioned above), there is not much that has to be converted here.
The main chunk of work for this upgrade is covered with the Batch Table conversion (mentioned above).
The actual instancing can be translated into EXT_mesh_gpu_instancing
.
Similar to the "Quantized data in PNTS" section: There are some properties thare are quantized, and there are the same three possible "Stages" for upgrading them:
EXT_mesh_gpu_instancing
(may increase the file size)The last one refers to EXT_meshopt_compression
: I'll have to read the spec here to see whether this can actually be applied to the data that is used for the transforms in EXT_mesh_gpu_instancing
(i.e. whether it's possible to combine these extensions in that manner)
Whatever is done for CMPT, it has to be applied "recursively": For example, the CMPT may contain one CMPT (with an I3DM and a B3DM), and another B3DM. The I3DM and B3DMs would have to be migrated first, converting them into GLBs. The result would always be a list of GLBs.
Then, broadly, there are two possible ways of handling this list of GLBs:
contents
The first one would probably be pretty easy: The functions for extracting all GLBs from a CMPT are already there (as part of the cmptToGlb
command). The functions for converting a single (explicit) tile content
into multiple contents
would also be easy to add into the tilesetProcessing
classes.
But the second option - creating a merged GLB - would be preferable, for two reasons:
contents
(causing 100 web requests when loading). The structure would be closer to what has been modeled with the CMPT(The problem with converting CMPT in implicit tiling into multiple GLB contents is that the CMPTs that are referred to by a single template URI may eventually contain different numbers of GLBs. It is not clear how many GLB template URIs there should be)
However, it's not entirely trivial to "merge arbitrary GLBs". It may be trivial in most cases that are relevant for Cesium/3D Tiles: There's usually a bunch of mesh primitives, materials, texture, and they can probably just be shoved into a single asset without hassle. But as soon as there is something like animations, morphing, multiple scenes, it is probably not possible to do this in an automated way (at least not without requiring many asumptions or some form of input about what the resulting structure should be).
If this was supposed to be tackled by merging the GLBs into one:
gltf-pipeline
? The latter would make more sense - but in doubt, first, internal, (possibly incomplete) implementations of that functionality could be part of the tools, and moved to gltf-pipeline
when they reach a reasonably complete/mature stateJust to have a back-link here: There are some points about a possible upgrade from 3D Tiles 1.0 to 1.1 summarized in https://github.com/CesiumGS/3d-tiles/issues/592#issuecomment-982634526 that may have to be taken into account here.
A short update: Most of the functionality for the generalized upgrade has been implemented in https://github.com/CesiumGS/3d-tiles-tools/pull/41 and https://github.com/CesiumGS/3d-tiles-tools/pull/52 .
The remaining (open) task is that of upgrading CMPT files. There are some caveats (as described in detail in the previous comment), so this may not be tackled immediately. But the approach of "merging the (resulting) GLBs" could be worth a try, because for the kind of data that usually appears as tile content, this could be implementable with glTF-Transform with reasonable effort.
A small update: The conversion of CMPT to GLB has been implemented as part of https://github.com/CesiumGS/3d-tiles-tools/pull/117 (with caveats, corner cases, and limitations laid out in the PR, and the comment above)
Now, from the list that was posted when we were still young, there are two main points left:
The latter made its way into the specification, But it was pretty late, and caused some "disruption" like https://github.com/CesiumGS/cesium/commit/4b3b4186b4afa2307d7d1666569826d864b984ca and many (other) ("legacy") data sets that are "invalid" due to some alignment errors.
Some of this is already handled via the functionality of converting the "legacy" tile formats to GLB. But one could make a case for offering a command that just takes contents like B3DM and fixes the alignment requirements, with as few other changes as possible. Maybe this should be tracked in a dedicated issue...?
@javagl I think this issue is closeable now, after 6 years 😄
But one could make a case for offering a command that just takes contents like B3DM and fixes the alignment requirements, with as few other changes as possible. Maybe this should be tracked in a dedicated issue...?
Feel free to open a separate issue. Though this would be lower priority.
🎉 👴
A command for fixing the alignment may have low-priority, but ... it should also not be sooo difficult, so maybe I'll try to sneak it in, as a recreational task for some boring weekend. Tracked at https://github.com/CesiumGS/3d-tiles-tools/issues/134
Tentative changes for
1.0
that should be handled in theupgrade
commandasset.gltfUpAxis
removedBATCHID
to_BATCHID
Progress is in https://github.com/AnalyticalGraphicsInc/3d-tiles-tools/tree/2.0-tools