Looks like you’re close. The general overview of the DynamicScene layer is that a DynamicObjectCollection just contains scene description data, loaded from CZML (or loaded any other way, e.g. created programmatically). The Visualizers are responsible for interpreting that data, and managing the construction and updating of Cesium primitives at a given time.
I’ve attached a Skeleton.js that loads a CZML file and renders the contained objects. I just used the simple.czml file from the CesiumViewer.
I had to adjust the near and far plane of the camera:
var maxRadii = ellipsoid.getRadii().getMaximumComponent();
scene.getCamera().frustum.near = 0.0002 * maxRadii;
scene.getCamera().frustum.far = 50.0 * maxRadii;
Any Cesium developers know why the default near plane in the Skeleton is 1.0? That seems far too low, and made the scene much slower, glitchier, and basically unusable.
The parts I added are:
var clock;
var animationController;
var dynamicObjectCollection = new Cesium.DynamicObjectCollection();
var visualizers = Cesium.VisualizerCollection.createCzmlStandardCollection(scene, dynamicObjectCollection);
var url = ‘…/…/Apps/CesiumViewer/Gallery/simple.czml’;
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, url, true);
xhr.onreadystatechange = function(e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var czml = JSON.parse(xhr.responseText);
Cesium.processCzml(czml, dynamicObjectCollection, url);
clock = new Cesium.Clock();
var availability = dynamicObjectCollection.computeAvailability();
if (availability.start.equals(Cesium.Iso8601.MINIMUM_VALUE)) {
clock.startTime = new JulianDate();
clock.stopTime = clock.startTime.addDays(1);
clock.clockRange = Cesium.ClockRange.UNBOUNDED;
} else {
clock.startTime = availability.start;
clock.stopTime = availability.stop;
clock.clockRange = Cesium.ClockRange.LOOP;
}
clock.currentTime = clock.startTime;
clock.multiplier = 60;
animationController = new Cesium.AnimationController(clock);
}
}
};
xhr.send(null);
The clock logic is copied from the CesiumViewerWidget, but essentially it configures the clock to match the availability of the data in the CZML file. There’s some logic in there to deal with a CZML document with infinite availability (which means all objects in the scene exist across all time), but I don’t think it’s quite right.
The dynamicObjectCollection is constructed empty, and then later when the JSON loads async, it’s populated with the processed CZML.
Then later in the file, I replaced the scene’s animation callback with:
scene.setAnimation(function() {
if (typeof animationController !== ‘undefined’){
var currentTime = animationController.update();
visualizers.update(currentTime);
}
scene.setSunPosition(Cesium.SunPosition.compute(currentTime).position);
});
This animation function is called by the scene automatically before each render, which gives us a chance to update the animation controller (tick the clock, essentially), and call the visualizer collection’s update function with the new time, so that it can create or change the primitives in the scene.
There’s no UI here for controlling the clock or the animation controller. Hooking up the Timeline control is one option, but really any UI would be fine in any framework. It just has to change the clock’s currentTime to skip around, or call methods on the animation controller to pause/play or adjust the multiplier.
Let me know if this helps. The exercise of putting this together was useful for reminding me that we still have work to do in building up the API, because right now the CesiumViewer app has too much functionality itself internally. In the long run, the CesiumViewer app should be just wire-up for more general functionality in Cesium itself.
Skeleton.js (5.53 KB)