How to work with MaterialProperty

Gents,

Entity.material is unlike other properties in that it is a MaterialProperty instead of Property. Thus, questions arise:

  1. What is the recommended way to change entity color dynamically? I’m looking for something like CallbackProperty.

  2. How to use Material.PolylineArrowType within an entity?

Thank you.

  1. Create a ColorMaterialProperty and assign it’s color value to a CallbackProperty. Here’s an example (warning this demo may cause seizures)

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

//New color every time it’s called

var randomColor = new Cesium.CallbackProperty(function(time, result){

return Cesium.Color.fromRandom({alpha: 1.0}, result);

}, false);

viewer.entities.add({

name : 'Red box with black outline',

position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),

box : {

    dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),

    material : new Cesium.ColorMaterialProperty(randomColor)

}

});

viewer.zoomTo(viewer.entities);

  1. I thought I we handled this already, but we don’t. Good news is it’s trivial to add and I’ll put it in 1.8, even better you can use the below class to add this functionality yourself until then:

var PolylineArrowMaterialProperty = function(colorProperty) {

this._definitionChanged = new Cesium.Event();

this._color = undefined;

this._colorSubscription = undefined;

this.color = colorProperty;

};

Cesium.defineProperties(PolylineArrowMaterialProperty.prototype, {

isConstant : {

    get : function() {

        return Cesium.Property.isConstant(this._color);

    }

},

definitionChanged : {

    get : function() {

        return this._definitionChanged;

    }

},

color : Cesium.createPropertyDescriptor('color')

});

PolylineArrowMaterialProperty.prototype.getType = function(time) {

return 'PolylineArrow';

};

PolylineArrowMaterialProperty.prototype.getValue = function(time, result) {

if (!Cesium.defined(result)) {

    result = {};

}

result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);

return result;

};

PolylineArrowMaterialProperty.prototype.equals = function(other) {

return this === other || (other instanceof PolylineArrowMaterialProperty && Cesium.Property.equals(this._color, other._color));

};

And here’s an example using it:

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

viewer.entities.add({

name : 'Red line on the surface',

polyline : {

    positions : Cesium.Cartesian3.fromDegreesArray([-126, 35, -125, 35]),

    width : 15,

    material : new PolylineArrowMaterialProperty(Cesium.Color.RED)

}

});

viewer.zoomTo(viewer.entities);

Thanks!

Can we create a dotted poly line in Cesium like ------------ this?

Hi,

See https://github.com/AnalyticalGraphicsInc/cesium/issues/2584

Hello,

I am trying to accomplish something similar to example 1, where I dynamically change the color of some entities. I believe I'm missing some understanding of the CallbackProperty function because that function is being called continuously and what appears to be an infinite amount of times from the moment the entities are added. I only want the function called when I click on a button. Is there a way to accomplish this?

The CallbackProperty is called every frame by design. Ideally your function would be incredibly simple and therefore fast to call. If you aren’t changing a color dynamically, you can just assign a new value with the new color rather than using CallbackProperty, but depending on your use case this might not perform as well. Can you describe what you are trying to implement?

Thank you for your response. Here is a bit more information about what I am trying to accomplish. I am plotting tens to hundreds of river segments on the globe. I have discharge data time histories for each river segment. What I want to do is animate the time history by correlating discharge values with certain colors (shades of blue or something) with more flow being darker and less flow lighter. During the animation the colors of all the streams will change dynamically at each time step for which there is available data. Does that make sense? Let me know if you have any additional thoughts and ideas on how I could efficiently implement this.

Oh, and to clarify, this would all happen with the click of an “Animate” button.