LotsOfSatellites spinSlider code

Friends,

First off - thank you so much for creating such a great product for all of us to use. I love Cesium and I’ve really been enjoying learning to work with it.

I would like to implement a spinSlider like the one that is used on LotsOfSatellites. I looked at the code but it’s been obfuscated and included in dojo.js in that project - is there any chance anyone has the relevant code to implement such a thing so that I don’t have to re-create the handler functions / camera angle algorithms over again? Thought it might be worth asking. There’s quite a bit of calculation it seems to make such a simple effect. maybe I missed this code being avalable somewhere? I did search quite extensively.

Thanks so much!

All the Best,

    • Dan

Hi Dan,

The spin slider in Lots of Satellites is built out of a few pieces. First, in the HTML we have a dojox.mobile.Slider defined:

Then, in the setup JavaScript code, we attach a change listener using dojo/on:

// on -> dojo/on

// registry -> dijit/registry

var spinRate = 0;

on(registry.byId(‘spinSlider’), ‘Change’, function(newVal) {

spinRate = newVal * newVal;

});

Finally, before calling render, we rotate the camera using the spindleController that’s part of the CameraCentralBodyController which is added to the scene’s camera controllers. The Skeleton adds a CentralBody controller but doesn’t capture it in a variable, but you’ll need a reference to it to rotate the camera.

// calculate secondsDifference as the number of elapsed seconds since the last frame

if (spinRate > 1e-8) {

centralBodyCameraController.spindleController.rotate(Cartesian3.UNIT_Z, -spinRate * secondsDifference);

}

Essentially, this just rotates the camera around Earth’s Z-axis at a spin rate based on the value from the slider times the number of seconds since the last frame, in order to make the spin rate independent of framerate.

There’s a lot of things that can be tweaked here. The base value from the slider is squared in the change handler to make the rate non-linear, but doesn’t have to be. The min and max values of the slider can be changed. The secondsDifference value could be drawn from simulation time instead of system clock time, so that the spin reverses while animating backwards.

Let me know if this helps.

Scott,

Thank you so much - this is extremely helpful. I’ve gotten this most of the way working, but I’ve hit one last issue. When I move the spinSlider, the globe rotates as I move the slider, but it doesn’t stay rotating when Im not moving the slider. I move the slider up and down and it spins the globe at varying rates. Below is the code Im using - I’m retrofitting the CesiumViewerWidget.js, not the Skeleton. The only different from your suggestion is that I hard coded secondsDifference to 1… I didnt think that would cause this problem but maybe it is?

var spinSlider = widget.spinSlider;

var spinRate = 0;

on(spinSlider, ‘Change’, function(newVal) {

spinRate = newVal * newVal

if (spinRate > 1e-8) {

var controllers = camera.getControllers();

controllers.removeAll();

this.spindleController = controllers.addSpindle();

this.spindleController.rotate(Cartesian3.UNIT_Z, -spinRate * 1);

}

});

Looks like the problem is that you need to rotate the spindleController during update, not in response to a slider change.

Take out everything from the change handler except just the assignment to spinRate. Switch spinRate to be a property on the widget instead of a local, so that we can assign it when the slider changes, and read from it later while updating:

// this code goes in _setupCesium

widget.spinRate = 0;

on(spinSlider, ‘Change’, function(newVal) {

widget.spinRate = newVal * newVal;

});

Then, inside the update function:

var spinRate = this.spinRate;

var secondsDifference = 1;

if (spinRate > 1e-8) {

this.centralBodyCameraController.spindleController.rotate(Cartesian3.UNIT_Z, -spinRate * secondsDifference);

}

The CesiumViewerWidget already maintains a reference to the centralBodyCameraController, so you don’t need to do any adding or removing of controllers.

The update function is called on every frame, so it will continue to rotate using the last value of spinRate, which is updated whenever the slider changes.

Scott,

Everything is working now - you rock - thanks so much. It’s so hard to look at obfuscated code, and with all of the custom work inside CameraHelpers, CameraSpindleController in the definition at the top… it looked like the rotation was being done in there somehow. It’s elegant the way update is called every frame and this can be handled so easily.

VERY cool. I appreciate your time very much.

Dan,

What kind of app are you working on? Have any screenshots to share?

Patrick

I run Product Management for SOASTA (www.soasta.com) - we have a product (and a service) called CloudTest that allows you to run very large scale Performance/Load/Stress tests using cloud based load generators. Most recently we did all of the testing for the London Olympics websites and apps, as well as for the NASA Curiosity rover landing. Basically we record and play back huge amounts of traffic to make sure that sites can handle the load during peak. What makes CloudTest so cool is that all of our dashboards are real-time… they update every second with perf data like average response time, errors, etc.

We have a widget in the product today called the Activity Map (see screenshot). It shows data in real time by cloud server location… like Amazon EC2 East, RackSpace Chicago, wherever the servers are. It uses Google Maps and openStreetMaps. I ran in to Cesium while looking for cool ways to visualize data and I thought I would see if it would be possible to do a prototype globe instead of a map.

Currently I don’t have anything interesting other than my own retrofitted CesiumViewerWidget with a .czml file loaded in with like 1000 datapoints in the US. What Im really interested in is the ability to write realtime data into the globe. I’ll be getting into with that next :wink:

I think this project is awesome - you are all extremely cool for contributing this to the dev community.

Dan,

Cool use case. Cesium is a great fit. Looking forward to see how you take advantage of 3D, e.g., extruding bars from the globe based on load, etc.

Regards,

Patrick