There are some aspects of implciit tiling that are a bit hard to grasp. There are some degrees of freedom for implementations, and depending on the implementation, the purpose of certain parts may not be perfectly clear (we talked about CesiumJS apparently not using the
availableLevels, in Implicit tiling: availableLevels and IIRC a later thread).
A somewhat anecdotal example: I created an implementation for reading, traversing, creating and converting implicit tilesets. And at some point, I noticed: “Whoops. I didn’t use
childSubtreeAvailability anywhere in my code!”. Sure, I always ran this on the file system, and basically did an
if (exists(subtreeFile)) where necessary. The
childSubtreeAvailability serves - very roughly speaking - the purpose of not having to do this kind of check. One has to keep in mind that when operating on the network, this would imply sending out thousands of requests that would be answered with 404s…
One could see the information in the
implicitTiling JSON structure as two separate things.
availableLevels define the overall structure. Together with the
content.uri (i.e. the template URI), they define the overall structure of the tileset, in a very abstract sense. They just say “This is an octree with 10 levels, and the content is in stored in files called
subtrees.uri are information about how this abstract data structure is stored. It’s not possible or sensible to store the availability information for 10 million tiles and content in a single file. So the overall information is subdivided into subtrees. These subtrees are regular, and always have the same height (namely
subtreeLevels). One can imagine the overall data structure to be divided into “layers” of subtrees.
There often are different ways how certain structures can be defined, or how certain information can be encoded. This may be related to your point:
To retrieve the next level subtree file(s) it can be derived from the length of the childSubtreeAvailability (if its 4 → 1 level, if its 16 → 2 levels). When childSubtreeAvailability is empty in a subtree file I expected I could use any level for tile/content availability
If I understood this correctly, then this eventually leads to a structure where the heights of the “subtree layers” is not fixed. And that’s a valid (and interesting) point.
Until now, I think that you only intended to leave the number of levels for the “leaf subtrees” open. As a generalization (just brainstorming now: ) one could consider having an implicit tiling scheme where the first
subtree has a height of 3, and its children have a height of 5, and its grandchildren have a height of 7. This could even be very generic, as in
subtreeLevelsProgression=CONSTANT/LINEAR/EXPONENTIAL - or somehow defined explicitly for each “layer” (as in something like
subtreeHeights: [3, 5, 7, INFINITE]).
But one would have to think deeply about the implications for this on the spec- and implementation (!) level - and.whether it could be expected to have benefits that are worthwhile. Having some regularity in the subtree structure may as well be beneficial here.
(An aside: It is also true that some information can sometimes be derived from other information. For example, the
subtreeHeight could be derived from the
childSubtreeAvailability. But as you said, this only works when the latter is present, so defining this clearly and unambiguously in the spec would be hard…)
Going up a few levels: I think the overarching question here is How to make subtree division… that I linked to earlier.
When you have a tileset with 10 levels, you could choose
subtreeLevels=10,9,8...,2,1, and the resulting layout out the data itself (for the same abstract data structure!) would be vastly different. Many of them will be very wasteful - like
1. The engineering questions here start with fairly trivial ones, e.g. whether
availableLevels is divisible by
subtreeLevels. But they quickly touch topics where there is no “one true answer” - for example: Which content is actually available? This determines whether you can structure the data in a way that nicely exploits the cases where you can use
constant:0/1 for the availability. On top of that are questions like “What are sensible file sizes for
subtree files, to be transferred via network without large delays?”, or “Does the client/viewer use a smart approach to deal with this data?” (which leads to the CesiumJS issue that you linked to).
For now, I think that setting
subtreeLevels=ceil(availableLevels/2) should be a good first shot. But this is just a gut feeling for now: Every potential insight of such
trial and err… engineering has to be justified with experiments - i.e. with performance tests. And… designing these in a sensible form is a huge topic on its own…