3DTiles Next, Subtree --(Problems encountered in testing 3DTiles)(Upload 3dfiles next file)

Hello, everyone
I am passing 3dfiles_ implicit_ Tiling tests the new features of 3dfiles next. But I have encountered some problems. When loading 3dfiles next, there is an error: cannot read property ‘implicitcoordinates’ of undefined. How to solve this problem.
I suspect that it is the problem of the tile availability binary data file (bin file), but the specification of this bin file is not mentioned in the official document. How to store this bin file. Is there any specification?
Looking forward to the answer, thank you.
NextTest.rar (2.8 MB)
This is the 3dtiles I generated, and the next.json is the 3dtiles next entry file, tileset_ b3dm. json is a common 3dtiles entry file. Please help me find the problem, thank you.

How to store this bin file. Is there any specification?

The format is described in the Implicit Tiling section of the specification. The relevant sections are

I know, this looks complicated at the first glance. But I’ll try to focus on what may be wrong with the example that you provided.

A small disclaimer: It can be difficult to debug something like this. The input data can have many different errors. I tried to analyze the data. And I found a few things that seem to be wrong. But I can not say for sure that this is really the reason for the error.


The error seems to be in the Data/subtree/0_0_0_0.subtree file. The JSON part of this file is the following:

{
   "buffers":[
      {
         "byteLength":74
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteLength":74,
         "byteOffset":0
      }
   ],
   "tileAvailability":{
      "bitstream":0
   },
   "contentAvailability":[
      {
         "bitstream":0
      }
   ],
   "childSubtreeAvailability":{
      "constant":0
   }
}

It is a bit unusual that tileAvailability and contentAvailability refer to the same bitstream. But this is not necessarily wrong: It only means that every available tile also has content.

But there is one important point in the specification, in the tile availability section:

  • If a non-root tile’s availability is 1, its parent tile’s availability shall also be 1.

I tried to extract the relevant information from your subtree file, and it seems like this is not the case here. My test prints the following:

Is (level=2, (3,1,1)) available? true
Is (level=1, (1,0,0)) available? false
Is (level=0, (0,0,0)) available? true

(This is just one example - there seem to be several other cases like this).

The point is: When the tile (level=2, (3,1,1)) is available, then its parent tile (level=1, (1,0,0)) also has to be available.

(If this really is the reason for the error, and if you change this, then this means that your tileAvailability and contentAvailability will be different, and will no longer use the same bitstream).


A debugging hint: I came to the assumption that this might be the reason for the error because it reached the line cesium/Implicit3DTileContent.js at a8c27a25fc4d810788a8c30f3e8ea8ba0b773fc7 · CesiumGS/cesium · GitHub in a case where the parentTile was undefined. But I’m not sure whether this is the right track.

Thank you very much for your reply. I am checking these problems you mentioned. Thank you again.

Hi,Marco13.
I have found the problem because the availability data stored in the buffer is 01 data stream, not byte data stream.After correcting this problem, the 3DTiles Next can be displayed.
But now I have encountered new problems and some doubts.That is the display effect of the 3DTiles Next is worse than that of normal 3DTiles.In 3DTiles next, the child tile boundingVolume and geometricError calculated automatically(Divided into four or eight parts depending on the
subdivisionScheme.Each child geometricError is half of its parent geometricError.)However, these two values are quite different from the parent in normal 3DTiles.
Does it means that the application scenario of 3DTiles Next is limited?
It can only apply to some strict model? I look forward to your clarification. Thank you.

Does this refer to a lower performance?

By default, the geometricError of the child tiles is half of the geometricError of the parent tile. But if you can compute better values for the geometric error, then you can store these values as tile metadata, as described in the Tile Metadata section.

This metadata allows you to store additional values for each available tile. This metadata can have a “semantic”, and one of the semantics that are listed here is the TILE_GEOMETRIC_ERROR.

For example, when you have a quadtree with a tile availability like the example from the specification, then 9 of the 21 possible tiles are available. You can then define metadata that contains the values of a property table with 9 rows. Each row of this property table will correspond to one available tile, and the value that is stored in this table is the geometric error for each of these tiles.

Hi,Marco13.
I have added TILE_GEOMETRIC_ERROR through metadata, and found that this value has been set successfully, but the disappearance effect has not been improved. Could you please help me find out the problem?
next test.zip (2.4 MB)

First, a general remark:

“3D Tiles Next” is a name for set of extensions for 3D Tiles 1.0. The functionality that is provided by these extensions is part of the core standard of 3D Tiles 1.1.

You can use 3D Tiles 1.0 and extensions like 3DTILES_implicit_tiling or 3DTILES_metadata. But I’d recommend to use 3D Tiles 1.1 instead. In 3D Tiles 1.1, you don’t need the extensions any more. You can directly use the same functionality, without using extensions. The specification for 3D Tiles 1.1 is at GitHub - CesiumGS/3d-tiles at draft-1.1

For example: In your current tileset_next.json, you have this:

    "extensions": {
        "3DTILES_metadata": {
            "schema": {
                "classes": {
                    "tile": {
...

When using 3D Tiles 1.1, you can write it like this:

    "schema": {
        "classes": {
            "tile": {
...

without the extensions/3DTILES_metadata object. See the tileset.schema.json for 3D Tiles 1.1 for details.


The tileset_next.json has some errors. For example, it contains the line

"version": "0.0"
  • If you want to use the ‘Next’ extensions, then this should be "1.0"
  • If you want to use 3D Tiles 1.1, then this should be "1.1"

Also, the root node does not define any Implicit Tiling.

  • If you want to use the ‘Next’ extension, then there should be an extensions/3DTILES_implicit_tiling object.
  • If you want to use 3D Tiles 1.1, then there should be an implicitTiling object.

Here is an archive with a tileset_next.json file where I have added the required information, and a tileset_1.1.json file that has the same functionality, but with 3D Tiles 1.1:

Cesium Forum 19618 tilesets.zip (1.6 KB)


You can open this tileset in a Sandcastle, with the following code:

const viewer = new Cesium.Viewer("cesiumContainer", {
  globe: false
});

const tileset = new Cesium.Cesium3DTileset({
  url: "http://localhost:8003/tileset_1.1.json",
  debugShowGeometricError: true,
  debugShowBoundingVolume: true,
});

viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);

The debugShowGeometricError flag may be helpful for testing: It should show the geometric error of tiles, as shown in this screenshot:

You can see that the geometric error for the root is 12112.7…, but the geometric error for the inner tiles is 31, 12, 10, … (and these should be the values from the metadata).


However, I have also seen that there are some tiles that disappear at certain zoom levels, although they should not disappear. I have not yet found out whether this is a bug in CesiumJS, or an error in the data.

Hi,Marco13.
Thank you for your reply. It’s very helpful to me.
“However, I have also seen that there are some tiles that disappear at certain zoom levels, although they should not disappear. ” That’s the problem I’m facing now, but it doesn’t exist in 3DTiles 1.0,so it makes me very confused.
If there is any new progress, please reply me again. Thank you.

I thought that the reason for the disappearing geometry might be that the geometry with the higher level of detail is somehow “invalid”. And this might be the case, but I cannot say for sure.

I tried to extract the GLB (glTF binary payload) from the B3DM files, and view them in a standalone glTF viewer. But they refer to images using a URI that contains "../images" (and thus, navigate to the parent directory), which makes them hard to use. I tried to convert them into self-contained GLB files with gltf-pipeline, but this may not have worked perfectly.

However, here are some of the resulting GLB files, with different levels:

You can see that the GLB files contain hundreds of errors. This may be the reason for the rendering errors.

When assuming that this does not cause rendering errors, then the GLB files do not contain sensible geometry: The flat building in the foreground is never displayed properly. In one GLB file, it shows the roof. In the other one, it shows the pillars. In the other one, it shows these round structures and parts of the roof.

But again: All this may be caused by the GLB errors. It’s nearly impossible to analyze that.


I also thought that the reason for the errors could be a wrong refinement strategy: The tileset JSON file currently contains

"refine": "REPLACE",

and maybe this should be

"refine": "ADD",

But again: It’s really hard to understand what the geometry should be, because it is difficult to display the GLB from the B3DM files…

Hi,Marco13.
Thank you for your reply.I have found the cause of the problem and solved it.
When I write tile’s bounding box into metadata, it can be displayed normally.I guess the reason may be that the bounding box and geometric error are not calculated according to the default mode of 3DTiles Next.
Thank you again for your help.

@Marco13 .hi,Marco13.
When I divide the tileset into one subtree, the 3DTiles next displays normally. However, when I divide the tileset into multiple subtrees (child subtrees), the problem(some tiles that disappear at certain zoom levels) reappeared.


As shown in the figure above, each child subtree has been loaded, but its geometricError and boundingBox are calculated by default. I suspect this is the reason for the problem. I tried to write the boundingBox and geometricError calculated by myself into the subtree metadata, but it did not take effect. The introduction about subtree metadata in the official documents is little. Can you help me find the problem?

In the figure above, the left side is the result of multiple subtrees, and the right side is the result of one subtree.
The following file is 3DTiles next (with child subtrees)
subtrees.zip (2.4 MB)

I had a short look at the data set. But as I said earlier: It is really difficult to just “look at” the raw data, and find out what is the reason for the error.

I have noticed one thing. This is probably unrelated to the problem that you are observing, but I’ll mention it here: The tileset_next.json contains this part:

      "subtree": {
        "properties": {
          "boundingVolume": {
            "array": true,
            "componentType": "FLOAT64",
            "count": 12,
            "semantic": "SUBTREE_BOUNDING_BOX",
            "type": "SCALAR"
          },
          "geometricError": {
            "componentType": "FLOAT64",
            "semantic": "SUBTREE_GEOMETRIC_ERROR",
            "type": "SCALAR"
          }
        }
      }

The subtree metadata is intended for the subtree as a whole. (There maybe some specific use-cases for this, but it is most likely not what you intended to do here).

Also: Trying to assign the same metadata (namely, boundingVolume and geometricError) to the tiles and to the subtree does not make sense (there is only one subtree, but it contains/defines multiple tiles.

And finally: There is no semantic that is called SUBTREE_BOUNDING_BOX or SUBTREE_GEOMETRIC_ERROR.

Again: This is probably unrelated to the error, but it appears that the data is not valid in various ways.


Somewhat related: There are currently efforts for creating a validator for 3D Tiles 1.1. (There already is a validator for 3D Tiles 1.0, but this does not yet cover the new functions like implicit tiling). The goal of this effort is to create a tool that can analyze tilesets autmatically, and point out what is wrong there (for example, when there is a problem with the availability information, or an inconsistency for the bounding volumes).

The exact timeline for this validator is not yet finalized, but hopefully, it will soon be possible to detect certain errors in the data automatically.

(I might try to allocate some time to have a closer look at the data that you provided, but it’s hard to make any promises here: Even if I find the specific error that is causing the problem, there may be further inconsistencies in this data or other data sets that should preferably be detected automatically)

hi,Marco13.
There are no SUBTREE_BOUNDING_BOX and SUBTREE_GEOMETRIC_ERROR semantic in the official document. There is not even any semantic about subtree metadata.I did this just to verify the problem.
Does this mean that cannot set boundingVolume and geometricError to child subtrees?If so, the boundingvolume and geometryerror of the child subtrees calculated by default must be very different from the tiles it contains(from tile metadata).Isn’t this a serious problem?

so could you get it working with 1 subtree file (0.0.0.subtree?)

hi bertt.
one subtree.zip (2.4 MB)
The above file is 3DTiles next (one subtree,no child subtrees), the whole tileset is treated as one subtree tree. It shows well.
I noticed that the geometrierror of the child subtree is one fourth of the topmost subtree. This seems to be correct, because the level of child subtree is 2. However, can’t we modify this value? like modify tile through tile metadata.

so why are you using child subtrees when 1 subtree file is working well?

Btw upon quick inspection I see some (validation) errors in the ‘one subtree.zip’:

  • 0_0_0_0.b3dm: validate error with b3dm byte padding

  • 0_0_0.glb does not validate

Advice: try to fix these kind of errors first before proceeding to more complex cases.

hi bertt.
I am testing my program, and I have some larger and more complex models. It is mentioned in the official document that using child subtrees can prevent subtree (one subtree) from becoming too large.
Thank you for your reply. I will check the problems you pointed out.

cool you are using the octree tiling:-) I’ll do some experiments with it.

The subtree files only define the structure of the tile hiearchy. When you have a tile hierarchy with 8 levels, then you could

  1. create subtrees with 4 levels (so there would be 2 levels of subtrees)
  2. create subtrees with 2 levels (so there would be 4 levels of subtrees)

You can assign arbitrary metadata values to the subtrees, but the important point is how these values are interpreted. CesiumJS does not use any subtree metadata right now. It only uses the tile metadata. When you want to assign a certain TILE_GEOMETRIC_ERROR to the tiles, then this value has to be stored for each tile in the subtree, and not for the subtree itself.

  • When the subtrees have 4 levels, then they would store the geometric error for each tile in the 4 levels of tiles that they contain
  • When the subtrees have 2 levels, then they would store the geometric error for each tile in the 2 levels of tiles that they contain

I just noticed another issue with the 0_0_0_0.subtree file. This issue is also not the reason for the problem, but worth mentioning here:

The jsonByteLength field of the binary subtree file format is defined to be an unsigned 64 bit integer value, as shown in the image of the specification:

This means that the bytes 0x08...0x0F store the desired value. But in your file, the bytes 0x0C stores another value, causing the byte length to become 523986011240

The reason why this does not cause any more severe errors is that CesiumJS currently only uses the bottom 32 bits, causing the right value (768) to be computed. But other viewers might use the full value, and this could cause errors, so it should be fixed nevertheless.


Edit: This seems to be the case for all subtree files…