diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html new file mode 100644 index 000000000000..6a31256c48bf --- /dev/null +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -0,0 +1,86 @@ + + +
+ + + + + +true
if they are equal, false
otherwise.
+ *
+ * @param {Property} [other] The other property.
+ * @returns {Boolean} true
if left and right are equal, false
otherwise.
+ */
+ GeometryHeightProperty.prototype.equals = function(other) {
+ return this === other ||//
+ (other instanceof GeometryHeightProperty &&
+ Property.equals(this._height, other._height) &&
+ Property.equals(this._heightReference, other._heightReference));
+ };
+
+ return GeometryHeightProperty;
+});
diff --git a/Source/DataSources/GeometryVisualizer.js b/Source/DataSources/GeometryVisualizer.js
index 9ea93859248f..41f4ee0a792c 100644
--- a/Source/DataSources/GeometryVisualizer.js
+++ b/Source/DataSources/GeometryVisualizer.js
@@ -142,23 +142,31 @@ define([
this._changedObjects = new AssociativeArray();
var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES;
- this._outlineBatches = new Array(numberOfShadowModes);
- this._closedColorBatches = new Array(numberOfShadowModes);
- this._closedMaterialBatches = new Array(numberOfShadowModes);
- this._openColorBatches = new Array(numberOfShadowModes);
- this._openMaterialBatches = new Array(numberOfShadowModes);
+ this._outlineBatches = new Array(numberOfShadowModes*2);
+ this._closedColorBatches = new Array(numberOfShadowModes*2);
+ this._closedMaterialBatches = new Array(numberOfShadowModes*2);
+ this._openColorBatches = new Array(numberOfShadowModes*2);
+ this._openMaterialBatches = new Array(numberOfShadowModes*2);
var supportsMaterialsforEntitiesOnTerrain = Entity.supportsMaterialsforEntitiesOnTerrain(scene);
this._supportsMaterialsforEntitiesOnTerrain = supportsMaterialsforEntitiesOnTerrain;
var i;
for (i = 0; i < numberOfShadowModes; ++i) {
- this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i);
+ this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i, false);
+ this._outlineBatches[numberOfShadowModes + i] = new StaticOutlineGeometryBatch(primitives, scene, i, true);
- this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, true, i);
- this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, true, i);
- this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, false, i);
- this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, false, i);
+ this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, true, i, true);
+ this._closedColorBatches[numberOfShadowModes + i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, true, i, false);
+
+ this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, true, i, true);
+ this._closedMaterialBatches[numberOfShadowModes + i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, true, i, false);
+
+ this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, false, i, true);
+ this._openColorBatches[numberOfShadowModes + i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance, undefined, false, i, false);
+
+ this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, false, i, true);
+ this._openMaterialBatches[numberOfShadowModes + i] = new StaticGeometryPerMaterialBatch(primitives, MaterialAppearance, undefined, false, i, false);
}
var numberOfClassificationTypes = ClassificationType.NUMBER_OF_CLASSIFICATION_TYPES;
@@ -390,8 +398,13 @@ define([
shadows = updater.shadowsProperty.getValue(time);
}
+ var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES;
if (updater.outlineEnabled) {
- this._outlineBatches[shadows].add(time, updater);
+ if (defined(updater.terrainOffsetProperty)) {
+ this._outlineBatches[numberOfShadowModes + shadows].add(time, updater);
+ } else {
+ this._outlineBatches[shadows].add(time, updater);
+ }
}
if (updater.fillEnabled) {
@@ -408,14 +421,32 @@ define([
}
} else if (updater.isClosed) {
if (updater.fillMaterialProperty instanceof ColorMaterialProperty) {
- this._closedColorBatches[shadows].add(time, updater);
+ if (defined(updater.terrainOffsetProperty)) {
+ this._closedColorBatches[numberOfShadowModes + shadows].add(time, updater);
+ } else {
+ this._closedColorBatches[shadows].add(time, updater);
+ }
} else {
- this._closedMaterialBatches[shadows].add(time, updater);
+ // eslint-disable-next-line no-lonely-if
+ if (defined(updater.terrainOffsetProperty)) {
+ this._closedMaterialBatches[numberOfShadowModes + shadows].add(time, updater);
+ } else {
+ this._closedMaterialBatches[shadows].add(time, updater);
+ }
}
} else if (updater.fillMaterialProperty instanceof ColorMaterialProperty) {
- this._openColorBatches[shadows].add(time, updater);
+ if (defined(updater.terrainOffsetProperty)) {
+ this._openColorBatches[numberOfShadowModes + shadows].add(time, updater);
+ } else {
+ this._openColorBatches[shadows].add(time, updater);
+ }
} else {
- this._openMaterialBatches[shadows].add(time, updater);
+ // eslint-disable-next-line no-lonely-if
+ if (defined(updater.terrainOffsetProperty)) {
+ this._openMaterialBatches[numberOfShadowModes + shadows].add(time, updater);
+ } else {
+ this._openMaterialBatches[shadows].add(time, updater);
+ }
}
}
};
diff --git a/Source/DataSources/GroundGeometryUpdater.js b/Source/DataSources/GroundGeometryUpdater.js
index 43f2a98afc14..4d4c4d5c629b 100644
--- a/Source/DataSources/GroundGeometryUpdater.js
+++ b/Source/DataSources/GroundGeometryUpdater.js
@@ -1,19 +1,31 @@
define([
+ '../Core/Cartesian3',
+ '../Core/Check',
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
+ '../Core/DeveloperError',
'../Core/Iso8601',
'../Core/oneTimeWarning',
+ '../Scene/HeightReference',
'./ConstantProperty',
- './GeometryUpdater'
+ './GeometryHeightProperty',
+ './GeometryUpdater',
+ './TerrainOffsetProperty'
], function(
+ Cartesian3,
+ Check,
defaultValue,
defined,
defineProperties,
+ DeveloperError,
Iso8601,
oneTimeWarning,
+ HeightReference,
ConstantProperty,
- GeometryUpdater) {
+ GeometryHeightProperty,
+ GeometryUpdater,
+ TerrainOffsetProperty) {
'use strict';
var defaultZIndex = new ConstantProperty(0);
@@ -33,6 +45,7 @@ define([
GeometryUpdater.call(this, options);
this._zIndex = 0;
+ this._terrainOffsetProperty = undefined;
}
if (defined(Object.create)) {
@@ -51,9 +64,25 @@ define([
get: function() {
return this._zIndex;
}
+ },
+
+ terrainOffsetProperty: {
+ get: function() {
+ return this._terrainOffsetProperty;
+ }
}
});
+ /**
+ * @param {Entity} entity
+ * @param {Object} geometry
+ * @param {JulianDate} time
+ * @param {Cartesian3} result
+ *
+ * @private
+ */
+ GroundGeometryUpdater.prototype._computeCenter = DeveloperError.throwInstantiationError;
+
GroundGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) {
GeometryUpdater.prototype._onEntityPropertyChanged.call(this, entity, propertyName, newValue, oldValue);
if (this._observedPropertyNames.indexOf(propertyName) === -1) {
@@ -69,6 +98,19 @@ define([
}
this._zIndex = defaultValue(geometry.zIndex, defaultZIndex);
+
+ var heightProperty = geometry.height;
+ var extrudedHeightProperty = geometry.extrudedHeight;
+
+ if (this._terrainOffsetProperty instanceof TerrainOffsetProperty) {
+ this._terrainOffsetProperty.destroy();
+ }
+
+ if (heightProperty instanceof GeometryHeightProperty || extrudedHeightProperty instanceof GeometryHeightProperty) {
+ this._terrainOffsetProperty = new TerrainOffsetProperty(this._scene, heightProperty, extrudedHeightProperty, this._computeCenter.bind(this));
+ } else {
+ this._terrainOffsetProperty = undefined;
+ }
};
return GroundGeometryUpdater;
diff --git a/Source/DataSources/PolygonGeometryUpdater.js b/Source/DataSources/PolygonGeometryUpdater.js
index c56094f34b35..32f55711bad1 100644
--- a/Source/DataSources/PolygonGeometryUpdater.js
+++ b/Source/DataSources/PolygonGeometryUpdater.js
@@ -1,4 +1,5 @@
define([
+ '../Core/Cartesian3',
'../Core/Check',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
@@ -6,21 +7,26 @@ define([
'../Core/DeveloperError',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
'../Core/GeometryInstance',
+ '../Core/GeometryOffsetAttribute',
'../Core/isArray',
'../Core/Iso8601',
+ '../Core/OffsetGeometryInstanceAttribute',
'../Core/PolygonGeometry',
'../Core/PolygonHierarchy',
'../Core/PolygonOutlineGeometry',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/GroundPrimitive',
+ '../Scene/HeightReference',
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'./ColorMaterialProperty',
'./DynamicGeometryUpdater',
+ './GeometryHeightProperty',
'./GeometryUpdater',
'./GroundGeometryUpdater',
'./Property'
], function(
+ Cartesian3,
Check,
Color,
ColorGeometryInstanceAttribute,
@@ -28,23 +34,30 @@ define([
DeveloperError,
DistanceDisplayConditionGeometryInstanceAttribute,
GeometryInstance,
+ GeometryOffsetAttribute,
isArray,
Iso8601,
+ OffsetGeometryInstanceAttribute,
PolygonGeometry,
PolygonHierarchy,
PolygonOutlineGeometry,
ShowGeometryInstanceAttribute,
GroundPrimitive,
+ HeightReference,
MaterialAppearance,
PerInstanceColorAppearance,
ColorMaterialProperty,
DynamicGeometryUpdater,
+ GeometryHeightProperty,
GeometryUpdater,
GroundGeometryUpdater,
Property) {
'use strict';
var scratchColor = new Color();
+ var defaultOffset = Cartesian3.ZERO;
+ var offsetScratch = new Cartesian3();
+ var scratchPolygonGeometry = new PolygonGeometry({polygonHierarchy: new PolygonHierarchy});
function PolygonGeometryOptions(entity) {
this.id = entity;
@@ -57,6 +70,7 @@ define([
this.extrudedHeight = undefined;
this.granularity = undefined;
this.stRotation = undefined;
+ this.offsetAttribute = undefined;
}
/**
@@ -105,12 +119,11 @@ define([
var entity = this._entity;
var isAvailable = entity.isAvailable(time);
- var attributes;
+ var attributes = {
+ show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)),
+ distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time))
+ };
- var color;
- var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time));
- var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
- var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition);
if (this._materialProperty instanceof ColorMaterialProperty) {
var currentColor;
if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) {
@@ -119,17 +132,10 @@ define([
if (!defined(currentColor)) {
currentColor = Color.WHITE;
}
- color = ColorGeometryInstanceAttribute.fromColor(currentColor);
- attributes = {
- show : show,
- distanceDisplayCondition : distanceDisplayConditionAttribute,
- color : color
- };
- } else {
- attributes = {
- show : show,
- distanceDisplayCondition : distanceDisplayConditionAttribute
- };
+ attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
+ }
+ if (defined(this._options.offsetAttribute)) {
+ attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
}
return new GeometryInstance({
@@ -161,17 +167,44 @@ define([
var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK, scratchColor);
var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
+ var attributes = {
+ show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
+ color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
+ distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
+ };
+
+ if (defined(this._options.offsetAttribute)) {
+ attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
+ }
+
return new GeometryInstance({
id : entity,
geometry : new PolygonOutlineGeometry(this._options),
- attributes : {
- show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
- color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
- distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
- }
+ attributes : attributes
});
};
+ PolygonGeometryUpdater.prototype._computeCenter = function(time, result) {
+ var positions = Property.getValueOrUndefined(this._entity.polygon.hierarchy, time);
+ if (defined(positions) && !isArray(positions)) {
+ positions = positions.positions;
+ }
+ if (positions.length === 0) {
+ return;
+ }
+
+ var centroid = Cartesian3.clone(Cartesian3.ZERO, result);
+ var length = positions.length;
+ for (var i = 0; i < length; i++) {
+ centroid = Cartesian3.add(positions[i], centroid, centroid);
+ }
+ centroid = Cartesian3.multiplyByScalar(centroid, 1 / length, centroid);
+ if (defined(this._scene.globe)) {
+ centroid = this._scene.globe.ellipsoid.scaleToGeodeticSurface(centroid, centroid);
+ }
+ return centroid;
+ };
+
PolygonGeometryUpdater.prototype._isHidden = function(entity, polygon) {
return !defined(polygon.hierarchy) || GeometryUpdater.prototype._isHidden.call(this, entity, polygon);
};
@@ -208,10 +241,13 @@ define([
hierarchyValue = new PolygonHierarchy(hierarchyValue);
}
- var heightValue = Property.getValueOrUndefined(polygon.height, Iso8601.MINIMUM_VALUE);
+ var height = polygon.height;
+ var extrudedHeight = polygon.extrudedHeight;
+
+ var heightValue = Property.getValueOrUndefined(height, Iso8601.MINIMUM_VALUE);
var closeTopValue = Property.getValueOrDefault(polygon.closeTop, Iso8601.MINIMUM_VALUE, true);
var closeBottomValue = Property.getValueOrDefault(polygon.closeBottom, Iso8601.MINIMUM_VALUE, true);
- var extrudedHeightValue = Property.getValueOrUndefined(polygon.extrudedHeight, Iso8601.MINIMUM_VALUE);
+ var extrudedHeightValue = Property.getValueOrUndefined(extrudedHeight, Iso8601.MINIMUM_VALUE);
var perPositionHeightValue = Property.getValueOrUndefined(polygon.perPositionHeight, Iso8601.MINIMUM_VALUE);
if (defined(extrudedHeightValue) && !defined(heightValue) && !defined(perPositionHeightValue)) {
@@ -226,6 +262,12 @@ define([
options.perPositionHeight = perPositionHeightValue;
options.closeTop = closeTopValue;
options.closeBottom = closeBottomValue;
+ options.offsetAttribute = GeometryHeightProperty.computeGeometryOffsetAttribute(height, extrudedHeight, Iso8601.MINIMUM_VALUE);
+
+ if (extrudedHeight instanceof GeometryHeightProperty && Property.getValueOrDefault(extrudedHeight.height, Iso8601.MINIMUM_VALUE, HeightReference.NONE) === HeightReference.CLAMP_TO_GROUND) {
+ scratchPolygonGeometry.setOptions(options);
+ options.extrudedHeight = GeometryHeightProperty.getMinimumTerrainValue(scratchPolygonGeometry.rectangle);
+ }
};
PolygonGeometryUpdater.prototype._getIsClosed = function(options) {
@@ -255,6 +297,9 @@ define([
DyanmicPolygonGeometryUpdater.prototype._setOptions = function(entity, polygon, time) {
var options = this._options;
+ var height = polygon.height;
+ var extrudedHeight = polygon.extrudedHeight;
+
var hierarchy = Property.getValueOrUndefined(polygon.hierarchy, time);
if (isArray(hierarchy)) {
options.polygonHierarchy = new PolygonHierarchy(hierarchy);
@@ -262,13 +307,20 @@ define([
options.polygonHierarchy = hierarchy;
}
- options.height = Property.getValueOrUndefined(polygon.height, time);
- options.extrudedHeight = Property.getValueOrUndefined(polygon.extrudedHeight, time);
+ options.height = Property.getValueOrUndefined(height, time);
+ options.extrudedHeight = Property.getValueOrUndefined(extrudedHeight, time);
options.granularity = Property.getValueOrUndefined(polygon.granularity, time);
options.stRotation = Property.getValueOrUndefined(polygon.stRotation, time);
options.perPositionHeight = Property.getValueOrUndefined(polygon.perPositionHeight, time);
options.closeTop = Property.getValueOrDefault(polygon.closeTop, time, true);
options.closeBottom = Property.getValueOrDefault(polygon.closeBottom, time, true);
+ options.offsetAttribute = GeometryHeightProperty.computeGeometryOffsetAttribute(height, extrudedHeight, time);
+
+ if (extrudedHeight instanceof GeometryHeightProperty && Property.getValueOrDefault(extrudedHeight.height, time, HeightReference.NONE) === HeightReference.CLAMP_TO_GROUND) {
+ scratchPolygonGeometry.setOptions(options);
+ options.extrudedHeight = GeometryHeightProperty.getMinimumTerrainValue(scratchPolygonGeometry.rectangle);
+ }
+
};
return PolygonGeometryUpdater;
diff --git a/Source/DataSources/RectangleGeometryUpdater.js b/Source/DataSources/RectangleGeometryUpdater.js
index 21e6c35a89a0..48416ea3bd83 100644
--- a/Source/DataSources/RectangleGeometryUpdater.js
+++ b/Source/DataSources/RectangleGeometryUpdater.js
@@ -1,46 +1,67 @@
define([
+ '../Core/Cartesian3',
+ '../Core/Cartographic',
'../Core/Check',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
'../Core/defined',
'../Core/DeveloperError',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
+ '../Core/Ellipsoid',
'../Core/GeometryInstance',
+ '../Core/GeometryOffsetAttribute',
'../Core/Iso8601',
+ '../Core/OffsetGeometryInstanceAttribute',
+ '../Core/Rectangle',
'../Core/RectangleGeometry',
'../Core/RectangleOutlineGeometry',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/GroundPrimitive',
+ '../Scene/HeightReference',
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'./ColorMaterialProperty',
'./DynamicGeometryUpdater',
+ './GeometryHeightProperty',
'./GeometryUpdater',
'./GroundGeometryUpdater',
'./Property'
], function(
+ Cartesian3,
+ Cartographic,
Check,
Color,
ColorGeometryInstanceAttribute,
defined,
DeveloperError,
DistanceDisplayConditionGeometryInstanceAttribute,
+ Ellipsoid,
GeometryInstance,
+ GeometryOffsetAttribute,
Iso8601,
+ OffsetGeometryInstanceAttribute,
+ Rectangle,
RectangleGeometry,
RectangleOutlineGeometry,
ShowGeometryInstanceAttribute,
GroundPrimitive,
+ HeightReference,
MaterialAppearance,
PerInstanceColorAppearance,
ColorMaterialProperty,
DynamicGeometryUpdater,
+ GeometryHeightProperty,
GeometryUpdater,
GroundGeometryUpdater,
Property) {
'use strict';
var scratchColor = new Color();
+ var defaultOffset = Cartesian3.ZERO;
+ var offsetScratch = new Cartesian3();
+ var scratchRectangleGeometry = new RectangleGeometry({rectangle: new Rectangle()});
+ var scratchCenterRect = new Rectangle();
+ var scratchCarto = new Cartographic();
function RectangleGeometryOptions(entity) {
this.id = entity;
@@ -51,6 +72,7 @@ define([
this.granularity = undefined;
this.stRotation = undefined;
this.rotation = undefined;
+ this.offsetAttribute = undefined;
}
/**
@@ -99,12 +121,11 @@ define([
var entity = this._entity;
var isAvailable = entity.isAvailable(time);
- var attributes;
+ var attributes = {
+ show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)),
+ distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time))
+ };
- var color;
- var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time));
- var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
- var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition);
if (this._materialProperty instanceof ColorMaterialProperty) {
var currentColor;
if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) {
@@ -113,17 +134,10 @@ define([
if (!defined(currentColor)) {
currentColor = Color.WHITE;
}
- color = ColorGeometryInstanceAttribute.fromColor(currentColor);
- attributes = {
- show : show,
- distanceDisplayCondition : distanceDisplayConditionAttribute,
- color : color
- };
- } else {
- attributes = {
- show : show,
- distanceDisplayCondition : distanceDisplayConditionAttribute
- };
+ attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
+ }
+ if (defined(this._options.offsetAttribute)) {
+ attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
}
return new GeometryInstance({
@@ -155,17 +169,32 @@ define([
var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK, scratchColor);
var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
+ var attributes = {
+ show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
+ color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
+ distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
+ };
+
+ if (defined(this._options.offsetAttribute)) {
+ attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
+ }
+
return new GeometryInstance({
id : entity,
geometry : new RectangleOutlineGeometry(this._options),
- attributes : {
- show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
- color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
- distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
- }
+ attributes : attributes
});
};
+ RectangleGeometryUpdater.prototype._computeCenter = function(time, result) {
+ var rect = Property.getValueOrUndefined(this._entity.rectangle.coordinates, time, scratchCenterRect);
+ if (!defined(rect)) {
+ return;
+ }
+ var center = Rectangle.center(rect, scratchCarto);
+ return Cartographic.toCartesian(center, Ellipsoid.WGS84, result);
+ };
+
RectangleGeometryUpdater.prototype._isHidden = function(entity, rectangle) {
return !defined(rectangle.coordinates) || GeometryUpdater.prototype._isHidden.call(this, entity, rectangle);
};
@@ -203,6 +232,12 @@ define([
options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined;
+ options.offsetAttribute = GeometryHeightProperty.computeGeometryOffsetAttribute(height, extrudedHeight, Iso8601.MINIMUM_VALUE);
+
+ if (extrudedHeight instanceof GeometryHeightProperty && Property.getValueOrDefault(extrudedHeight.height, Iso8601.MINIMUM_VALUE, HeightReference.NONE) === HeightReference.CLAMP_TO_GROUND) {
+ scratchRectangleGeometry.setOptions(options);
+ options.extrudedHeight = GeometryHeightProperty.getMinimumTerrainValue(scratchRectangleGeometry.rectangle);
+ }
};
RectangleGeometryUpdater.prototype._getIsClosed = function(options) {
@@ -231,12 +266,21 @@ define([
DynamicRectangleGeometryUpdater.prototype._setOptions = function(entity, rectangle, time) {
var options = this._options;
+ var height = rectangle.height;
+ var extrudedHeight = rectangle.extrudedHeight;
+
options.rectangle = Property.getValueOrUndefined(rectangle.coordinates, time, options.rectangle);
- options.height = Property.getValueOrUndefined(rectangle.height, time);
- options.extrudedHeight = Property.getValueOrUndefined(rectangle.extrudedHeight, time);
+ options.height = Property.getValueOrUndefined(height, time);
+ options.extrudedHeight = Property.getValueOrUndefined(extrudedHeight, time);
options.granularity = Property.getValueOrUndefined(rectangle.granularity, time);
options.stRotation = Property.getValueOrUndefined(rectangle.stRotation, time);
options.rotation = Property.getValueOrUndefined(rectangle.rotation, time);
+ options.offsetAttribute = GeometryHeightProperty.computeGeometryOffsetAttribute(height, extrudedHeight, time);
+
+ if (extrudedHeight instanceof GeometryHeightProperty && Property.getValueOrDefault(extrudedHeight.height, time, HeightReference.NONE) === HeightReference.CLAMP_TO_GROUND) {
+ scratchRectangleGeometry.setOptions(options);
+ options.extrudedHeight = GeometryHeightProperty.getMinimumTerrainValue(scratchRectangleGeometry.rectangle);
+ }
};
return RectangleGeometryUpdater;
diff --git a/Source/DataSources/StaticGeometryColorBatch.js b/Source/DataSources/StaticGeometryColorBatch.js
index 32168a30c123..7f87f7a1f699 100644
--- a/Source/DataSources/StaticGeometryColorBatch.js
+++ b/Source/DataSources/StaticGeometryColorBatch.js
@@ -1,10 +1,12 @@
define([
'../Core/AssociativeArray',
+ '../Core/Cartesian3',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
'../Core/defined',
'../Core/DistanceDisplayCondition',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
+ '../Core/OffsetGeometryInstanceAttribute',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/Primitive',
'./BoundingSphereState',
@@ -13,11 +15,13 @@ define([
'./Property'
], function(
AssociativeArray,
+ Cartesian3,
Color,
ColorGeometryInstanceAttribute,
defined,
DistanceDisplayCondition,
DistanceDisplayConditionGeometryInstanceAttribute,
+ OffsetGeometryInstanceAttribute,
ShowGeometryInstanceAttribute,
Primitive,
BoundingSphereState,
@@ -29,6 +33,8 @@ define([
var colorScratch = new Color();
var distanceDisplayConditionScratch = new DistanceDisplayCondition();
var defaultDistanceDisplayCondition = new DistanceDisplayCondition();
+ var defaultOffset = Cartesian3.ZERO;
+ var offsetScratch = new Cartesian3();
function Batch(primitives, translucent, appearanceType, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) {
this.translucent = translucent;
@@ -80,7 +86,7 @@ define([
this.createPrimitive = true;
this.geometry.set(id, instance);
this.updaters.set(id, updater);
- if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) {
+ if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty) || !Property.isConstant(updater.terrainOffsetProperty)) {
this.updatersWithAttributes.set(id, updater);
} else {
var that = this;
@@ -245,6 +251,15 @@ define([
attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition);
}
}
+
+ var offsetProperty = updater.terrainOffsetProperty;
+ if (!Property.isConstant(offsetProperty)) {
+ var offset = Property.getValueOrDefault(offsetProperty, time, defaultOffset, offsetScratch);
+ if (!Cartesian3.equals(offset, attributes._lastOffset)) {
+ attributes._lastOffset = Cartesian3.clone(offset, attributes._lastOffset);
+ attributes.offset = OffsetGeometryInstanceAttribute.toValue(offset, attributes.offset);
+ }
+ }
}
this.updateShows(primitive);
diff --git a/Source/DataSources/StaticGeometryPerMaterialBatch.js b/Source/DataSources/StaticGeometryPerMaterialBatch.js
index 4734c5be14fd..0fd9eed26e2c 100644
--- a/Source/DataSources/StaticGeometryPerMaterialBatch.js
+++ b/Source/DataSources/StaticGeometryPerMaterialBatch.js
@@ -1,10 +1,12 @@
define([
'../Core/AssociativeArray',
+ '../Core/Cartesian3',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
'../Core/defined',
'../Core/DistanceDisplayCondition',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
+ '../Core/OffsetGeometryInstanceAttribute',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/Primitive',
'./BoundingSphereState',
@@ -13,11 +15,13 @@ define([
'./Property'
], function(
AssociativeArray,
+ Cartesian3,
Color,
ColorGeometryInstanceAttribute,
defined,
DistanceDisplayCondition,
DistanceDisplayConditionGeometryInstanceAttribute,
+ OffsetGeometryInstanceAttribute,
ShowGeometryInstanceAttribute,
Primitive,
BoundingSphereState,
@@ -28,6 +32,8 @@ define([
var distanceDisplayConditionScratch = new DistanceDisplayCondition();
var defaultDistanceDisplayCondition = new DistanceDisplayCondition();
+ var defaultOffset = Cartesian3.ZERO;
+ var offsetScratch = new Cartesian3();
function Batch(primitives, appearanceType, materialProperty, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) {
this.primitives = primitives;
@@ -74,7 +80,7 @@ define([
var id = updater.id;
this.updaters.set(id, updater);
this.geometry.set(id, updater.createFillGeometryInstance(time));
- if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) {
+ if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty) || !Property.isConstant(updater.terrainOffsetProperty)) {
this.updatersWithAttributes.set(id, updater);
} else {
var that = this;
@@ -234,6 +240,15 @@ define([
attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition);
}
}
+
+ var offsetProperty = updater.terrainOffsetProperty;
+ if (!Property.isConstant(offsetProperty)) {
+ var offset = Property.getValueOrDefault(offsetProperty, time, defaultOffset, offsetScratch);
+ if (!Cartesian3.equals(offset, attributes._lastOffset)) {
+ attributes._lastOffset = Cartesian3.clone(offset, attributes._lastOffset);
+ attributes.offset = OffsetGeometryInstanceAttribute.toValue(offset, attributes.offset);
+ }
+ }
}
this.updateShows(primitive);
diff --git a/Source/DataSources/StaticOutlineGeometryBatch.js b/Source/DataSources/StaticOutlineGeometryBatch.js
index 848154fa3c51..def326371c71 100644
--- a/Source/DataSources/StaticOutlineGeometryBatch.js
+++ b/Source/DataSources/StaticOutlineGeometryBatch.js
@@ -1,10 +1,12 @@
define([
'../Core/AssociativeArray',
+ '../Core/Cartesian3',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
'../Core/defined',
'../Core/DistanceDisplayCondition',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
+ '../Core/OffsetGeometryInstanceAttribute',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
@@ -12,11 +14,13 @@ define([
'./Property'
], function(
AssociativeArray,
+ Cartesian3,
Color,
ColorGeometryInstanceAttribute,
defined,
DistanceDisplayCondition,
DistanceDisplayConditionGeometryInstanceAttribute,
+ OffsetGeometryInstanceAttribute,
ShowGeometryInstanceAttribute,
PerInstanceColorAppearance,
Primitive,
@@ -27,6 +31,8 @@ define([
var colorScratch = new Color();
var distanceDisplayConditionScratch = new DistanceDisplayCondition();
var defaultDistanceDisplayCondition = new DistanceDisplayCondition();
+ var defaultOffset = Cartesian3.ZERO;
+ var offsetScratch = new Cartesian3();
function Batch(primitives, translucent, width, shadows) {
this.translucent = translucent;
@@ -50,7 +56,7 @@ define([
this.createPrimitive = true;
this.geometry.set(id, instance);
this.updaters.set(id, updater);
- if (!updater.hasConstantOutline || !updater.outlineColorProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) {
+ if (!updater.hasConstantOutline || !updater.outlineColorProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty) || !Property.isConstant(updater.terrainOffsetProperty)) {
this.updatersWithAttributes.set(id, updater);
} else {
var that = this;
@@ -189,6 +195,15 @@ define([
attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition);
}
}
+
+ var offsetProperty = updater.terrainOffsetProperty;
+ if (!Property.isConstant(offsetProperty)) {
+ var offset = Property.getValueOrDefault(offsetProperty, time, defaultOffset, offsetScratch);
+ if (!Cartesian3.equals(offset, attributes._lastOffset)) {
+ attributes._lastOffset = Cartesian3.clone(offset, attributes._lastOffset);
+ attributes.offset = OffsetGeometryInstanceAttribute.toValue(offset, attributes.offset);
+ }
+ }
}
this.updateShows(primitive);
diff --git a/Source/DataSources/TerrainOffsetProperty.js b/Source/DataSources/TerrainOffsetProperty.js
new file mode 100644
index 000000000000..7a0612ae1c8f
--- /dev/null
+++ b/Source/DataSources/TerrainOffsetProperty.js
@@ -0,0 +1,199 @@
+define([
+ '../Core/Cartesian3',
+ '../Core/Cartographic',
+ '../Core/Check',
+ '../Core/defined',
+ '../Core/defineProperties',
+ '../Core/destroyObject',
+ '../Core/Event',
+ '../Core/Iso8601',
+ '../Core/Math',
+ '../Scene/HeightReference',
+ './Property'
+], function(
+ Cartesian3,
+ Cartographic,
+ Check,
+ defined,
+ defineProperties,
+ destroyObject,
+ Event,
+ Iso8601,
+ CesiumMath,
+ HeightReference,
+ Property) {
+ 'use strict';
+
+ var scratchPosition = new Cartesian3();
+ var scratchCarto = new Cartographic();
+
+ /**
+ * @private
+ * @param {Scene} scene
+ * @param {Property} height
+ * @param {Property} extrudedHeight
+ * @param {TerrainOffsetProperty~PositionFunction} getPosition
+ * @constructor
+ */
+ function TerrainOffsetProperty(scene, height, extrudedHeight, getPosition) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.defined('scene', scene);
+ Check.defined('height', height);
+ Check.defined('extrudedHeight', extrudedHeight);
+ Check.typeOf.func('getPosition', getPosition);
+ //>>includeEnd('debug');
+
+ this._scene = scene;
+ this._height = height;
+ this._extrudedHeight = extrudedHeight;
+ this._getPosition = getPosition;
+
+ this._position = new Cartesian3();
+ this._cartographicPosition = new Cartographic();
+ this._normal = new Cartesian3();
+
+ this._definitionChanged = new Event();
+ this._terrainHeight = 0;
+ this._removeCallbackFunc = undefined;
+ this._removeEventListener = undefined;
+ this._removeModeListener = undefined;
+
+ var that = this;
+ if (defined(scene.globe)) {
+ this._removeEventListener = scene.terrainProviderChanged.addEventListener(function() {
+ that._updateClamping();
+ });
+ this._removeModeListener = scene.morphComplete.addEventListener(function() {
+ that._updateClamping();
+ });
+ }
+ }
+
+ defineProperties(TerrainOffsetProperty.prototype, {
+ /**
+ * Gets a value indicating if this property is constant.
+ * @memberof TerrainOffsetProperty.prototype
+ *
+ * @type {Boolean}
+ * @readonly
+ */
+ isConstant : {
+ get : function() {
+ return false;
+ }
+ },
+ /**
+ * Gets the event that is raised whenever the definition of this property changes.
+ * @memberof TerrainOffsetProperty.prototype
+ *
+ * @type {Event}
+ * @readonly
+ */
+ definitionChanged : {
+ get : function() {
+ return this._definitionChanged;
+ }
+ }
+ });
+
+ /**
+ * @private
+ */
+ TerrainOffsetProperty.prototype._updateClamping = function() {
+ var scene = this._scene;
+ var globe = scene.globe;
+ if (!defined(globe)) {
+ this._terrainHeight = 0;
+ return;
+ }
+ var ellipsoid = globe.ellipsoid;
+ var surface = globe._surface;
+
+ var position = this._position;
+ if (defined(this._removeCallbackFunc)) {
+ this._removeCallbackFunc();
+ }
+
+ var that = this;
+ var cartographicPosition = ellipsoid.cartesianToCartographic(position, this._cartographicPosition);
+ var height = globe.getHeight(cartographicPosition);
+ if (defined(height)) {
+ this._terrainHeight = height;
+ } else {
+ this._terrainHeight = 0;
+ }
+
+ function updateFunction(clampedPosition) {
+ var carto = ellipsoid.cartesianToCartographic(clampedPosition, scratchCarto);
+ that._terrainHeight = carto.height;
+ that.definitionChanged.raiseEvent();
+ }
+ this._removeCallbackFunc = surface.updateHeight(cartographicPosition, updateFunction);
+ };
+
+ /**
+ * Gets the height relative to the terrain based on the positions.
+ *
+ * @returns {Cartesian3} The offset
+ */
+ TerrainOffsetProperty.prototype.getValue = function(time, result) {
+ var heightProperty = this._height;
+ var extrudedHeightProperty = this._extrudedHeight;
+ var heightReference = HeightReference.NONE;
+ var extrudedHeightReference = HeightReference.NONE;
+ if (defined(heightProperty)) {
+ heightReference = Property.getValueOrDefault(heightProperty.heightReference, time, HeightReference.NONE);
+ }
+ if (defined(extrudedHeightProperty)) {
+ extrudedHeightReference = Property.getValueOrDefault(extrudedHeightProperty.heightReference, time, HeightReference.NONE);
+ }
+
+ if (heightReference === HeightReference.NONE && extrudedHeightReference !== HeightReference.RELATIVE_TO_GROUND) {
+ return Cartesian3.clone(Cartesian3.ZERO, result);
+ }
+
+ var scene = this._scene;
+ var position = this._getPosition(time, scratchPosition);
+ if (!defined(position) || Cartesian3.equals(position, Cartesian3.ZERO) || !defined(scene.globe)) {
+ return Cartesian3.clone(Cartesian3.ZERO, result);
+ }
+
+ if (Cartesian3.equalsEpsilon(this._position, position, CesiumMath.EPSILON10)) {
+ return Cartesian3.multiplyByScalar(this._normal, this._terrainHeight, result);
+ }
+
+ this._position = Cartesian3.clone(position, this._position);
+
+ this._updateClamping();
+
+ var normal = scene.globe.ellipsoid.geodeticSurfaceNormal(position, this._normal);
+ return Cartesian3.multiplyByScalar(normal, this._terrainHeight, result);
+ };
+
+ TerrainOffsetProperty.prototype.isDestroyed = function() {
+ return false;
+ };
+
+ TerrainOffsetProperty.prototype.destroy = function() {
+ if (defined(this._removeEventListener)) {
+ this._removeEventListener();
+ }
+ if (defined(this._removeModeListener)) {
+ this._removeModeListener();
+ }
+ if (defined(this._removeCallbackFunc)) {
+ this._removeCallbackFunc();
+ }
+ return destroyObject(this);
+ };
+
+ /**
+ * A function which creates one or more providers.
+ * @callback TerrainOffsetProperty~PositionFunction
+ * @param {JulianDate} time The clock time at which to retrieve the position
+ * @param {Cartesian3} result The result position
+ * @returns {Cartesian3} The position at which to do the terrain height check
+ */
+
+ return TerrainOffsetProperty;
+});
diff --git a/Specs/DataSources/CorridorGeometryUpdaterSpec.js b/Specs/DataSources/CorridorGeometryUpdaterSpec.js
index 940a2718d92b..d074c244febb 100644
--- a/Specs/DataSources/CorridorGeometryUpdaterSpec.js
+++ b/Specs/DataSources/CorridorGeometryUpdaterSpec.js
@@ -2,7 +2,9 @@ defineSuite([
'DataSources/CorridorGeometryUpdater',
'Core/Cartesian3',
'Core/CornerType',
+ 'Core/GeometryOffsetAttribute',
'Core/JulianDate',
+ 'Core/Math',
'Core/TimeInterval',
'Core/TimeIntervalCollection',
'DataSources/ConstantProperty',
@@ -22,7 +24,9 @@ defineSuite([
CorridorGeometryUpdater,
Cartesian3,
CornerType,
+ GeometryOffsetAttribute,
JulianDate,
+ CesiumMath,
TimeInterval,
TimeIntervalCollection,
ConstantProperty,
@@ -54,7 +58,7 @@ defineSuite([
function createBasicCorridor() {
var corridor = new CorridorGraphics();
- corridor.positions = new ConstantProperty(Cartesian3.fromRadiansArray([
+ corridor.positions = new ConstantProperty(Cartesian3.fromDegreesArray([
0, 0,
1, 0,
1, 1,
@@ -69,13 +73,13 @@ defineSuite([
function createDynamicCorridor() {
var entity = createBasicCorridor();
- entity.corridor.positions = createDynamicProperty(Cartesian3.fromRadiansArray([0, 0, 1, 0, 1, 1, 0, 1]));
+ entity.corridor.positions = createDynamicProperty(Cartesian3.fromDegreesArray([0, 0, 1, 0, 1, 1, 0, 1]));
return entity;
}
function createBasicCorridorWithoutHeight() {
var corridor = new CorridorGraphics();
- corridor.positions = new ConstantProperty(Cartesian3.fromRadiansArray([
+ corridor.positions = new ConstantProperty(Cartesian3.fromDegreesArray([
0, 0,
1, 0,
1, 1,
@@ -89,7 +93,7 @@ defineSuite([
function createDynamicCorridorWithoutHeight() {
var entity = createBasicCorridorWithoutHeight();
- entity.corridor.positions = createDynamicProperty(Cartesian3.fromRadiansArray([0, 0, 1, 0, 1, 1, 0, 1]));
+ entity.corridor.positions = createDynamicProperty(Cartesian3.fromDegreesArray([0, 0, 1, 0, 1, 1, 0, 1]));
return entity;
}
@@ -193,6 +197,7 @@ defineSuite([
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
expect(geometry._cornerType).toEqual(options.cornerType);
+ expect(geometry._offsetAttribute).toBeUndefined();
instance = updater.createOutlineGeometryInstance(time);
geometry = instance.geometry;
@@ -201,11 +206,12 @@ defineSuite([
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
expect(geometry._cornerType).toEqual(options.cornerType);
+ expect(geometry._offsetAttribute).toBeUndefined();
});
it('dynamic updater sets properties', function() {
var corridor = new CorridorGraphics();
- corridor.positions = createDynamicProperty(Cartesian3.fromRadiansArray([
+ corridor.positions = createDynamicProperty(Cartesian3.fromDegreesArray([
0, 0,
1, 0,
1, 1,
@@ -234,6 +240,7 @@ defineSuite([
expect(options.width).toEqual(corridor.width.getValue());
expect(options.granularity).toEqual(corridor.granularity.getValue());
expect(options.cornerType).toEqual(corridor.cornerType.getValue());
+ expect(options.offsetAttribute).toBeUndefined();
});
it('geometryChanged event is raised when expected', function() {
@@ -268,6 +275,13 @@ defineSuite([
expect(listener.calls.count()).toEqual(4);
});
+ it('computes center', function() {
+ var entity = createBasicCorridor();
+ var updater = new CorridorGeometryUpdater(entity, scene);
+
+ expect(updater._computeCenter(time)).toEqualEpsilon(Cartesian3.fromDegrees(1.0, 1.0), CesiumMath.EPSILON10);
+ });
+
function getScene() {
return scene;
}
diff --git a/Specs/DataSources/EllipseGeometryUpdaterSpec.js b/Specs/DataSources/EllipseGeometryUpdaterSpec.js
index a429a8dd859a..a10f242244c3 100644
--- a/Specs/DataSources/EllipseGeometryUpdaterSpec.js
+++ b/Specs/DataSources/EllipseGeometryUpdaterSpec.js
@@ -1,6 +1,7 @@
defineSuite([
'DataSources/EllipseGeometryUpdater',
'Core/Cartesian3',
+ 'Core/GeometryOffsetAttribute',
'Core/JulianDate',
'Core/TimeIntervalCollection',
'DataSources/ConstantPositionProperty',
@@ -18,6 +19,7 @@ defineSuite([
], function(
EllipseGeometryUpdater,
Cartesian3,
+ GeometryOffsetAttribute,
JulianDate,
TimeIntervalCollection,
ConstantPositionProperty,
@@ -234,6 +236,7 @@ defineSuite([
expect(geometry._height).toEqual(options.height);
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
+ expect(geometry._offsetAttribute).toBeUndefined();
instance = updater.createOutlineGeometryInstance(time);
geometry = instance.geometry;
@@ -245,6 +248,7 @@ defineSuite([
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
expect(geometry._numberOfVerticalLines).toEqual(options.numberOfVerticalLines);
+ expect(geometry._offsetAttribute).toBeUndefined();
});
it('dynamic updater sets properties', function() {
@@ -265,6 +269,7 @@ defineSuite([
expect(options.semiMajorAxis).toEqual(ellipse.semiMajorAxis.getValue());
expect(options.semiMinorAxis).toEqual(ellipse.semiMinorAxis.getValue());
expect(options.height).toEqual(ellipse.height.getValue());
+ expect(options.offsetAttribute).toBeUndefined();
});
it('geometryChanged event is raised when expected', function() {
@@ -304,6 +309,13 @@ defineSuite([
expect(listener.calls.count()).toEqual(5);
});
+ it('computes center', function() {
+ var entity = createBasicEllipse();
+ var updater = new EllipseGeometryUpdater(entity, scene);
+
+ expect(updater._computeCenter(time)).toEqual(entity.position.getValue(time));
+ });
+
function getScene() {
return scene;
}
diff --git a/Specs/DataSources/GeometryHeightPropertySpec.js b/Specs/DataSources/GeometryHeightPropertySpec.js
new file mode 100644
index 000000000000..bdaf1021c505
--- /dev/null
+++ b/Specs/DataSources/GeometryHeightPropertySpec.js
@@ -0,0 +1,150 @@
+defineSuite([
+ 'DataSources/GeometryHeightProperty',
+ 'Core/ApproximateTerrainHeights',
+ 'Core/Event',
+ 'Core/JulianDate',
+ 'Core/Rectangle',
+ 'Scene/HeightReference',
+ 'DataSources/ConstantProperty'
+], function(
+ GeometryHeightProperty,
+ ApproximateTerrainHeights,
+ Event,
+ JulianDate,
+ Rectangle,
+ HeightReference,
+ ConstantProperty) {
+ 'use strict';
+
+ var time = JulianDate.now();
+ beforeAll(function() {
+ return ApproximateTerrainHeights.initialize();
+ });
+
+ afterAll(function() {
+ ApproximateTerrainHeights._initPromise = undefined;
+ ApproximateTerrainHeights._terrainHeights = undefined;
+ });
+
+ it('can default construct', function() {
+ var property = new GeometryHeightProperty();
+ expect(property.isConstant).toBe(true);
+ expect(property.definitionChanged).toBeInstanceOf(Event);
+ expect(property.height).toBeUndefined();
+ expect(property.heightReference).toBeUndefined();
+ expect(property.getValue(time)).toBe(0);
+ });
+
+ it('can construct with arguments', function() {
+ var height = new ConstantProperty(30);
+ var heightReference = new ConstantProperty(HeightReference.NONE);
+ var property = new GeometryHeightProperty(height, heightReference);
+ expect(property.isConstant).toBe(true);
+ expect(property.definitionChanged).toBeInstanceOf(Event);
+ expect(property.height).toBe(height);
+ expect(property.heightReference).toBe(heightReference);
+ expect(property.getValue(time)).toBe(30);
+ });
+
+ it('setting height raises definitionChanged event', function() {
+ var property = new GeometryHeightProperty();
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.height = new ConstantProperty();
+ expect(listener).toHaveBeenCalledWith(property);
+ });
+
+ it('setting heightReference raises definitionChanged event', function() {
+ var property = new GeometryHeightProperty();
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.heightReference = new ConstantProperty();
+ expect(listener).toHaveBeenCalledWith(property);
+ });
+
+ it('setting height does not raise definitionChanged event for same data', function() {
+ var height = new ConstantProperty(30);
+ var property = new GeometryHeightProperty(height);
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.height = height;
+ expect(listener.calls.count()).toBe(0);
+ });
+
+ it('setting heightReference does not raise definitionChanged event for same data', function() {
+ var heightReference = new ConstantProperty(HeightReference.NONE);
+ var property = new GeometryHeightProperty(undefined, heightReference);
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.heightReference = heightReference;
+ expect(listener.calls.count()).toBe(0);
+ });
+
+ it('getValue works for for height reference NONE and RELATIVE_TO_GROUND', function() {
+ var expected = 30;
+ var height = new ConstantProperty(expected);
+ var heightReference = new ConstantProperty(HeightReference.NONE);
+ var property = new GeometryHeightProperty(height, heightReference);
+ expect(property.getValue(time)).toBe(expected);
+
+ property.heightReference = new ConstantProperty(HeightReference.RELATIVE_TO_GROUND);
+ expect(property.getValue(time)).toBe(expected);
+ });
+
+ it('getValue works for for height reference CLAMP_TO_GROUND', function() {
+ var height = new ConstantProperty(50);
+ var heightReference = new ConstantProperty(HeightReference.CLAMP_TO_GROUND);
+ var property = new GeometryHeightProperty(height, heightReference);
+ expect(property.getValue(time)).toBe(0);
+ });
+
+ it('equals works', function() {
+ var height = new ConstantProperty(50);
+ var heightReference = new ConstantProperty(HeightReference.NONE);
+
+ var left = new GeometryHeightProperty();
+ var right = new GeometryHeightProperty();
+
+ expect(left.equals(undefined)).toBe(false);
+ expect(left.equals(right)).toBe(true);
+
+ left.height = height;
+ expect(left.equals(right)).toBe(false);
+
+ right.height = height;
+ expect(left.equals(right)).toBe(true);
+
+ left.heightReference = heightReference;
+ expect(left.equals(right)).toBe(false);
+
+ right.heightReference = heightReference;
+ expect(left.equals(right)).toBe(true);
+ });
+
+ it('getValue throws without time', function() {
+ var property = new GeometryHeightProperty();
+ expect(function() {
+ property.getValue();
+ }).toThrowDeveloperError();
+ });
+
+ it('getMinimumTerrainValue return terrain value', function() {
+ var rectangle = Rectangle.fromDegrees(0, 0, 1, 1);
+ var expected = ApproximateTerrainHeights.getApproximateTerrainHeights(rectangle).minimumTerrainHeight;
+ expect(GeometryHeightProperty.getMinimumTerrainValue(rectangle)).toBe(expected);
+ });
+
+ it('getMinimumTerrainValue throws without rectangle', function() {
+ expect(function() {
+ return GeometryHeightProperty.getMinimumTerrainValue();
+ }).toThrowDeveloperError();
+ });
+});
diff --git a/Specs/DataSources/PolygonGeometryUpdaterSpec.js b/Specs/DataSources/PolygonGeometryUpdaterSpec.js
index 1e87f87d4d5a..f9b13de57acb 100644
--- a/Specs/DataSources/PolygonGeometryUpdaterSpec.js
+++ b/Specs/DataSources/PolygonGeometryUpdaterSpec.js
@@ -1,7 +1,10 @@
defineSuite([
'DataSources/PolygonGeometryUpdater',
'Core/Cartesian3',
+ 'Core/Ellipsoid',
+ 'Core/GeometryOffsetAttribute',
'Core/JulianDate',
+ 'Core/Math',
'Core/PolygonHierarchy',
'Core/TimeIntervalCollection',
'DataSources/ConstantProperty',
@@ -20,7 +23,10 @@ defineSuite([
], function(
PolygonGeometryUpdater,
Cartesian3,
+ Ellipsoid,
+ GeometryOffsetAttribute,
JulianDate,
+ CesiumMath,
PolygonHierarchy,
TimeIntervalCollection,
ConstantProperty,
@@ -55,10 +61,10 @@ defineSuite([
function createBasicPolygon() {
var polygon = new PolygonGraphics();
polygon.hierarchy = new ConstantProperty(new PolygonHierarchy(Cartesian3.fromRadiansArray([
- 0, 0,
- 1, 0,
+ -1, -1,
+ 1, -1,
1, 1,
- 0, 1
+ -1, 1
])));
polygon.height = new ConstantProperty(0);
var entity = new Entity();
@@ -225,6 +231,7 @@ defineSuite([
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
expect(geometry._closeTop).toEqual(options.closeTop);
expect(geometry._closeBottom).toEqual(options.closeBottom);
+ expect(geometry._offsetAttribute).toBeUndefined();
instance = updater.createOutlineGeometryInstance(time);
geometry = instance.geometry;
@@ -232,6 +239,7 @@ defineSuite([
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
expect(geometry._perPositionHeight).toEqual(options.perPositionHeight);
+ expect(geometry._offsetAttribute).toBeUndefined();
});
it('Checks that a polygon with per position heights isn\'t on terrain', function() {
@@ -291,6 +299,7 @@ defineSuite([
expect(options.stRotation).toEqual(polygon.stRotation.getValue());
expect(options.closeTop).toEqual(polygon.closeTop.getValue());
expect(options.closeBottom).toEqual(polygon.closeBottom.getValue());
+ expect(options.offsetAttribute).toBeUndefined();
});
it('geometryChanged event is raised when expected', function() {
@@ -333,6 +342,14 @@ defineSuite([
expect(updater.onTerrain).toBe(false);
});
+ it('computes center', function() {
+ var entity = createBasicPolygon();
+ var updater = new PolygonGeometryUpdater(entity, scene);
+ var result = updater._computeCenter(time);
+ result = Ellipsoid.WGS84.scaleToGeodeticSurface(result, result);
+ expect(result).toEqualEpsilon(Cartesian3.fromDegrees(0.0, 0.0), CesiumMath.EPSILON10);
+ });
+
function getScene() {
return scene;
}
diff --git a/Specs/DataSources/PolylineGeometryUpdaterSpec.js b/Specs/DataSources/PolylineGeometryUpdaterSpec.js
index cc14250f3aef..67f2e43daff3 100644
--- a/Specs/DataSources/PolylineGeometryUpdaterSpec.js
+++ b/Specs/DataSources/PolylineGeometryUpdaterSpec.js
@@ -800,5 +800,7 @@ defineSuite([
var instance = updater.createFillGeometryInstance(time);
expect(instance.geometry instanceof GroundPolylineGeometry).toBe(false);
+
+ updater.destroy();
});
}, 'WebGL');
diff --git a/Specs/DataSources/RectangleGeometryUpdaterSpec.js b/Specs/DataSources/RectangleGeometryUpdaterSpec.js
index 2608b931511f..5f14ca3741c2 100644
--- a/Specs/DataSources/RectangleGeometryUpdaterSpec.js
+++ b/Specs/DataSources/RectangleGeometryUpdaterSpec.js
@@ -1,7 +1,9 @@
defineSuite([
'DataSources/RectangleGeometryUpdater',
'Core/Cartesian3',
+ 'Core/GeometryOffsetAttribute',
'Core/JulianDate',
+ 'Core/Math',
'Core/Rectangle',
'Core/TimeIntervalCollection',
'DataSources/ConstantProperty',
@@ -17,7 +19,9 @@ defineSuite([
], function(
RectangleGeometryUpdater,
Cartesian3,
+ GeometryOffsetAttribute,
JulianDate,
+ CesiumMath,
Rectangle,
TimeIntervalCollection,
ConstantProperty,
@@ -48,7 +52,7 @@ defineSuite([
var rectangle = new RectangleGraphics();
var entity = new Entity();
entity.rectangle = rectangle;
- entity.rectangle.coordinates = new ConstantProperty(new Rectangle(0, 0, 1, 1));
+ entity.rectangle.coordinates = new ConstantProperty(new Rectangle(-1, -1, 1, 1));
entity.rectangle.height = new ConstantProperty(0);
return entity;
}
@@ -161,12 +165,14 @@ defineSuite([
expect(geometry._surfaceHeight).toEqual(options.height);
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
+ expect(geometry._offsetAttribute).toBeUndefined();
instance = updater.createOutlineGeometryInstance(time);
geometry = instance.geometry;
expect(geometry._surfaceHeight).toEqual(options.height);
expect(geometry._granularity).toEqual(options.granularity);
expect(geometry._extrudedHeight).toEqual(options.extrudedHeight);
+ expect(geometry._offsetAttribute).toBeUndefined();
});
it('dynamic updater sets properties', function() {
@@ -194,6 +200,7 @@ defineSuite([
expect(options.extrudedHeight).toEqual(rectangle.extrudedHeight.getValue());
expect(options.granularity).toEqual(rectangle.granularity.getValue());
expect(options.stRotation).toEqual(rectangle.stRotation.getValue());
+ expect(options.offsetAttribute).toBeUndefined();
});
it('geometryChanged event is raised when expected', function() {
@@ -224,6 +231,13 @@ defineSuite([
expect(listener.calls.count()).toEqual(3);
});
+ it('computes center', function() {
+ var entity = createBasicRectangle();
+ var updater = new RectangleGeometryUpdater(entity, scene);
+
+ expect(updater._computeCenter(time)).toEqualEpsilon(Cartesian3.fromDegrees(0.0, 0.0), CesiumMath.EPSILON10);
+ });
+
function getScene() {
return scene;
}
diff --git a/Specs/DataSources/TerrainOffsetPropertySpec.js b/Specs/DataSources/TerrainOffsetPropertySpec.js
new file mode 100644
index 000000000000..d565db1d6e27
--- /dev/null
+++ b/Specs/DataSources/TerrainOffsetPropertySpec.js
@@ -0,0 +1,77 @@
+defineSuite([
+ 'DataSources/TerrainOffsetProperty',
+ 'Core/Cartesian3',
+ 'Core/Event',
+ 'Core/JulianDate',
+ 'Core/Rectangle',
+ 'Scene/HeightReference',
+ 'DataSources/ConstantProperty',
+ 'Specs/createGlobe',
+ 'Specs/createScene'
+], function(
+ TerrainOffsetProperty,
+ Cartesian3,
+ Event,
+ JulianDate,
+ Rectangle,
+ HeightReference,
+ ConstantProperty,
+ createGlobe,
+ createScene) {
+ 'use strict';
+
+ var scene;
+ var time = JulianDate.now();
+ beforeAll(function() {
+ scene = createScene();
+ scene.globe = createGlobe();
+ });
+
+ afterAll(function() {
+ scene.destroyForSpecs();
+ });
+
+ it('can construct and destroy', function() {
+ var getPosition = jasmine.createSpy();
+ var height = new ConstantProperty(30);
+ var extrudedHeight = new ConstantProperty(0);
+ var property = new TerrainOffsetProperty(scene, height, extrudedHeight, getPosition);
+ expect(property.isConstant).toBe(false);
+ expect(property.getValue(time)).toEqual(Cartesian3.ZERO);
+ property.destroy();
+ expect(property.isDestroyed()).toBe(true);
+ });
+
+ it('throws without scene', function() {
+ var getPosition = jasmine.createSpy();
+ var height = new ConstantProperty(30);
+ var extrudedHeight = new ConstantProperty(0);
+ expect(function() {
+ return new TerrainOffsetProperty(undefined, height, extrudedHeight, getPosition);
+ }).toThrowDeveloperError();
+ });
+
+ it('throws without height', function() {
+ var getPosition = jasmine.createSpy();
+ var extrudedHeight = new ConstantProperty(0);
+ expect(function() {
+ return new TerrainOffsetProperty(scene, undefined, extrudedHeight, getPosition);
+ }).toThrowDeveloperError();
+ });
+
+ it('throws without extrudedHeight', function() {
+ var getPosition = jasmine.createSpy();
+ var height = new ConstantProperty(30);
+ expect(function() {
+ return new TerrainOffsetProperty(scene, height, undefined, getPosition);
+ }).toThrowDeveloperError();
+ });
+
+ it('throws without getPosition', function() {
+ var height = new ConstantProperty(30);
+ var extrudedHeight = new ConstantProperty(0);
+ expect(function() {
+ return new TerrainOffsetProperty(scene, height, extrudedHeight, undefined);
+ }).toThrowDeveloperError();
+ });
+});
diff --git a/Specs/createGeometryUpdaterGroundGeometrySpecs.js b/Specs/createGeometryUpdaterGroundGeometrySpecs.js
index b0ed38ab479c..9334437e320b 100644
--- a/Specs/createGeometryUpdaterGroundGeometrySpecs.js
+++ b/Specs/createGeometryUpdaterGroundGeometrySpecs.js
@@ -1,20 +1,26 @@
define([
'Core/Color',
+ 'Core/GeometryOffsetAttribute',
'Core/JulianDate',
'DataSources/ColorMaterialProperty',
'DataSources/ConstantProperty',
+ 'DataSources/GeometryHeightProperty',
'DataSources/SampledProperty',
'Scene/ClassificationType',
'Scene/GroundPrimitive',
+ 'Scene/HeightReference',
'Scene/PrimitiveCollection'
], function(
Color,
+ GeometryOffsetAttribute,
JulianDate,
ColorMaterialProperty,
ConstantProperty,
+ GeometryHeightProperty,
SampledProperty,
ClassificationType,
GroundPrimitive,
+ HeightReference,
PrimitiveCollection) {
'use strict';
@@ -119,6 +125,108 @@ define([
expect(updater.onTerrain).toBe(false);
});
+ it('Creates geometry with no offsetAttribute when geometry is on terrain', function() {
+ var entity = createEntity();
+
+ var updater = new Updater(entity, getScene());
+
+ var instance;
+ var geometry;
+ instance = updater.createFillGeometryInstance(time);
+ geometry = instance.geometry;
+ expect(geometry._offsetAttribute).toBeUndefined();
+ });
+
+ it('Creates geometry with expected offsetAttribute based on height and extrudedHeight', function() {
+ var entity = createEntity();
+ var graphics = entity[geometryPropertyName];
+ graphics.outline = true;
+ graphics.outlineColor = Color.BLACK;
+ var updater = new Updater(entity, getScene());
+
+ var instance;
+
+ graphics.height = new ConstantProperty(20.0);
+ graphics.extrudedHeight = new ConstantProperty(0.0);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.NONE);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.NONE);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.NONE);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.CLAMP_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toBeUndefined();
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.NONE);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.RELATIVE_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.CLAMP_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.NONE);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.CLAMP_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.CLAMP_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.CLAMP_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.RELATIVE_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.ALL);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.ALL);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.RELATIVE_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.NONE);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.RELATIVE_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.CLAMP_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.TOP);
+
+ graphics.height = new GeometryHeightProperty(20.0, HeightReference.RELATIVE_TO_GROUND);
+ graphics.extrudedHeight = new GeometryHeightProperty(0.0, HeightReference.RELATIVE_TO_GROUND);
+ updater._onEntityPropertyChanged(entity, geometryPropertyName);
+ instance = updater.createFillGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.ALL);
+ instance = updater.createOutlineGeometryInstance(time);
+ expect(instance.geometry._offsetAttribute).toEqual(GeometryOffsetAttribute.ALL);
+ });
+
it('color material sets onTerrain to true', function() {
var entity = createEntity();
var geometry = entity[geometryPropertyName];