[cesium-dev] Updating ellipses position?

The low-level Primitive instances have no concept of their geometry being updated. You actually need to remove the ellipse and recreate it every time it changes. This is largely because Primitives closely reflect how the underlying graphics hardware works. The Entity API handles this kind of stuff for you, but honestly highly dynamic geometry like this is one of the slower parts of Cesium. We will eventually have support for what is known as “dynamic buffers” in the geometry layer which will greatly improve performance, but it’s not on the near term roadmap.

Depending on how many ellipses you have, you’ll probably be fine doing the adds and removes, just make sure you create the primitives synchronously so that there isn’t a lag between the old and new values.

I need to create around 1000 and update them twice every second, this does not hold.

What I did is calculating the ellipses positions on my own and draw them using polylines which I can change.

This holds, kinda.

May I ask why wont you allow us to change the geometry (considering I disable geometry removal) and force a call to the Primitive.update function ?
After a couple of hours reading your code it seems to me It should work, but I guess it wouldn’t since you do not allow it.

The reason updates are slow is not because the Primitive is unmodifiable, it’s slow because of two things

  1. Overhead of transferring updated geometry to the GPU (this would be greatly improved by the dynamic buffers I spoke of in my original replay)

  2. The time it takes to calculate the new mesh for the geometry (this is greatly reduced if you are simply using outlines, but still there).

PolylineCollection is a potential workaround, but for large ellipses the lines will cut through the surface of the earth (small ellipses would be fine).

I threw together a quick (and naive) example of updating 1000 ellipse outlines twice a second using totally random data (located around 0,0). Code is below.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var primitive;

setInterval(function() {

if (primitive) {

viewer.scene.primitives.remove(primitive);

}

var instances = ;

for (var i = 0; i < 1000; i++) {

instances.push(new Cesium.GeometryInstance({

geometry : new Cesium.EllipseOutlineGeometry({

center : Cesium.Cartesian3.fromDegrees(-Math.random(), Math.random()),

semiMinorAxis : Math.random() * 1000,

semiMajorAxis : 1000 + (Math.random() * 1000)

}),

attributes : {

color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 1.0}))

}

}));

}

primitive = viewer.scene.primitives.add(new Cesium.Primitive({

geometryInstances : instances,

asynchronous : false,

appearance : new Cesium.PerInstanceColorAppearance({

flat : true

})

}));

}, 500);

You could probably improve performance a bit by moving this into a preRender loop and diffing times instead of using setInterval (which causes it’s own issues for other reasons outside of the scope of this email). The size of the ellipses also forgets performance because larger sizes create more data that needs to be computed and transferred.

Just to reiterate, I totally agree that Cesium performance can be greatly improved in this area (dynamic geometry), and we definitely want to work on it in the future, but right now we’re finishing up 3D Tiles.

We would be happy to look at any pull requests that make improvements in the shorter term. If you’re interested in helping out, check out https://github.com/AnalyticalGraphicsInc/cesium/blob/master/CONTRIBUTING.md to get started.

Thanks.