Skip to content
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

Refinement of mixed empty and non-empty tiles #9356

Closed
seepa opened this issue Feb 1, 2021 · 4 comments · Fixed by #11843
Closed

Refinement of mixed empty and non-empty tiles #9356

seepa opened this issue Feb 1, 2021 · 4 comments · Fixed by #11843

Comments

@seepa
Copy link

seepa commented Feb 1, 2021

Hello,

I'm building a level-of-detail structure of triangle meshes (Cesium 1.77) where some nodes in the tree can be empty (i.e. no "content" field, only geometric error, bounding volume and children are set).

Let's assume my tree has 7 levels, where level 7 is the coarsest and level 0 the most detailed representation. Each non-empty tile is stored as a single b3dm file. My question is regarding the refinement of a node on level 7 that has one empty and one non-empty child:

level 7:         non-empty          GE: 200
                 /      \
level 6:     empty     non-empty    GE: 100
level 5:     empty        .         GE:  50
level 4:     empty        .         GE:  25
level 3:     empty        .         GE:  12
level 2:   non-empty      .         GE:   6
level 1:   non-empty      .         GE:   3
level 0:   non-empty   non-empty    GE:   1

(The geometric error "GE" decreases when going down the tree and is the same for all nodes on a given level. The refinement strategy is "REPLACE".)

When level 7 is to be refined, I see that the non-empty child on level 6 gets fetched (its b3dm file) by the browser, while the empty child is not. For this reason, the level 7 tile is never refined.

Adding "content" : "" to the empty level 6 node and all following empty nodes, causes level 7 to be refined. However, the non-empty level 2 tile is shown instead of the empty level 6 tile essentially showing two very different geometry resolutions at the same time.

Instead, I would expect that the level 7 tile is replaced by its two immediate children on level 6 (one empty and one non-empty) and only when I keep zooming in, the non-empty level 2 tile would eventually be displayed.

What is the intended behavior in this case? Regarding the "content" field, I think there could be a bug because it is not required as per specification but leaving it out causes level 7 to never be refined.

For reference, I've found this report from a while ago which seems to describe a similar setup: #7084 (comment)

Thankful for any help or pointers!

@lilleyse
Copy link
Contributor

lilleyse commented Feb 4, 2021

The reason this happens is CesiumJS avoids refining unless all descendants with content are loaded, specifically to prevent empty regions from showing.

To get the more traditional replacement refinement behavior you might be able to replace this line with childRefines = true

childRefines = executeEmptyTraversal(tileset, child, frameState);

It's possible this could be added as an option for Cesium3DTileset.

@seepa
Copy link
Author

seepa commented Feb 9, 2021

Thanks for the explanation!

For now, we're only creating the tilesets but do not have control over the viewer and the options set there.

Is there a good (sustainable) way to make a tileset with empty nodes work with the current default settings?

As mentioned above, leaving out the content field causes the tile to not get refined at all. This is contrary to the specification where the content field is listed as optional. Furthermore, while adding an empty content field works, it raises the question if it will break with future versions because as to the spec, the content field at least needs the uri field. Since the tile is empty, we cannot specify any uri...

@jerstlouis
Copy link

jerstlouis commented Aug 2, 2021

We encountered this issue in the OGC Interoperable Simulation & Gaming Year 2 Sprint, spent a lot of effort trying to figure out the problem, and had to implement an awkward work-around in our server to generate an empty .b3dm to work around this issue. According to my opinion and my interpretation of the 3D Tiles specifications, this is a problem in the CesiumJS client library.

Specifically, in REPLACE refinement mode, CesiumJS should consider a child node with no content but with children, not yet refined because its geometric error is still acceptable, as "loaded" so that its siblings can be refined.

@lilleyse
Copy link
Contributor

I opened an issue in the 3d-tiles repo related to this: CesiumGS/3d-tiles#609. CesiumJS probably shouldn't have special treatment for empty tiles since the spec doesn't make any such distinction for empty vs. non-empty tiles for refinement. Though the word considered arguably adds some leeway.

In a client implementation, geometric error is used with other screen space metrics—e.g., distance from the tile to the camera, screen size, and resolution— to calculate the SSE introduced if this tile is rendered and its children are not. If the introduced SSE exceeds the maximum allowed, then the tile is refined and its children are considered for rendering.

Also, cesium-native doesn't have the special treatment for empty tiles in its traversal code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants