CZML, missing dependencies, just trying to reuse Skeleton project

First of all, I am blown away by Cesium - it is exactly what I have been looking for. Aside from Dojo - which I personally find very verbose and difficult to pick up - I’m trying to start my own “Skeleton” project and have run into issues with dependencies.

Following the Skeleton project, after “Add example code here”, I’m simply trying to load the local “simple.czml” file and add the objects to the scene. After some time trying to figure out why I couldn’t use “getJson”, I gave up and made my own XHR request.

I am then stuck on the “processCzml” function, which I am told does not exist in DynamicObjectCollection. Confusing because the CZML documentation states to use the “processCzml” function.

Can anyone tel me what I am doing wrong? Thanks.

processCzml is a stand-alone function, not a member of DynamicObjectCollection. In the Skeleton, which requires in the “Cesium” helper object, you can access it using Cesium.processCzml.

“getJson” currently depends on Dojo, which is why it’s not part of the “Cesium” object, since we don’t want all Cesium users to have to depend on Dojo (I do think it’s worth learning if you have the time, start with the AMD-based 1.7 or the newly released 1.8, watch out for obsolete information out there on the net about 1.6 and previous versions).

We will be adding better support for loading CZML soon, including standalone functions for loading JSON or binary array buffers, etc. but since you know how to use XHR directly, what you have is fine.

Scott - Thanks for the extremely quick reply. I knew that getJson was part of the Dojo widgets, but I saw how other code was using it and tried to make it work - alas, I just used XHR.

So I was able to load the “simple.czml” after all, which I will show below. Unfortunately, the facilities that I expected to be added to the map (canned Cesium data from “CesiumViewer” application), were not…so I’m unsure if I need to add the dynamicObjectCollection onto the scene…or maybe the time/availability of the objects has passed (i.e. I am not using the Timeline widget)?

Cesium is some seriously cool stuff. If I only knew Dojo well…a jQuery adapter or something would be amazing. And a GWT wrapper would be even more amazing. :slight_smile:

Forgot to supply the code, which is not much different than above:

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)

I set the near plane in the skeleton to 1.0 so you can zoom all the way to the surface of the earth and see the hi-res imagery. Otherwise it would be clipped by the near plane. This will change with the DDR and the multi-frustum where most people won’t have to worry about setting the near or far plane.

Scott,

Works great, thank you so much for your time and effort - it is truly appreciated.

I’m going to work next on Billboards, adding and remove them as needed. I’ve run into one issue that I’m going to try to figure out on my own - but I can’t guarantee that I won’t seek help later. :slight_smile:

Thanks again.

  • Chris