-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Time dynamic 3D Tiles support #12977
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
base: main
Are you sure you want to change the base?
Conversation
Thank you for the pull request, @javagl! ✅ We can confirm we have a CLA on file for you. |
The PR has been updated with a first draft of an implementation. This does not fully reflect the latest state of all decisions. There are several open questions. But can serve as a preview. Data sideThe dynamic content definition contains information like the following: "dynamicContents": [
{
"uri": "content-2025-09-25-revision0.glb",
"keys": {
"exampleTimeStamp": "2025-09-25",
"exampleRevision": "revision0"
}
},
{
"uri": "content-2025-09-25-revision1.glb",
"keys": {
"exampleTimeStamp": "2025-09-25",
"exampleRevision": "revision1"
}
}
] Each entry indicates which content (URI) should be shown for the respective configuration of Application sideIn the application, the selection of the dynamic content is governed by a structure like the following:
Yes, this returns a fixed dummy value here. The point is: There is that "dynamic contents property provider" that provides the properties that should be used for selecting the active content at any point in time. (See the Sandcastle in the example for details). Connecting the twoThe main work for wiring this together is currently in a class called The The
without having to care about what that Combining these functionalities, the
Based on that, during its The class maintains the ExampleThe following is an example tileset and a sandcastle. The tileset contains a single dynamic content. It defines 64 time stamps and 3 "revisions", meaning that it has 192 actual contents. The follwing screencap summarizes a few aspects that can be tested with the sandcastle:
|
Until now, the dynamic contents information was fetched from an extension in the A strong reason for treating it as a new content type is that this should simplify using dynamic contents within implicit tilesets. So I created an example for that as well. Here's a screencap of that example: The previous test data (explicit) and the new data set (implicit) both with using that new content type are attached here, together with the Sandcastle: (Note: I have a bunch of infrastructure for ~"creating test data like that". This was developed in my spare time, off-the-clock. Tweaking it for cases like this sometimes requires a bit of fiddling and copy-and paste and hacks and manual steps, and now there's a |
The issue about Time-dynamic 3D Tiles has recently has been addressed on the side of the specification, with draft extension PRs. The subsequent comments in this issue already dived into details of the proposed extensions and approach. This has some overlap to some discussion in one of the specification PRs.
I'll try to summarize some of the points that are relevant for the interplay between the specification and the implementation within CesiumJS, both in terms of the approach that will be taken, as well as questions that still have to be addressed.
Representation
The original proposal suggested to use the 'multiple contents' concept of 3D Tiles to represent time-dynamic tiles. The idea was to associate a time range with each content (using metadata), and select the respective content for rendering depending on the time range.
After some discussion, the intention is now rather to separate the concepts of "multiple contents" and "time-dynamic content". There are many open questions about the concept of "time-dynamicness" (some listed below). Having a clean slate offers more degrees of freedom for what can go into the specification, and reduces the risk of interfering with existing aspects of the implementations.
Two options have been considered for this separation:
tile.content
.timeDynamicContent.json
:The current intention is option 2., to define it as a new content type. A summary of the reasoning:
timeDynamicContent.json
with an additional time stamp, than to re-process and modify the whole tileset JSONFor explicit tilesets and the first draft implementations, the different ways of separating the data does not matter so much. The pseudocode difference is that of
const d = tile.getExtension(...).dynamicContent;
vs.const d = tile.content.dynamicContent;
There are maaaany low-level quirks omitted here. But one important point is that the content can be created either with the object that was fetched from the tileset JSON, or the one that was loaded from the content JSON file.
In any case, there will be a top-level extension object in the tileset JSON that describes the structure of the dynamic content in more detail.
Features and capabilities
The efforts (and names) focus on time-dynamic 3D Tiles. That's the primary use-case. The seemingly philosophical question "What is 'time'?" is important in this context:
"übermorgen"
. Whatever the representation is, it could turn out to be wrong (or have severe drawbacks and limitations) for certain use-cases.const content = getContentFor(time);
Based on some discussion in the linked issues/PRs, the "dynamicness" for 3D Tiles should not be limited to "time" (given that we cannot even say what that is). There could, for example, be different "revisions" of the same tileset, and it should be possible to dynamically change which revision is displayed. At this point, "time" just becomes "one dimension in the space of things that can be displayed".
One important distinction is whether these dimensions are discrete (like 'revisions'), or continuous (like some forms of 'time'). The continuous dimensions would require some form of "binning/discretization", based on "intervals/ranges". There are some options about where and how this discretization could take place.
The current intention is to only have discrete keys for the dynamic contents. An overly suggestive example:
There is a representation of dynamic contents, with different revisions. The application will determine which of the contents should be displayed. The "exampleRevision" could be selected with a dropdown menu. The "exampleTimeStamp" could be selected by the application as well. For example, when the "time" is a value in [0,1], then a "time" of 0.2 could be clamped to
0
and cause the selection of the"time0"
time stamp.Implementation
There are several open questions for the implementation, on various levels. Most of the subsequent comments here will likely revolve around the question of "(Oh dear), how are we going to handle that?". An attempt to sumarize the current state, open questions, and considerations:
Dynamic3DTileContent
class. This class is-aCesium3DTileContent
. Most functions in this interface are underspecified. Many functions that could make sense are missing. Nearly all implementations of nearly all functions are just returning "dummy" values (just0
orundefined
), because they simply don't make sense for what constitutes "(tile) content". And for nearly all functions, there are deeeep questions about what they should do for "dynamic content". For example: It is not clear whether theCesium3DTileContent.trianglesLength
implementation should return the number of triangles that are currently loaded, or the triangles that are currently displayed. Both options will be wrong in one way or another.Cesium3DTileContentState
. For whatever reason, thiscontentState
is stored in the tile, and not the content. (Corollary: It should be part of theCesium3DTileContent
interface!). Dynamic content can not go thorough the fixed sequence of states (likeLOADING
->PROCESSING
->READY
) that is assumed for other contents. Which state it should be in, at which point in time, has to be decided. (MaybeEXPIRED
could be (ab)used to represent state transitions here, but that remains to be investigated).update
function and theready
flag. Dynamic contents is either "alwaysready
" or "neverready"
. It will likely be the former, but ... someupdate
will still have to be called, even when it already counts asready
. More generally: TheCesium3DTile
class has about 15 properties that reflect the state of (and should be stored in) its content, including flagshasEmptyContent
,hasRenderableContent
,hasMultipleContents
,hasTilesetContent
, andhasImplicitContent
, which should not exist to begin with, and which can neither betrue
norfalse
for dynamic content.Dynamic3DTileContent
class has to load other contents. And it has to do this dynamically. I tried to take inspiration fromMultiple3DTileContent
, but this has limitations that should be fixed independently. TheDynamic3DTileContent
class has to send out requests, wait for the responses, post-process that content, and possibly unload content that is no longer "needed" (until the user drags the time slider, and it is needed again). I'm currently trying to create sorts of "utility classes" for all that, but this pretty much experimental.(The pull request template is omitted for now. It will be inserted before this is converted to 'Ready For Review')