Manually syncing Timeline, Animation, and Scene to a DataSource clock

Hi, what I'm essentially trying to do is create the Cesium.Viewer, without the Cesium.Viewer. I have a scene, camera, timeline, and animation, and everything displays correctly. But when I add a DataSource that has components that have visibility based on a date/time range, it only displays those elements if that date/time range is within 'now', meaning when the scene is displayed.

For example, I have a data source that shows objects moving over the period of a day. If that day is now (6/14) and runs until tomorrow (6/15), my objects show up and are moving (although the animation controls do not affect it).

But if the day was last week, my stationary objects show up, but the animated ones do not.
Both the Timeline and the Animation controls show the correct date/time of the DataSource.

When loaded through the Cesium.Viewer, both data sets display correctly.

I have used the Cesium.Viewer as my guideline, creating a Clock and ClockViewModel, attaching it to the Animation and Timeline controls, and using that clock to 'tick' on render.

The reason for this is I'm actually using OLCesium, a blending of OpenLayers for 2D and Cesium for 3D (because in some cases, our users don't have WebGL and we still want them to have 2D capabilities). OLCesium does not use the Viewer, but rather creates a Scene and DataSourceCollection, and manage them via a DataSourceDisplay (which I am accessing).

Unfortunately, I am unable to provide a code sample.

Hi,

It’s hard to say exactly what’s going on without seeing some code, but my guess is that you have two Clock instances kicking around your application. Keep in mind that CesiumWidget, like Viewer, creates its own Clock. You may get better results by using that instead of creating your own and wiring it up. Or are you attempting to avoid using CesiumWidget as well? I don’t think that’s usually necessary.

Since you’re interested in Cesium plus a non-WebGL 2D fallback, I can’t help but plug my own project: TerriaJS. I’m one of the developers that started Cesium, so TerriaJS is much more “Cesium first” than OLCesium. It uses Leaflet for the 2D fallback.

Kevin

1 Like

First, thanks for the reply.

Yes, I kinda suspected I had two clocks going on, but wasn't certain where the 2nd clock originated from. As far as I can tell, Cesium.Scene doesn't contain a cock, nor does Cesium.Camera, so I was kinda confused where the 2nd clock was coming from.

As far as CesiumWidget, its not that I'm trying to avoid it, its that I'm not certain I can use it. OLCesium gives me an 'olCesium' instance, which contains a Cesium.DataSourceDisplay that they manage. That contains the Scene that I'm trying to control, as well as the DataSourceCollection that my DataSource resides within.

I will take a look at TerraJS, though. OLCesium was suggested by another team just a couple months ago. It sounded good since we had previously done an OpenLayers integration, and didn't want to keep maintaining two integrations. At first it seemed we could 'resurrect' our OpenLayers interface, but unfortunately, it doesn't play well with CZML and time-based data sets, so now I'm having to interface w/ Cesium directly for some things.

Sorry, I’m not much help there. You’ll probably have to ask the OLCesium developers. It seems likely that OLCesium is creating its own Clock internally, but I wouldn’t know how to go about accessing it.

Actually, you were a big help. I decided to dig more into the OLCesium code, and discovered they were calling 'update()' on the attached DataSourceDisplay. The 'time' used in the call to update() was an internal property 'time_', which was defaulted to Cesium.JulianDate.now().

The whole process was part of their rendering loop, so even though I was setting the time in certain places in my rendering loop, theirs was setting it on the DataSourceDisplay. This caused an issue in the Cesium.Batch.update() method, specifically where it called ShowGeometryInstanceAttribute.valueOf().

There is an 'if' statement that checks 'if (show !== currentShow) {...}'. However, 'show' is undefined because the 'time' component sent to the updater.isFilled() call is not within the time scope (2 lines above the 'if').

An exception is thrown and rendering stops.

To resolve this, I provide a 'time' function when creating the OL Cesium object and check if I have a DataSource. If I do, I return the currentTime of its clock. Otherwise, I return the JulianDate.now().

Does that make sense?

1 Like