define([ 'Core/Color', 'Core/ColorGeometryInstanceAttribute', 'Core/DistanceDisplayCondition', 'Core/DistanceDisplayConditionGeometryInstanceAttribute', 'Core/JulianDate', 'Core/ShowGeometryInstanceAttribute', 'Core/TimeInterval', 'DataSources/ColorMaterialProperty', 'DataSources/ConstantProperty', 'DataSources/EllipsoidGeometryUpdater', 'DataSources/Entity', 'DataSources/GridMaterialProperty', 'DataSources/SampledProperty', 'DataSources/TimeIntervalCollectionProperty', 'Scene/ShadowMode' ], function( Color, ColorGeometryInstanceAttribute, DistanceDisplayCondition, DistanceDisplayConditionGeometryInstanceAttribute, JulianDate, ShowGeometryInstanceAttribute, TimeInterval, ColorMaterialProperty, ConstantProperty, EllipsoidGeometryUpdater, Entity, GridMaterialProperty, SampledProperty, TimeIntervalCollectionProperty, ShadowMode) { 'use strict'; function createGeometryUpdaterSpecs(Updater, geometryPropertyName, createEntity, getScene) { var time = JulianDate.now(); it('Constructor sets expected defaults', function() { var entity = createEntity(); var updater = new Updater(entity, getScene()); expect(updater.isDestroyed()).toBe(false); expect(updater.entity).toBe(entity); expect(updater.isClosed).toBe(updater._getIsClosed(updater._options)); expect(updater.fillEnabled).toBe(true); expect(updater.fillMaterialProperty).toBeInstanceOf(ColorMaterialProperty); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); expect(updater.outlineColorProperty).toBe(undefined); expect(updater.outlineWidth).toBe(1.0); expect(updater.shadowsProperty.getValue()).toBe(ShadowMode.DISABLED); expect(updater.distanceDisplayConditionProperty.getValue()).toEqual(new DistanceDisplayCondition()); expect(updater.isDynamic).toBe(false); expect(updater.onTerrain).toBe(false); expect(updater.isOutlineVisible(time)).toBe(false); expect(updater.isFilled(time)).toBe(true); updater.destroy(); expect(updater.isDestroyed()).toBe(true); }); it('No geometry created when entity geometry property is undefined ', function() { var entity = new Entity(); var updater = new Updater(entity, getScene()); expect(updater.fillEnabled).toBe(false); expect(updater.outlineEnabled).toBe(false); expect(updater.isDynamic).toBe(false); }); it('No geometry available when not filled or outline.', function() { var entity = createEntity(); entity[geometryPropertyName].fill = new ConstantProperty(false); entity[geometryPropertyName].outline = new ConstantProperty(false); var updater = new Updater(entity, getScene()); expect(updater.fillEnabled).toBe(false); expect(updater.outlineEnabled).toBe(false); expect(updater.isDynamic).toBe(false); }); it('Values correct when using default graphics', function() { var entity = createEntity(); var updater = new Updater(entity, getScene()); expect(updater.isClosed).toBe(updater._getIsClosed(updater._options)); expect(updater.fillEnabled).toBe(true); expect(updater.fillMaterialProperty).toEqual(new ColorMaterialProperty(Color.WHITE)); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); expect(updater.outlineColorProperty).toBe(undefined); expect(updater.outlineWidth).toBe(1.0); expect(updater.shadowsProperty).toEqual(new ConstantProperty(ShadowMode.DISABLED)); expect(updater.distanceDisplayConditionProperty).toEqual(new ConstantProperty(new DistanceDisplayCondition())); expect(updater.isDynamic).toBe(false); }); it('material is correctly exposed.', function() { var entity = createEntity(); entity[geometryPropertyName].material = new GridMaterialProperty(Color.BLUE); var updater = new Updater(entity, getScene()); expect(updater.fillMaterialProperty).toBe(entity[geometryPropertyName].material); }); it('A time-varying outlineWidth causes geometry to be dynamic', function() { var entity = createEntity(); entity[geometryPropertyName].outlineWidth = new SampledProperty(Number); entity[geometryPropertyName].outlineWidth.addSample(time, 1); var updater = new Updater(entity, getScene()); expect(updater.isDynamic).toBe(true); }); it('Correctly exposes outlineWidth', function() { var entity = createEntity(); entity[geometryPropertyName].outlineWidth = new ConstantProperty(8); var updater = new Updater(entity, getScene()); expect(updater.outlineWidth).toBe(8); }); it('Attributes have expected values at creation time', function() { var time1 = new JulianDate(0, 0); var time2 = new JulianDate(10, 0); var time3 = new JulianDate(20, 0); var fill = new TimeIntervalCollectionProperty(); fill.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : false })); fill.intervals.addInterval(new TimeInterval({ start : time2, stop : time3, isStartIncluded : false, data : true })); var colorMaterial = new ColorMaterialProperty(); colorMaterial.color = new SampledProperty(Color); colorMaterial.color.addSample(time, Color.YELLOW); colorMaterial.color.addSample(time2, Color.BLUE); colorMaterial.color.addSample(time3, Color.RED); var outline = new TimeIntervalCollectionProperty(); outline.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : false })); outline.intervals.addInterval(new TimeInterval({ start : time2, stop : time3, isStartIncluded : false, data : true })); var outlineColor = new SampledProperty(Color); outlineColor.addSample(time, Color.BLUE); outlineColor.addSample(time2, Color.RED); outlineColor.addSample(time3, Color.YELLOW); var entity = createEntity(); entity[geometryPropertyName].fill = fill; entity[geometryPropertyName].material = colorMaterial; entity[geometryPropertyName].outline = outline; entity[geometryPropertyName].outlineColor = outlineColor; var updater = new Updater(entity, getScene()); var instance = updater.createFillGeometryInstance(time2); var attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(colorMaterial.color.getValue(time2))); expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(fill.getValue(time2))); instance = updater.createOutlineGeometryInstance(time2); attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(outlineColor.getValue(time2))); expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(outline.getValue(time2))); }); it('createFillGeometryInstance obeys Entity.show is false.', function() { var entity = createEntity(); entity.show = false; entity[geometryPropertyName].fill = true; var updater = new Updater(entity, getScene()); var instance = updater.createFillGeometryInstance(new JulianDate()); var attributes = instance.attributes; expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(false)); }); it('createOutlineGeometryInstance obeys Entity.show is false.', function() { var entity = createEntity(); entity.show = false; entity[geometryPropertyName].outline = true; var updater = new Updater(entity, getScene()); var instance = updater.createFillGeometryInstance(new JulianDate()); var attributes = instance.attributes; expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(false)); }); it('createFillGeometryInstance throws if object is not filled', function() { if (Updater === EllipsoidGeometryUpdater) { // ellipsoid doesn't throw developer error because it always creates both fill and outline when dynamic return; } var entity = new Entity(); var updater = new Updater(entity, getScene()); expect(function() { return updater.createFillGeometryInstance(time); }).toThrowDeveloperError(); }); it('createFillGeometryInstance throws if no time provided', function() { var entity = createEntity(); var updater = new Updater(entity, getScene()); expect(function() { return updater.createFillGeometryInstance(undefined); }).toThrowDeveloperError(); }); it('createOutlineGeometryInstance throws if object is not outlined', function() { if (Updater === EllipsoidGeometryUpdater) { // ellipsoid doesn't throw developer error because it always creates both fill and outline when dynamic return; } var entity = new Entity(); var updater = new Updater(entity, getScene()); expect(function() { return updater.createOutlineGeometryInstance(time); }).toThrowDeveloperError(); }); it('createOutlineGeometryInstance throws if no time provided', function() { var entity = createEntity(); entity[geometryPropertyName].outline = new ConstantProperty(true); var updater = new Updater(entity, getScene()); expect(function() { return updater.createOutlineGeometryInstance(undefined); }).toThrowDeveloperError(); }); function validateGeometryInstanceAttributes(options) { var entity = createEntity(); var geometryProperty = entity[geometryPropertyName]; geometryProperty.show = true; geometryProperty.fill = true; geometryProperty.material = options.material; geometryProperty.outline = true; geometryProperty.outlineColor = new ConstantProperty(options.outlineColor); geometryProperty.distanceDisplayCondition = options.distanceDisplayCondition; var updater = new Updater(entity, getScene()); var instance; var attributes; instance = updater.createFillGeometryInstance(time); attributes = instance.attributes; if (options.material instanceof ColorMaterialProperty) { expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.material.color.getValue(time))); } else { expect(attributes.color).toBeUndefined(); } expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(true)); if (options.distanceDisplayCondition) { expect(attributes.distanceDisplayCondition.value).toEqual(DistanceDisplayConditionGeometryInstanceAttribute.toValue(options.distanceDisplayCondition)); } instance = updater.createOutlineGeometryInstance(time); attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.outlineColor)); expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(true)); if (options.distanceDisplayCondition) { expect(attributes.distanceDisplayCondition.value).toEqual(DistanceDisplayConditionGeometryInstanceAttribute.toValue(options.distanceDisplayCondition)); } } it('Creates expected per-color geometry', function() { validateGeometryInstanceAttributes({ material : new ColorMaterialProperty(Color.RED), outlineColor : Color.BLUE }); }); it('Creates expected per-material geometry', function() { validateGeometryInstanceAttributes({ material : new GridMaterialProperty(), outlineColor : Color.GREEN }); }); it('Creates expected distance display condition geometry', function() { validateGeometryInstanceAttributes({ material : new ColorMaterialProperty(Color.BLUE), outlineColor : Color.RED, distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0) }); }); it('Attributes have expected values at creation time', function() { var time1 = new JulianDate(0, 0); var time2 = new JulianDate(10, 0); var time3 = new JulianDate(20, 0); var fill = new TimeIntervalCollectionProperty(); fill.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : false })); fill.intervals.addInterval(new TimeInterval({ start : time2, stop : time3, isStartIncluded : false, data : true })); var colorMaterial = new ColorMaterialProperty(); colorMaterial.color = new SampledProperty(Color); colorMaterial.color.addSample(time, Color.YELLOW); colorMaterial.color.addSample(time2, Color.BLUE); colorMaterial.color.addSample(time3, Color.RED); var outline = new TimeIntervalCollectionProperty(); outline.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : false })); outline.intervals.addInterval(new TimeInterval({ start : time2, stop : time3, isStartIncluded : false, data : true })); var outlineColor = new SampledProperty(Color); outlineColor.addSample(time, Color.BLUE); outlineColor.addSample(time2, Color.RED); outlineColor.addSample(time3, Color.YELLOW); var entity = createEntity(); var geoemtry = entity[geometryPropertyName]; geoemtry.fill = fill; geoemtry.material = colorMaterial; geoemtry.outline = outline; geoemtry.outlineColor = outlineColor; var updater = new Updater(entity, getScene()); var instance = updater.createFillGeometryInstance(time2); var attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(colorMaterial.color.getValue(time2))); expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(fill.getValue(time2))); instance = updater.createOutlineGeometryInstance(time2); attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(outlineColor.getValue(time2))); expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(outline.getValue(time2))); }); it('Works with dynamic color with missing interval', function() { var time1 = new JulianDate(0, 0); var time2 = new JulianDate(10, 0); var missingTime = new JulianDate(15, 0); var time3 = new JulianDate(20, 0); var time4 = new JulianDate(30, 0); var colorMaterial = new ColorMaterialProperty(); var color = new TimeIntervalCollectionProperty(); color.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : Color.BLUE })); color.intervals.addInterval(new TimeInterval({ start : time3, stop : time4, isStartIncluded : false, data : Color.YELLOW })); colorMaterial.color = color; var outlineColor = new TimeIntervalCollectionProperty(); outlineColor.intervals.addInterval(new TimeInterval({ start : time1, stop : time2, data : Color.RED })); outlineColor.intervals.addInterval(new TimeInterval({ start : time3, stop : time4, isStartIncluded : false, data : Color.GREEN })); var entity = createEntity(); var geometry = entity[geometryPropertyName]; geometry.fill = true; geometry.outline = true; geometry.material = colorMaterial; geometry.outlineColor = outlineColor; var updater = new Updater(entity, getScene()); var instance = updater.createFillGeometryInstance(missingTime); var attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); instance = updater.createOutlineGeometryInstance(missingTime); attributes = instance.attributes; expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(Color.BLACK)); }); } return createGeometryUpdaterSpecs; });