diff --git a/CHANGES.md b/CHANGES.md index 7ff9cc47343b..710b8220b2f4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Change Log * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll, result)` was removed. Use `Quaternion.fromHeadingPitchRoll(hpr, result)` instead where `hpr` is a `HeadingPitchRoll`. * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` was removed. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where `fixedFrameTransform` is a a 4x4 transformation matrix (see `Transforms.localFrameToFixedFrameGenerator`). * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` was removed. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where `fixedFrameTransform` is a a 4x4 transformation matrix (see `Transforms.localFrameToFixedFrameGenerator`). + * The `color`, `show`, and `pointSize` properties of `Cesium3DTileStyle` are no longer initialized with default values. * Deprecated * `Scene/CullingVolume` is deprecated and will be removed in 1.38. Use `Core/CullingVolume`. * `Scene/OrthographicFrustum` is deprecated and will be removed in 1.38. Use `Core/OrthographicFrustum`. @@ -17,6 +18,7 @@ Change Log * Fixed issue where composite 3D Tiles that contained instanced 3D Tiles with an external model reference would fail to download the model. * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) +* Added ability to set a style's `color`, `show`, or `pointSize` with a string or object literal. `show` may also take a boolean and `pointSize` may take a number. [#5412](https://github.com/AnalyticalGraphicsInc/cesium/pull/5412) * Added setter for `KmlDataSource.name` to specify a name for the datasource [#5660](https://github.com/AnalyticalGraphicsInc/cesium/pull/5660). * Added setter for `GeoJsonDataSource.name` to specify a name for the datasource [#5653](https://github.com/AnalyticalGraphicsInc/cesium/issues/5653) * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 7526fe2cbdf0..f2b10bc06534 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -68,6 +68,9 @@ define([ StencilOperation) { 'use strict'; + var DEFAULT_COLOR_VALUE = Color.WHITE; + var DEFAULT_SHOW_VALUE = true; + /** * @private */ @@ -414,7 +417,7 @@ define([ Check.typeOf.object('color', color); //>>includeEnd('debug'); - if (Color.equals(color, Color.WHITE) && !defined(this._batchValues)) { + if (Color.equals(color, DEFAULT_COLOR_VALUE) && !defined(this._batchValues)) { // Avoid allocating since the default is white return; } @@ -475,7 +478,7 @@ define([ //>>includeEnd('debug'); if (!defined(this._batchValues)) { - return Color.clone(Color.WHITE, result); + return Color.clone(DEFAULT_COLOR_VALUE, result); } var batchValues = this._batchValues; @@ -495,7 +498,7 @@ define([ Cesium3DTileBatchTable.prototype.applyStyle = function(frameState, style) { if (!defined(style)) { - this.setAllColor(Color.WHITE); + this.setAllColor(DEFAULT_COLOR_VALUE); this.setAllShow(true); return; } @@ -504,8 +507,8 @@ define([ var length = this.featuresLength; for (var i = 0; i < length; ++i) { var feature = content.getFeature(i); - var color = style.color.evaluateColor(frameState, feature, scratchColor); - var show = style.show.evaluate(frameState, feature); + var color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; + var show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; this.setColor(i, color); this.setShow(i, show); } diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 02b4d55947ae..a21770cf06ea 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -22,10 +22,6 @@ define([ Expression) { 'use strict'; - var DEFAULT_JSON_COLOR_EXPRESSION = 'color("#ffffff")'; - var DEFAULT_JSON_BOOLEAN_EXPRESSION = true; - var DEFAULT_JSON_NUMBER_EXPRESSION = 1.0; - /** * A style that is applied to a {@link Cesium3DTileset}. *

@@ -95,49 +91,13 @@ define([ styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT); - that._colorShaderFunctionReady = !defined(styleJson.color); - that._showShaderFunctionReady = !defined(styleJson.show); - that._pointSizeShaderFunctionReady = !defined(styleJson.pointSize); - - var colorExpression = defaultValue(styleJson.color, DEFAULT_JSON_COLOR_EXPRESSION); - var showExpression = defaultValue(styleJson.show, DEFAULT_JSON_BOOLEAN_EXPRESSION); - var pointSizeExpression = defaultValue(styleJson.pointSize, DEFAULT_JSON_NUMBER_EXPRESSION); - - var defines = styleJson.defines; - - var color; - if (typeof colorExpression === 'string') { - color = new Expression(colorExpression, defines); - } else if (defined(colorExpression.conditions)) { - color = new ConditionsExpression(colorExpression, defines); - } - - that._color = color; - - var show; - if (typeof showExpression === 'boolean') { - show = new Expression(String(showExpression), defines); - } else if (typeof showExpression === 'string') { - show = new Expression(showExpression, defines); - } else if (defined(showExpression.conditions)) { - show = new ConditionsExpression(showExpression, defines); - } - - that._show = show; - - var pointSize; - if (typeof pointSizeExpression === 'number') { - pointSize = new Expression(String(pointSizeExpression), defines); - } else if (typeof pointSizeExpression === 'string') { - pointSize = new Expression(pointSizeExpression, defines); - } else if (defined(pointSizeExpression.conditions)) { - pointSize = new ConditionsExpression(pointSizeExpression, defines); - } - - that._pointSize = pointSize; + that.color = styleJson.color; + that.show = styleJson.show; + that.pointSize = styleJson.pointSize; var meta = {}; if (defined(styleJson.meta)) { + var defines = styleJson.defines; var metaJson = defaultValue(styleJson.meta, defaultValue.EMPTY_OBJECT); for (var property in metaJson) { if (metaJson.hasOwnProperty(property)) { @@ -209,7 +169,8 @@ define([ }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. Alternatively a boolean, string, or object defining a show style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. *

* The expression must return or convert to a Boolean. *

@@ -234,6 +195,28 @@ define([ * return true; * } * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a boolean + * style.show = true; + * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a string + * style.show = '${Height} > 0'; + * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a condition + * style.show = { + * conditions: [ + * ['${height} > 2', 'false'], + * ['true', 'true'] + * ]; + * }; */ show : { get : function() { @@ -246,13 +229,25 @@ define([ return this._show; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; + if (!defined(value)) { + this._show = undefined; + } else if (typeof value === 'boolean') { + this._show = new Expression(String(value)); + } else if (typeof value === 'string') { + this._show = new Expression(value, defines); + } else if (defined(value.conditions)) { + this._show = new ConditionsExpression(value, defines); + } else { + this._show = value; + } this._showShaderFunctionReady = false; - this._show = value; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. *

* The expression must return a Color. *

@@ -277,6 +272,21 @@ define([ * return Cesium.Color.clone(Cesium.Color.WHITE, result); * } * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a string + * style.color = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a condition + * style.color = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ color : { get : function() { @@ -289,13 +299,23 @@ define([ return this._color; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; + if (!defined(value)) { + this._color = undefined; + } else if (typeof value === 'string') { + this._color = new Expression(value, defines); + } else if (defined(value.conditions)) { + this._color = new ConditionsExpression(value, defines); + } else { + this._color = value; + } this._colorShaderFunctionReady = false; - this._color = value; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. Alternatively a number, string, or object defining a pointSize style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. *

* The expression must return or convert to a Number. *

@@ -320,6 +340,26 @@ define([ * return 1.0; * } * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a number + * style.pointSize = 1.0; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a string + * style.pointSize = '${height} / 10'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a condition + * style.pointSize = { + * conditions : [ + * ['${height} > 2', '1.0'], + * ['true', '2.0'] + * ] + * }; */ pointSize : { get : function() { @@ -332,8 +372,19 @@ define([ return this._pointSize; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; + if (!defined(value)) { + this._pointSize = undefined; + } else if (typeof value === 'number') { + this._pointSize = new Expression(String(value)); + } else if (typeof value === 'string') { + this._pointSize = new Expression(value, defines); + } else if (defined(value.conditions)) { + this._pointSize = new ConditionsExpression(value, defines); + } else { + this._pointSize = value; + } this._pointSizeShaderFunctionReady = false; - this._pointSize = value; } }, @@ -389,7 +440,7 @@ define([ } this._colorShaderFunctionReady = true; - this._colorShaderFunction = this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4'); + this._colorShaderFunction = defined(this.color) ? this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4') : undefined; return this._colorShaderFunction; }; @@ -411,7 +462,7 @@ define([ } this._showShaderFunctionReady = true; - this._showShaderFunction = this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool'); + this._showShaderFunction = defined(this.show) ? this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool') : undefined; return this._showShaderFunction; }; @@ -433,7 +484,7 @@ define([ } this._pointSizeShaderFunctionReady = true; - this._pointSizeShaderFunction = this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float'); + this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') : undefined; return this._pointSizeShaderFunction; }; diff --git a/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js b/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js index b58d82ec377d..6fff82c67a4a 100644 --- a/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js +++ b/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js @@ -1014,7 +1014,7 @@ define([ // Restore original color to feature that is no longer selected var frameState = this._scene.frameState; if (!this.colorize && defined(this._style)) { - currentFeature.color = this._style.color.evaluateColor(frameState, currentFeature, scratchColor); + currentFeature.color = defined(this._style.color) ? this._style.color.evaluateColor(frameState, currentFeature, scratchColor) : Color.WHITE; } else { currentFeature.color = oldColor; } diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index e1dccae26621..43fab6e103b1 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -82,28 +82,28 @@ defineSuite([ }); }); - it('sets show value to default expression', function() { + it('sets show value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.show).toEqual(new Expression('true')); + expect(style.show).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.show).toEqual(new Expression('true')); + expect(style.show).toBeUndefined(); }); - it('sets color value to default expression', function() { + it('sets color value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.color).toEqual(new Expression('color("#ffffff")')); + expect(style.color).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.color).toEqual(new Expression('color("#ffffff")')); + expect(style.color).toBeUndefined(); }); - it('sets pointSize value to default expression', function() { + it('sets pointSize value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.pointSize).toEqual(new Expression('1')); + expect(style.pointSize).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.pointSize).toEqual(new Expression('1')); + expect(style.pointSize).toBeUndefined(); }); it('sets show value to expression', function() { @@ -147,11 +147,48 @@ defineSuite([ expect(style.show).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets show to undefined if not a string, boolean, or conditional', function() { - var style = new Cesium3DTileStyle({ - show : 1 + it('sets show expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', 'false'], + ['true', 'true'] + ] }); - expect(style.show).toEqual(undefined); + + style.show = condExp; + expect(style.show).toEqual(condExp); + + var exp = new Expression('false'); + style.show = exp; + expect(style.show).toEqual(exp); + }); + + it('sets show values in setter', function() { + var defines = { + 'showFactor': 10 + }; + var style = new Cesium3DTileStyle({ 'defines': defines }); + + style.show = '${height} * ${showFactor} >= 1000'; + expect(style.show).toEqual(new Expression('${height} * ${showFactor} >= 1000', defines)); + + style.show = false; + expect(style.show).toEqual(new Expression('false')); + + var jsonExp = { + conditions : [ + ['${height} > ${showFactor}', 'false'], + ['true', 'true'] + ] + }; + + style.show = jsonExp; + expect(style.show).toEqual(new ConditionsExpression(jsonExp, defines)); + + style.show = undefined; + expect(style.show).toBeUndefined(); }); it('sets color value to expression', function() { @@ -185,11 +222,45 @@ defineSuite([ expect(style.color).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets color to undefined if not a string or conditional', function() { - var style = new Cesium3DTileStyle({ - color : 1 + it('sets color expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + var exp = new Expression('color("red")'); + style.color = exp; + expect(style.color).toEqual(exp); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', 'color("cyan")'], + ['true', 'color("blue")'] + ] }); - expect(style.color).toEqual(undefined); + + style.color = condExp; + expect(style.color).toEqual(condExp); + + style.color = undefined; + expect(style.color).toBeUndefined(); + }); + + it('sets color values in setter', function() { + var defines = { + 'targetColor': 'red' + }; + var style = new Cesium3DTileStyle({ 'defines': defines }); + + style.color = 'color("${targetColor}")'; + expect(style.color).toEqual(new Expression('color("${targetColor}")', defines)); + + var jsonExp = { + conditions : [ + ['${height} > 2', 'color("cyan")'], + ['true', 'color("${targetColor}")'] + ] + }; + + style.color = jsonExp; + expect(style.color).toEqual(new ConditionsExpression(jsonExp, defines)); }); it('sets pointSize value to expression', function() { @@ -223,11 +294,51 @@ defineSuite([ expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets pointSize to undefined if not a number, string, or conditional', function() { - var style = new Cesium3DTileStyle({ - pointSize : true + it('sets pointSize expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + style.pointSize = 2; + expect(style.pointSize).toEqual(new Expression('2')); + + var exp = new Expression('2'); + style.pointSize = exp; + expect(style.pointSize).toEqual(exp); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', '1.0'], + ['true', '2.0'] + ] }); - expect(style.pointSize).toEqual(undefined); + + style.pointSize = condExp; + expect(style.pointSize).toEqual(condExp); + + style.pointSize = undefined; + expect(style.pointSize).toBeUndefined(); + }); + + it('sets pointSize values in setter', function() { + var defines = { + 'targetPointSize': '2.0' + }; + var style = new Cesium3DTileStyle({ 'defines': defines }); + + style.pointSize = 2; + expect(style.pointSize).toEqual(new Expression('2')); + + style.pointSize = '${targetPointSize} + 1.0'; + expect(style.pointSize).toEqual(new Expression('${targetPointSize} + 1.0', defines)); + + var jsonExp = { + conditions : [ + ['${height} > 2', '1.0'], + ['true', '${targetPointSize}'] + ] + }; + + style.pointSize = jsonExp; + expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp, defines)); }); it('throws on accessing style if not ready', function() { @@ -334,7 +445,6 @@ defineSuite([ expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.show.evaluate(frameState, feature2)).toEqual(false); - expect(style.color.evaluateColor(frameState, undefined)).toEqual(Color.WHITE); }); it('applies show style with regexp and variables', function() { @@ -344,7 +454,6 @@ defineSuite([ expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.show.evaluate(frameState, feature2)).toEqual(false); - expect(style.color.evaluateColor(frameState, undefined)).toEqual(Color.WHITE); }); it('applies show style with conditional', function() { @@ -368,7 +477,6 @@ defineSuite([ var style = new Cesium3DTileStyle({ "color" : "(${Temperature} > 90) ? color('red') : color('white')" }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.WHITE); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.RED); }); @@ -377,7 +485,6 @@ defineSuite([ var style = new Cesium3DTileStyle({ "color" : "rgba(${red}, ${green}, ${blue}, (${volume} > 100 ? 0.5 : 1.0))" }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(new Color(38/255, 255/255, 82/255, 0.5)); expect(style.color.evaluateColor(frameState, feature2)).toEqual(new Color(255/255, 30/255, 30/255, 1.0)); }); @@ -395,7 +502,6 @@ defineSuite([ ] } }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.RED); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.LIME); }); @@ -413,7 +519,6 @@ defineSuite([ ] } }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.BLUE); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.YELLOW); });