From a16cf49d04786b0af6f0c91aa6731b5d84d9f2fa Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 23 Jan 2014 17:00:29 -0500 Subject: [PATCH 01/81] Start of DynamicScene refactor Start adding `isConstant` property and `definitionChanged` Event to all `Property` objects. Start migrating code to new DataSource directory. --- Source/Core/DeveloperError.js | 7 + Source/DataSource/CompositeProperty.js | 155 +++++ Source/DataSource/ConstantPositionProperty.js | 154 +++++ Source/DataSource/ConstantProperty.js | 123 ++++ Source/DataSource/PositionProperty.js | 131 +++++ Source/DataSource/Property.js | 83 +++ Source/DataSource/SampledPositionProperty.js | 218 ++++++++ Source/DataSource/SampledProperty.js | 528 ++++++++++++++++++ .../TimeIntervalCollectionPositionProperty.js | 158 ++++++ .../TimeIntervalCollectionProperty.js | 152 +++++ Specs/DataSource/CompositePropertySpec.js | 110 ++++ .../ConstantPositionPropertySpec.js | 131 +++++ Specs/DataSource/ConstantPropertySpec.js | 97 ++++ .../DataSource/SampledPositionPropertySpec.js | 264 +++++++++ Specs/DataSource/SampledPropertySpec.js | 372 ++++++++++++ ...eIntervalCollectionPositionPropertySpec.js | 181 ++++++ .../TimeIntervalCollectionPropertySpec.js | 129 +++++ 17 files changed, 2993 insertions(+) create mode 100644 Source/DataSource/CompositeProperty.js create mode 100644 Source/DataSource/ConstantPositionProperty.js create mode 100644 Source/DataSource/ConstantProperty.js create mode 100644 Source/DataSource/PositionProperty.js create mode 100644 Source/DataSource/Property.js create mode 100644 Source/DataSource/SampledPositionProperty.js create mode 100644 Source/DataSource/SampledProperty.js create mode 100644 Source/DataSource/TimeIntervalCollectionPositionProperty.js create mode 100644 Source/DataSource/TimeIntervalCollectionProperty.js create mode 100644 Specs/DataSource/CompositePropertySpec.js create mode 100644 Specs/DataSource/ConstantPositionPropertySpec.js create mode 100644 Specs/DataSource/ConstantPropertySpec.js create mode 100644 Specs/DataSource/SampledPositionPropertySpec.js create mode 100644 Specs/DataSource/SampledPropertySpec.js create mode 100644 Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js create mode 100644 Specs/DataSource/TimeIntervalCollectionPropertySpec.js diff --git a/Source/Core/DeveloperError.js b/Source/Core/DeveloperError.js index fa7416741b15..5adfce986f6a 100644 --- a/Source/Core/DeveloperError.js +++ b/Source/Core/DeveloperError.js @@ -54,5 +54,12 @@ define(['./defined'], function(defined) { return str; }; + /** + * @private + */ + DeveloperError.throwInstantiationError = function() { + throw new DeveloperError('This type should not be instantiated directly.'); + }; + return DeveloperError; }); diff --git a/Source/DataSource/CompositeProperty.js b/Source/DataSource/CompositeProperty.js new file mode 100644 index 000000000000..de04dba8db01 --- /dev/null +++ b/Source/DataSource/CompositeProperty.js @@ -0,0 +1,155 @@ +/*global define*/ +define(['./Property', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/EventHelper', + '../Core/TimeIntervalCollection', + '../Core/wrapFunction' + ], function( + Property, + defined, + defineProperties, + DeveloperError, + Event, + EventHelper, + TimeIntervalCollection, + wrapFunction) { + "use strict"; + + function subscribeAll(property, eventHelper, definitionChanged, intervals) { + var callback = function() { + definitionChanged.raiseEvent(property); + }; + + var items = []; + eventHelper.removeAll(); + var length = intervals.getLength(); + for (var i = 0; i < length; i++) { + var interval = intervals.get(i); + if (defined(interval.data) && items.indexOf(interval.data) === -1) { + eventHelper.add(interval.data.definitionChanged, callback); + } + } + } + + /** + * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the + * data property of each {@link TimeInterval} is another Property instance which is + * evaluated at the provided time. + * + * @alias CompositeProperty + * @constructor + * + * @see CompositeMaterialProperty + * @see CompositePositionProperty + * + * @example + * var constantProperty = ...; + * var sampledProperty = ...; + * + * //Create a composite property from two previously defined properties + * //where the property is valid on August 1st, 2012 and uses a constant + * //property for the first half of the day and a sampled property for the + * //remaining half. + * var composite = new Cesium.CompositeProperty(); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T12:00:00.00Z', true, true, constantProperty)); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', false, false, sampledProperty)); + */ + var CompositeProperty = function() { + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var eventHelper = new EventHelper(); + var intervalsChanged = function() { + subscribeAll(that, eventHelper, definitionChanged, intervals); + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, intervals.addInterval, intervalsChanged); + intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, intervalsChanged); + intervals.clear = wrapFunction(intervals, intervals.clear, intervalsChanged); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; + }; + + defineProperties(CompositeProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof CompositeProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof CompositeProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; + } + } + }); + + /** + * Gets the value of the property at the provided time. + * @memberof CompositeProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + CompositeProperty.prototype.getValue = function(time, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required'); + } + //>>includeEnd('debug'); + + var innerProperty = this._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValue(time, result); + } + return undefined; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof CompositeProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + CompositeProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositeProperty && // + this._intervals.equals(other._intervals, Property.equals)); + }; + + return CompositeProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/ConstantPositionProperty.js b/Source/DataSource/ConstantPositionProperty.js new file mode 100644 index 000000000000..ff2f74412afc --- /dev/null +++ b/Source/DataSource/ConstantPositionProperty.js @@ -0,0 +1,154 @@ +/*global define*/ +define(['./PositionProperty', + './Property', + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame' + ], function( + PositionProperty, + Property, + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame) { + "use strict"; + + /** + * A {@link PositionProperty} whose value does not change in respect to the + * {@link ReferenceFrame} in which is it defined. + * + * @alias ConstantPositionProperty + * @constructor + * + * @param {Cartesian3} [value] The property value. + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + var ConstantPositionProperty = function(value, referenceFrame) { + this._definitionChanged = new Event(); + this._value = Cartesian3.clone(value); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + }; + + defineProperties(ConstantPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return !defined(this._value) || this._referenceFrame === ReferenceFrame.FIXED; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof ConstantPositionProperty.prototype + * @Type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * @memberof ConstantPositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + ConstantPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof ConstantPositionProperty + * + * @param {Cartesian3} value The property value. + * @param {ReferenceFrame} [referenceFrame=this.referenceFrame] The reference frame in which the position is defined. + */ + ConstantPositionProperty.prototype.setValue = function(value, referenceFrame) { + var definitionChanged = false; + if (!Cartesian3.equals(this._value, value)) { + definitionChanged = true; + this._value = Cartesian3.clone(value); + } + if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { + definitionChanged = true; + this._referenceFrame = defaultValue(this._referenceFrame, referenceFrame); + } + if (definitionChanged) { + this._definitionChanged.raiseEvent(this); + } + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof ConstantPositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + ConstantPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + //>>includeEnd('debug'); + + return PositionProperty.convertToReferenceFrame(time, this._value, this._referenceFrame, referenceFrame, result); + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof ConstantPositionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + ConstantPositionProperty.prototype.equals = function(other) { + return this === other || + (other instanceof ConstantPositionProperty && + Cartesian3.equals(this._value, other._value) && + this._referenceFrame === other._referenceFrame); + }; + + return ConstantPositionProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/ConstantProperty.js b/Source/DataSource/ConstantProperty.js new file mode 100644 index 000000000000..8abfc5e8c9d3 --- /dev/null +++ b/Source/DataSource/ConstantProperty.js @@ -0,0 +1,123 @@ +/*global define*/ +define(['../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Enumeration', + '../Core/Event' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Enumeration, + Event) { + "use strict"; + + /** + * A {@link Property} whose value does not change with respect to simulation time. + * If the value is an object, the object must provide clone and equals functions. + * + * @alias ConstantProperty + * @constructor + * + * @param {Object|Number|String|Boolean} [value] The property value. + * + * @exception {DeveloperError} value.clone is a required function. + * @exception {DeveloperError} value.equals is a required function. + */ + var ConstantProperty = function(value) { + this._value = undefined; + this._simple = true; + this._definitionChanged = new Event(); + this.setValue(value); + }; + + defineProperties(ConstantProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * This property always returns true. + * @memberof ConstantProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return true; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof ConstantProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + } + }); + + /** + * Gets the value of the property. + * @memberof ConstantProperty + * + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ConstantProperty.prototype.getValue = function(time, result) { + return this._simple ? this._value : this._value.clone(result); + }; + + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof ConstantProperty + * + * @param {Object|Number|String|Boolean} value The property value. + * + * @exception {DeveloperError} value.clone is a required function. + * @exception {DeveloperError} value.equals is a required function. + */ + ConstantProperty.prototype.setValue = function(value) { + var oldValue = this._value; + var simple = this._simple; + if ((simple && oldValue !== value) || (!simple && !oldValue.equals(value))) { + simple = typeof value !== 'object' || Array.isArray(value) || value instanceof Enumeration; + + //>>includeStart('debug', pragmas.debug); + if (!simple) { + if (typeof value.clone !== 'function') { + throw new DeveloperError('clone is a required function.'); + } + if (typeof value.equals !== 'function') { + throw new DeveloperError('equals is a required function.'); + } + } + //>>includeEnd('debug'); + + this._value = simple ? value : value.clone(); + this._simple = simple; + this._definitionChanged.raiseEvent(this); + } + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof ConstantProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + ConstantProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof ConstantProperty && // + ((this._simple && (this._value === other._value)) || // + (!this._simple && this._value.equals(other._value)))); + }; + + return ConstantProperty; +}); diff --git a/Source/DataSource/PositionProperty.js b/Source/DataSource/PositionProperty.js new file mode 100644 index 000000000000..429c4648973c --- /dev/null +++ b/Source/DataSource/PositionProperty.js @@ -0,0 +1,131 @@ +/*global define*/ +define(['../Core/Cartesian3', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Matrix3', + '../Core/ReferenceFrame', + '../Core/Transforms' + ], function( + Cartesian3, + defined, + defineProperties, + DeveloperError, + Matrix3, + ReferenceFrame, + Transforms) { + "use strict"; + + /** + * The interface for all {@link Property} objects that define a world + * location as a {@link Cartesian3} with an associated {@link ReferenceFrame}. + * This type defines an interface and cannot be instantiated directly. + * + * @alias PositionProperty + * @constructor + * + * @see CompositePositionProperty + * @see ConstantPositionProperty + * @see SampledPositionProperty + * @see TimeIntervalCollectionPositionProperty + */ + var PositionProperty = function(){ + DeveloperError.throwInstantiationError(); + }; + + defineProperties(PositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the reference frame that the position is defined in. + * @memberof PositionProperty.prototype + * @Type {ReferenceFrame} + */ + referenceFrame : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * @memberof PositionProperty + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + PositionProperty.prototype.getValue = DeveloperError.throwInstantiationError; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof PositionProperty + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + PositionProperty.prototype.getValueInReferenceFrame = DeveloperError.throwInstantiationError; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof PositionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; + + var scratchMatrix3 = new Matrix3(); + + /** + * @private + */ + PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) { + if (!defined(value)) { + return value; + } + + if (inputFrame === outputFrame) { + return Cartesian3.clone(value, result); + } + + var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3); + if (!defined(icrfToFixed)) { + icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchMatrix3); + } + if (inputFrame === ReferenceFrame.INERTIAL) { + return Matrix3.multiplyByVector(icrfToFixed, value, result); + } + if (inputFrame === ReferenceFrame.FIXED) { + return Matrix3.multiplyByVector(Matrix3.transpose(icrfToFixed, scratchMatrix3), value, result); + } + }; + + return PositionProperty; +}); diff --git a/Source/DataSource/Property.js b/Source/DataSource/Property.js new file mode 100644 index 000000000000..9a7333d0293f --- /dev/null +++ b/Source/DataSource/Property.js @@ -0,0 +1,83 @@ +/*global define*/ +define(['../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defined, + defineProperties, + DeveloperError) { + "use strict"; + + /** + * The interface for all properties, which represent a value that can optionally vary over time. + * This type defines an interface and cannot be instantiated directly. + * + * @alias Property + * @constructor + * + * @see CompositeProperty + * @see ConstantProperty + * @see SampledProperty + * @see TimeIntervalCollectionProperty + * @see MaterialProperty + * @see PositionProperty + * @see ReferenceProperty + */ + var Property = function() { + DeveloperError.throwInstantiationError(); + }; + + defineProperties(Property.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof Property.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof Property.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Gets the value of the property at the provided time. + * @memberof Property + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + Property.prototype.getValue = DeveloperError.throwInstantiationError; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof Property + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + Property.prototype.equals = DeveloperError.throwInstantiationError; + + /** + * @private + */ + Property.equals = function(left, right) { + return left === right || (defined(left) && left.equals(right)); + }; + + return Property; +}); \ No newline at end of file diff --git a/Source/DataSource/SampledPositionProperty.js b/Source/DataSource/SampledPositionProperty.js new file mode 100644 index 000000000000..5418779e66e7 --- /dev/null +++ b/Source/DataSource/SampledPositionProperty.js @@ -0,0 +1,218 @@ +/*global define*/ +define(['./PositionProperty', + './Property', + './SampledProperty', + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame' + ], function( + PositionProperty, + Property, + SampledProperty, + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame) { + "use strict"; + + /** + * A {@link SampledProperty} which is also a {@link PositionProperty}. + * + * @alias SampledPositionProperty + * @constructor + * + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + var SampledPositionProperty = function(referenceFrame) { + this._property = new SampledProperty(Cartesian3); + this._definitionChanged = new Event(); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + + this._property._definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); + }; + + defineProperties(SampledPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledPositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._property.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledPositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof SampledPositionProperty.prototype + * @Type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + }, + /** + * Gets the degree of interpolation to perform when retrieving a value. + * @memberof SampledPositionProperty.prototype + * + * @type {Object} + * @default 1 + */ + interpolationDegree : { + get : function() { + return this._property.interpolationDegree; + } + }, + /** + * Gets the interpolation algorithm to use when retrieving a value. + * @memberof SampledPositionProperty.prototype + * + * @type {InterpolationAlgorithm} + * @default LinearApproximation + */ + interpolationAlgorithm : { + get : function() { + return this._property.interpolationAlgorithm; + } + } + }); + + /** + * Gets the value of the property at the provided time. + * @memberof SampledPositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + SampledPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof SampledPositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + SampledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + //>>includeEnd('debug'); + + result = this._property.getValue(time, result); + if (defined(result)) { + return PositionProperty.convertToReferenceFrame(time, result, this._referenceFrame, referenceFrame, result); + } + return result; + }; + + /** + * Sets the algorithm and degree to use when interpolating a position. + * @memberof SampledPositionProperty + * + * @param {Object} options The options + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * + * @exception {DeveloperError} options is required. + */ + SampledPositionProperty.prototype.setInterpolationOptions = function(options) { + this._property.setInterpolationOptions(options); + }; + + /** + * Adds a new sample + * @memberof SampledPositionProperty + * + * @param {JulianDate} time The sample time. + * @param {Cartesian3} value The value at the provided time. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} value is required. + */ + SampledPositionProperty.prototype.addSample = function(time, value) { + this._property.addSample(time, value); + }; + + /** + * Adds an array of samples + * @memberof SampledPositionProperty + * + * @param {Array} times An array of JulianDate instances where each index is a sample time. + * @param {Array} values The array of Cartesian3 instances, where each value corresponds to the provided times index. + * + * @exception {DeveloperError} times is required. + * @exception {DeveloperError} values is required. + * @exception {DeveloperError} times and values must be the same length.. + */ + SampledPositionProperty.prototype.addSamples = function(times, values) { + this._property.addSamples(times, values); + }; + + /** + * Adds samples as a single packed array where each new sample is represented as a date, followed by the packed representation of the corresponding value. + * @memberof SampledPositionProperty + * + * @param {Array} packedSamples The array of packed samples. + * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. + * + * @exception {DeveloperError} packedSamples is required. + */ + SampledPositionProperty.prototype.addSamplesPackedArray = function(data, epoch) { + this._property.addSamplesPackedArray(data, epoch); + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof SampledPositionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + SampledPositionProperty.prototype.equals = function(other) { + return this === other || // + (Property.equals(this._property, other._property) && // + this._referenceFrame === other._referenceFrame); + }; + + return SampledPositionProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/SampledProperty.js b/Source/DataSource/SampledProperty.js new file mode 100644 index 000000000000..b082b133e9dd --- /dev/null +++ b/Source/DataSource/SampledProperty.js @@ -0,0 +1,528 @@ +/*global define*/ +define(['../Core/binarySearch', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/JulianDate', + '../Core/LinearApproximation' + ], function( + binarySearch, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + JulianDate, + LinearApproximation) { + "use strict"; + + var PackableNumber = { + packedLength : 1, + pack : function(value, array, startingIndex) { + startingIndex = defaultValue(startingIndex, 0); + array[startingIndex] = value; + }, + unpack : function(array, startingIndex, result) { + startingIndex = defaultValue(startingIndex, 0); + return array[startingIndex]; + } + }; + + //We can't use splice for inserting new elements because function apply can't handle + //a huge number of arguments. See https://code.google.com/p/chromium/issues/detail?id=56588 + function arrayInsert(array, startIndex, items) { + var i; + var arrayLength = array.length; + var itemsLength = items.length; + var newLength = arrayLength + itemsLength; + + array.length = newLength; + if (arrayLength !== startIndex) { + var q = arrayLength - 1; + for (i = newLength - 1; i >= startIndex; i--) { + array[i] = array[q--]; + } + } + + for (i = 0; i < itemsLength; i++) { + array[startIndex++] = items[i]; + } + } + + function convertDate(date, epoch) { + if (date instanceof JulianDate) { + return date; + } + if (typeof date === 'string') { + return JulianDate.fromIso8601(date); + } + return epoch.addSeconds(date); + } + + var timesSpliceArgs = []; + var valuesSpliceArgs = []; + + var mergeNewSamples = function(epoch, times, values, newData, packedLength) { + var newDataIndex = 0; + var i; + var prevItem; + var timesInsertionPoint; + var valuesInsertionPoint; + var currentTime; + var nextTime; + + while (newDataIndex < newData.length) { + currentTime = convertDate(newData[newDataIndex], epoch); + timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare); + var timesSpliceArgsCount = 0; + var valuesSpliceArgsCount = 0; + + if (timesInsertionPoint < 0) { + //Doesn't exist, insert as many additional values as we can. + timesInsertionPoint = ~timesInsertionPoint; + + valuesInsertionPoint = timesInsertionPoint * packedLength; + prevItem = undefined; + nextTime = times[timesInsertionPoint]; + while (newDataIndex < newData.length) { + currentTime = convertDate(newData[newDataIndex], epoch); + if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) { + break; + } + timesSpliceArgs[timesSpliceArgsCount++] = currentTime; + newDataIndex = newDataIndex + 1; + for (i = 0; i < packedLength; i++) { + valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex]; + newDataIndex = newDataIndex + 1; + } + prevItem = currentTime; + } + + if (timesSpliceArgsCount > 0) { + valuesSpliceArgs.length = valuesSpliceArgsCount; + arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs); + + timesSpliceArgs.length = timesSpliceArgsCount; + arrayInsert(times, timesInsertionPoint, timesSpliceArgs); + } + } else { + //Found an exact match + for (i = 0; i < packedLength; i++) { + newDataIndex++; + values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex]; + } + newDataIndex++; + } + } + }; + + /** + * A {@link Property} whose value is interpolated for a given time from the + * provided set of samples and specified interpolation algorithm and degree. + * @alias SampledProperty + * @constructor + * + * @param {Number|Object} type The type of property, which must be a Number or implement {@link Packable}. + * + * @exception {DeveloperError} type is required. + * + * @see SampledPositionProperty + * + * @example + * //Create a linearly interpolated Cartesian2 + * var property = new Cesium.SampledProperty(Cesium.Cartesian2); + * property.interpolationDegree = 1; + * property.interpolationAlgorithm = LinearApproximation; + * + * //Populate it with data + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:00.00Z`), new Cesium.Cartesian2(0, 0)); + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-02T00:00:00.00Z`), new Cesium.Cartesian2(4, 7)); + * + * //Retrieve an interpolated value + * var result = property.getValue(Cesium.JulianDate.fromIso8601(`2012-08-01T12:00:00.00Z`)); + * + * @example + * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation + * var property = new Cesium.SampledProperty(Number); + * property.setInterpolationOptions({ + * interpolationDegree : 3, + * interpolationAlgorithm : Cesium.HermitePolynomialApproximation + * }); + * + * //Populate it with data + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:00.00Z`), 1.0); + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:01:00.00Z`), 6.0); + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:02:00.00Z`), 12.0); + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:03:30.00Z`), 5.0); + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:06:30.00Z`), 2.0); + * + * //Samples can be added in any order. + * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:30.00Z`), 6.2); + * + * //Retrieve an interpolated value + * var result = property.getValue(Cesium.JulianDate.fromIso8601(`2012-08-01T00:02:34.00Z`)); + */ + var SampledProperty = function(type) { + //>>includeStart('debug', pragmas.debug); + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + //>>includeEnd('debug'); + + var innerType = type; + if (innerType === Number) { + innerType = PackableNumber; + } + var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, innerType.packedLength); + + this._type = type; + this._innerType = innerType; + this._interpolationDegree = 1; + this._interpolationAlgorithm = LinearApproximation; + this._numberOfPoints = 0; + this._times = []; + this._values = []; + this._xTable = []; + this._yTable = []; + this._packedInterpolationLength = packedInterpolationLength; + this._updateTableLength = true; + this._interpolationResult = new Array(packedInterpolationLength); + this._definitionChanged = new Event(); + }; + + defineProperties(SampledProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._values.length === 0; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the type of property. + * @memberof SampledProperty.prototype + * @type {Object} + */ + type : { + get : function() { + return this._type; + } + }, + /** + * Gets the degree of interpolation to perform when retrieving a value. + * @memberof SampledProperty.prototype + * @type {Number} + * @default 1 + */ + interpolationDegree : { + get : function() { + return this._interpolationDegree; + } + }, + /** + * Gets the interpolation algorithm to use when retrieving a value. + * @memberof SampledProperty.prototype + * @type {InterpolationAlgorithm} + * @default LinearApproximation + */ + interpolationAlgorithm : { + get : function() { + return this._interpolationAlgorithm; + } + } + }); + + /** + * Gets the value of the property at the provided time. + * @memberof SampledProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + SampledProperty.prototype.getValue = function(time, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + //>>includeEnd('debug'); + + var innerType = this._innerType; + var times = this._times; + var values = this._values; + var index = binarySearch(times, time, JulianDate.compare); + if (index < 0) { + var xTable = this._xTable; + var yTable = this._yTable; + var interpolationAlgorithm = this._interpolationAlgorithm; + var packedInterpolationLength = this._packedInterpolationLength; + + if (this._updateTableLength) { + this._updateTableLength = false; + var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree), times.length); + if (numberOfPoints !== this._numberOfPoints) { + this._numberOfPoints = numberOfPoints; + xTable.length = numberOfPoints; + yTable.length = numberOfPoints * packedInterpolationLength; + } + } + + var degree = this._numberOfPoints - 1; + if (degree < 1) { + return undefined; + } + index = ~index; + + if (index >= times.length) { + index = times.length - 1; + } + + var firstIndex = 0; + var lastIndex = times.length - 1; + var pointsInCollection = lastIndex - firstIndex + 1; + + if (pointsInCollection < degree + 1) { + // Use the entire range. + } else { + var computedFirstIndex = index - ((degree / 2) | 0) - 1; + if (computedFirstIndex < firstIndex) { + computedFirstIndex = firstIndex; + } + var computedLastIndex = computedFirstIndex + degree; + if (computedLastIndex > lastIndex) { + computedLastIndex = lastIndex; + computedFirstIndex = computedLastIndex - degree; + if (computedFirstIndex < firstIndex) { + computedFirstIndex = firstIndex; + } + } + + firstIndex = computedFirstIndex; + lastIndex = computedLastIndex; + } + var length = lastIndex - firstIndex + 1; + + // Build the tables + for ( var i = 0; i < length; ++i) { + xTable[i] = times[lastIndex].getSecondsDifference(times[firstIndex + i]); + } + + if (!defined(innerType.convertPackedArrayForInterpolation)) { + var destinationIndex = 0; + var packedLength = innerType.packedLength; + var sourceIndex = firstIndex * packedLength; + var stop = (lastIndex + 1) * packedLength; + + while (sourceIndex < stop) { + yTable[destinationIndex] = values[sourceIndex]; + sourceIndex++; + destinationIndex++; + } + } else { + innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable); + } + + // Interpolate! + var x = times[lastIndex].getSecondsDifference(time); + var interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult); + + if (!defined(innerType.unpackInterpolationResult)) { + return innerType.unpack(interpolationResult, 0, result); + } + return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result); + } + return innerType.unpack(this._values, index * innerType.packedLength, result); + }; + + /** + * Sets the algorithm and degree to use when interpolating a value. + * @memberof SampledProperty + * + * @param {Object} options The options + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * + * @exception {DeveloperError} options is required. + */ + SampledProperty.prototype.setInterpolationOptions = function(options) { + //>>includeStart('debug', pragmas.debug); + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + //>>includeEnd('debug'); + + var valuesChanged = false; + + var interpolationAlgorithm = options.interpolationAlgorithm; + var interpolationDegree = options.interpolationDegree; + + if (this._interpolationAlgorithm !== interpolationAlgorithm) { + this._interpolationAlgorithm = interpolationAlgorithm; + valuesChanged = true; + } + + if (this._interpolationDegree !== interpolationDegree) { + this._interpolationDegree = interpolationDegree; + valuesChanged = true; + } + + if (valuesChanged) { + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + } + }; + + /** + * Adds a new sample + * @memberof SampledProperty + * + * @param {JulianDate} time The sample time. + * @param {Object} value The value at the provided time. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} value is required. + */ + SampledProperty.prototype.addSample = function(time, value) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + //>>includeEnd('debug'); + + var innerType = this._innerType; + var data = [time]; + innerType.pack(value, data, 1); + mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + }; + + /** + * Adds an array of samples + * @memberof SampledProperty + * + * @param {Array} times An array of JulianDate instances where each index is a sample time. + * @param {Array} values The array of values, where each value corresponds to the provided times index. + * + * @exception {DeveloperError} times is required. + * @exception {DeveloperError} values is required. + * @exception {DeveloperError} times and values must be the same length.. + */ + SampledProperty.prototype.addSamples = function(times, values) { + //>>includeStart('debug', pragmas.debug); + if (!defined(times)) { + throw new DeveloperError('times is required.'); + } + if (!defined(values)) { + throw new DeveloperError('values is required.'); + } + if (times.length !== values.length) { + throw new DeveloperError('times and values must be the same length.'); + } + //>>includeEnd('debug'); + + var innerType = this._innerType; + var length = times.length; + var data = []; + for ( var i = 0; i < length; i++) { + data.push(times[i]); + innerType.pack(values[i], data, data.length); + } + mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + }; + + /** + * Adds samples as a single packed array where each new sample is represented as a date, followed by the packed representation of the corresponding value. + * @memberof SampledProperty + * + * @param {Array} packedSamples The array of packed samples. + * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. + * + * @exception {DeveloperError} packedSamples is required. + */ + SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { + //>>includeStart('debug', pragmas.debug); + if (!defined(packedSamples)) { + throw new DeveloperError('packedSamples is required.'); + } + //>>includeEnd('debug'); + + mergeNewSamples(epoch, this._times, this._values, packedSamples, this._innerType.packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof SampledProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + SampledProperty.prototype.equals = function(other) { + if (this === other) { + return true; + } + if (!defined(other)) { + return false; + } + + var times = this._times; + var otherTimes = other._times; + var length = times.length; + + if (length !== otherTimes.length) { + return false; + } + + var i; + for (i = 0; i < length; i++) { + if (!JulianDate.equals(times[i], otherTimes[i])) { + return false; + } + } + + var values = this._values; + var otherValues = other._values; + for (i = 0; i < length; i++) { + if (values[i] !== otherValues[i]) { + return false; + } + } + + return this._type === other._type && // + this._interpolationDegree === other._interpolationDegree && // + this._interpolationAlgorithm === other._interpolationAlgorithm; + }; + + //Exposed for testing. + SampledProperty._mergeNewSamples = mergeNewSamples; + + return SampledProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/TimeIntervalCollectionPositionProperty.js b/Source/DataSource/TimeIntervalCollectionPositionProperty.js new file mode 100644 index 000000000000..6fcfb7fd5832 --- /dev/null +++ b/Source/DataSource/TimeIntervalCollectionPositionProperty.js @@ -0,0 +1,158 @@ +/*global define*/ +define(['./PositionProperty', + './Property', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame', + '../Core/TimeIntervalCollection', + '../Core/wrapFunction' + ], function( + PositionProperty, + Property, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame, + TimeIntervalCollection, + wrapFunction) { + "use strict"; + + /** + * A {@link TimeIntervalCollectionProperty} which is also a {@link PositionProperty}. + * + * @alias TimeIntervalCollectionPositionProperty + * @constructor + * + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + var TimeIntervalCollectionPositionProperty = function(referenceFrame) { + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var raiseDefinitionChanged = function() { + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, intervals.addInterval, raiseDefinitionChanged); + intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, raiseDefinitionChanged); + intervals.clear = wrapFunction(intervals, intervals.clear, raiseDefinitionChanged); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + }; + + defineProperties(TimeIntervalCollectionPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @Type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * @memberof CompositePositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + TimeIntervalCollectionPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof CompositePositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + TimeIntervalCollectionPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + //>>includeEnd('debug'); + + var position = this._intervals.findDataForIntervalContainingDate(time); + if (defined(position)) { + return PositionProperty.convertToReferenceFrame(time, position, this._referenceFrame, referenceFrame, result); + } + return undefined; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof TimeIntervalCollectionPositionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + TimeIntervalCollectionPositionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof TimeIntervalCollectionPositionProperty && // + this._intervals.equals(other._intervals, Property.equals) && // + this._referenceFrame === other._referenceFrame); + }; + + return TimeIntervalCollectionPositionProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/TimeIntervalCollectionProperty.js b/Source/DataSource/TimeIntervalCollectionProperty.js new file mode 100644 index 000000000000..d77a27ecd6d3 --- /dev/null +++ b/Source/DataSource/TimeIntervalCollectionProperty.js @@ -0,0 +1,152 @@ +/*global define*/ +define(['./Property', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Enumeration', + '../Core/Event', + '../Core/TimeIntervalCollection', + '../Core/wrapFunction' + ], function( + Property, + defined, + defineProperties, + DeveloperError, + Enumeration, + Event, + TimeIntervalCollection, + wrapFunction) { + "use strict"; + + /** + * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the + * data property of each {@link TimeInterval} represents the value at time. + * + * @alias TimeIntervalCollectionProperty + * @constructor + * + * @example + * //Create a Cartesian2 interval property which contains data on August 1st, 2012 + * //and uses a different value every 6 hours. + * var composite = new Cesium.TimeIntervalCollectionProperty(); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', true, false, new Cesium.Cartesian2(2.0, 3.4))); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, new Cesium.Cartesian2(12.0, 2.7))); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-01T18:00:00.00Z', true, false, new Cesium.Cartesian2(5.0, 12.4))); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T18:00:00.00Z/2012-08-02T00:00:00.00Z', true, true, new Cesium.Cartesian2(85.0, 4.1))); + * + * @example + * //Create a TimeIntervalCollectionProperty that contains user-defined objects. + * function cloneMyObject(value, result) { + * return { + * value : value.value + * }; + * } + * + * var myObject = { + * value : 6, + * clone : cloneMyObject + * }; + * var myObject2 = { + * value : 12, + * clone : cloneMyObject + * }; + * + * var composite = new Cesium.TimeIntervalCollectionProperty(); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', true, false, myObject)); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, myObject2)); + */ + var TimeIntervalCollectionProperty = function() { + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var raiseDefinitionChanged = function() { + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, intervals.addInterval, raiseDefinitionChanged); + intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, raiseDefinitionChanged); + intervals.clear = wrapFunction(intervals, intervals.clear, raiseDefinitionChanged); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; + }; + + defineProperties(TimeIntervalCollectionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof TimeIntervalCollectionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof TimeIntervalCollectionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof TimeIntervalCollectionProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; + } + } + }); + + /** + * Gets the value of the property at the provided time. + * @memberof TimeIntervalCollectionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} This value requires a clone function be specified for the TimeIntervalCollectionProperty constructor. + */ + TimeIntervalCollectionProperty.prototype.getValue = function(time, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required'); + } + //>>includeEnd('debug'); + + var value = this._intervals.findDataForIntervalContainingDate(time); + if (defined(value) && (typeof value === 'object' && !Array.isArray(value) && !(value instanceof Enumeration))) { + return value.clone(result); + } + return value; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof TimeIntervalCollectionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + TimeIntervalCollectionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof TimeIntervalCollectionProperty && // + this._intervals.equals(other._intervals, Property.equals)); + }; + + return TimeIntervalCollectionProperty; +}); \ No newline at end of file diff --git a/Specs/DataSource/CompositePropertySpec.js b/Specs/DataSource/CompositePropertySpec.js new file mode 100644 index 000000000000..0cc4e03a589d --- /dev/null +++ b/Specs/DataSource/CompositePropertySpec.js @@ -0,0 +1,110 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/CompositeProperty', + 'DataSource/ConstantProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection' + ], function( + CompositeProperty, + ConstantProperty, + Cartesian3, + JulianDate, + TimeInterval, + TimeIntervalCollection) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('default constructor has expected values', function() { + var property = new CompositeProperty(); + expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.getValue(new JulianDate())).toBeUndefined(); + }); + + it('works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(result1).not.toBe(interval1.data.getValue(interval1.start)); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop); + expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = new Cartesian3(); + var result1 = property.getValue(interval1.start, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('equals works', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var left = new CompositeProperty(); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new CompositeProperty(); + right.intervals.addInterval(interval1); + expect(left.equals(right)).toEqual(false); + + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('getValue throws with no time parameter', function() { + var property = new CompositeProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/ConstantPositionPropertySpec.js b/Specs/DataSource/ConstantPositionPropertySpec.js new file mode 100644 index 000000000000..5014ab5e22f3 --- /dev/null +++ b/Specs/DataSource/ConstantPositionPropertySpec.js @@ -0,0 +1,131 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/ConstantPositionProperty', + 'DataSource/PositionProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/ReferenceFrame' + ], function( + ConstantPositionProperty, + PositionProperty, + Cartesian3, + JulianDate, + ReferenceFrame) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + it('Constructor sets expected defaults', function() { + var property = new ConstantPositionProperty(); + expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); + + property = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); + expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); + }); + + it('getValue works without a result parameter', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantPositionProperty(value); + + var result = property.getValue(time); + expect(result).not.toBe(value); + expect(result).toEqual(value); + }); + + it('getValue works with a result parameter', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantPositionProperty(value); + + var expected = new Cartesian3(); + var result = property.getValue(time, expected); + expect(result).toBe(expected); + expect(expected).toEqual(value); + }); + + it('getValue returns in fixed frame', function() { + var valueInertial = new Cartesian3(1, 2, 3); + var valueFixed = PositionProperty.convertToReferenceFrame(time, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); + var property = new ConstantPositionProperty(valueInertial, ReferenceFrame.INERTIAL); + + var result = property.getValue(time); + expect(result).toEqual(valueFixed); + }); + + it('getValue works with undefined fixed value', function() { + var property = new ConstantPositionProperty(undefined); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('getValue work swith undefined inertial value', function() { + var property = new ConstantPositionProperty(undefined, ReferenceFrame.INERTIAL); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('getValueInReferenceFrame works without a result parameter', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantPositionProperty(value); + + var result = property.getValueInReferenceFrame(time, ReferenceFrame.INERTIAL); + expect(result).not.toBe(value); + expect(result).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL)); + }); + + it('getValueInReferenceFrame works with a result parameter', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantPositionProperty(value, ReferenceFrame.INERTIAL); + + var expected = new Cartesian3(); + var result = property.getValueInReferenceFrame(time, ReferenceFrame.FIXED, expected); + expect(result).toBe(expected); + expect(expected).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED)); + }); + + it('setValue rasies definitionChanged event', function() { + var property = new ConstantPositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(1, 2, 3)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('setValue does not raise definitionChanged event with equal data', function() { + var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0)); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0)); + expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + }); + + it('setValue raises definitionChanged when referenceFrame changes', function() { + var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0), ReferenceFrame.FIXED); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0), ReferenceFrame.INERTIAL); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('equals works', function() { + var left = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); + var right = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); + + expect(left.equals(right)).toEqual(true); + + right = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.FIXED); + expect(left.equals(right)).toEqual(false); + + right = new ConstantPositionProperty(new Cartesian3(1, 2, 4), ReferenceFrame.INERTIAL); + expect(left.equals(right)).toEqual(false); + }); + + it('getValue throws without time parameter', function() { + var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('getValueInReferenceFrame throws with no referenceFrame parameter', function() { + var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); + expect(function() { + property.getValueInReferenceFrame(time, undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/ConstantPropertySpec.js b/Specs/DataSource/ConstantPropertySpec.js new file mode 100644 index 000000000000..ec8ea4c8d605 --- /dev/null +++ b/Specs/DataSource/ConstantPropertySpec.js @@ -0,0 +1,97 @@ +/*global defineSuite*/ +defineSuite(['DataSource/ConstantProperty', + 'Core/Cartesian3', + 'Core/JulianDate' + ], function( + ConstantProperty, + Cartesian3, + JulianDate) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + it('works with basic types', function() { + var expected = 5; + var property = new ConstantProperty(expected); + expect(property.getValue(time)).toBe(expected); + }); + + it('works with objects', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantProperty(value); + + var result = property.getValue(time); + expect(result).not.toBe(value); + expect(result).toEqual(value); + }); + + it('setValue rasies definitionChanged event', function() { + var property = new ConstantProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('setValue does not raise definitionChanged event with equal data', function() { + var property = new ConstantProperty(new Cartesian3(0, 0, 0)); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0)); + expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + }); + + it('works with objects with result parameter', function() { + var value = new Cartesian3(1, 2, 3); + var property = new ConstantProperty(value); + + var expected = new Cartesian3(); + var result = property.getValue(time, expected); + expect(result).toBe(expected); + expect(expected).toEqual(value); + }); + + it('works with undefined value', function() { + var property = new ConstantProperty(undefined); + expect(property.getValue()).toBeUndefined(); + }); + + it('constructor throws with undefined clone function on non-basic type', function() { + expect(function() { + return new ConstantProperty({ + equals : function() { + return true; + } + }); + }).toThrowDeveloperError(); + }); + + it('constructor throws with undefined equals function on non-basic type', function() { + expect(function() { + return new ConstantProperty({ + clone : function() { + return {}; + } + }); + }).toThrowDeveloperError(); + }); + + it('equals works for object types', function() { + var left = new ConstantProperty(new Cartesian3(1, 2, 3)); + var right = new ConstantProperty(new Cartesian3(1, 2, 3)); + + expect(left.equals(right)).toEqual(true); + + right = new ConstantProperty(new Cartesian3(1, 2, 4)); + expect(left.equals(right)).toEqual(false); + }); + + it('equals works for simple types', function() { + var left = new ConstantProperty(1); + var right = new ConstantProperty(1); + + expect(left.equals(right)).toEqual(true); + + right = new ConstantProperty(2); + expect(left.equals(right)).toEqual(false); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/SampledPositionPropertySpec.js b/Specs/DataSource/SampledPositionPropertySpec.js new file mode 100644 index 000000000000..dfe90281af67 --- /dev/null +++ b/Specs/DataSource/SampledPositionPropertySpec.js @@ -0,0 +1,264 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/SampledPositionProperty', + 'DataSource/PositionProperty', + 'Core/Cartesian3', + 'Core/defined', + 'Core/JulianDate', + 'Core/LinearApproximation', + 'Core/LagrangePolynomialApproximation', + 'Core/ReferenceFrame' + ], function( + SampledPositionProperty, + PositionProperty, + Cartesian3, + defined, + JulianDate, + LinearApproximation, + LagrangePolynomialApproximation, + ReferenceFrame) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor sets expected defaults', function() { + var property = new SampledPositionProperty(); + expect(property.referenceFrame).toEqual(ReferenceFrame.FIXED); + expect(property.interpolationDegree).toEqual(1); + expect(property.interpolationAlgorithm).toEqual(LinearApproximation); + }); + + it('constructor sets expected values', function() { + var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); + expect(property.referenceFrame).toEqual(ReferenceFrame.INERTIAL); + expect(property.interpolationDegree).toEqual(1); + expect(property.interpolationAlgorithm).toEqual(LinearApproximation); + }); + + it('getValue works without a result parameter', function() { + var time = new JulianDate(); + var value = new Cartesian3(1, 2, 3); + var property = new SampledPositionProperty(); + property.addSample(time, value); + + var result = property.getValue(time); + expect(result).not.toBe(value); + expect(result).toEqual(value); + }); + + it('getValue works with a result parameter', function() { + var time = new JulianDate(); + var value = new Cartesian3(1, 2, 3); + var property = new SampledPositionProperty(); + property.addSample(time, value); + + var expected = new Cartesian3(); + var result = property.getValue(time, expected); + expect(result).toBe(expected); + expect(expected).toEqual(value); + }); + + it('getValue returns in fixed frame', function() { + var time = new JulianDate(); + var valueInertial = new Cartesian3(1, 2, 3); + var valueFixed = PositionProperty.convertToReferenceFrame(time, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); + var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); + property.addSample(time, valueInertial); + + var result = property.getValue(time); + expect(result).toEqual(valueFixed); + }); + + it('getValueInReferenceFrame works without a result parameter', function() { + var time = new JulianDate(); + var value = new Cartesian3(1, 2, 3); + var property = new SampledPositionProperty(); + property.addSample(time, value); + + var result = property.getValueInReferenceFrame(time, ReferenceFrame.INERTIAL); + expect(result).not.toBe(value); + expect(result).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL)); + }); + + it('getValueInReferenceFrame works with a result parameter', function() { + var time = new JulianDate(); + var value = new Cartesian3(1, 2, 3); + var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); + property.addSample(time, value); + + var expected = new Cartesian3(); + var result = property.getValueInReferenceFrame(time, ReferenceFrame.FIXED, expected); + expect(result).toBe(expected); + expect(expected).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED)); + }); + + it('addSamplesPackedArray works', function() { + var data = [0, 7, 8, 9, 1, 8, 9, 10, 2, 9, 10, 11]; + var epoch = new JulianDate(0, 0); + + var property = new SampledPositionProperty(); + property.addSamplesPackedArray(data, epoch); + expect(property.getValue(epoch)).toEqual(new Cartesian3(7, 8, 9)); + expect(property.getValue(new JulianDate(0, 0.5))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); + }); + + it('addSample works', function() { + var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)]; + var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; + + var property = new SampledPositionProperty(); + property.addSample(times[0], values[0]); + property.addSample(times[1], values[1]); + property.addSample(times[2], values[2]); + + expect(property.getValue(times[0])).toEqual(values[0]); + expect(property.getValue(times[1])).toEqual(values[1]); + expect(property.getValue(times[2])).toEqual(values[2]); + expect(property.getValue(new JulianDate(0.5, 0))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); + }); + + it('addSamples works', function() { + var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)]; + var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; + + var property = new SampledPositionProperty(); + property.addSamples(times, values); + expect(property.getValue(times[0])).toEqual(values[0]); + expect(property.getValue(times[1])).toEqual(values[1]); + expect(property.getValue(times[2])).toEqual(values[2]); + expect(property.getValue(new JulianDate(0.5, 0))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); + }); + + it('can set interpolationAlgorithm and degree', function() { + var data = [0, 7, 8, 9, 1, 8, 9, 10, 2, 9, 10, 11]; + var epoch = new JulianDate(0, 0); + + var timesCalled = 0; + var MockInterpolation = { + type : 'Mock', + getRequiredDataPoints : function(degree) { + return 3; + }, + + interpolateOrderZero : function(x, xTable, yTable, yStride, result) { + expect(x).toEqual(1); + + expect(xTable.length).toEqual(3); + expect(xTable[0]).toBe(-2); + expect(xTable[1]).toBe(-1); + expect(xTable[2]).toBe(0); + + expect(yTable.length).toEqual(9); + expect(yTable[0]).toBe(7); + expect(yTable[1]).toBe(8); + expect(yTable[2]).toBe(9); + expect(yTable[3]).toBe(8); + expect(yTable[4]).toBe(9); + expect(yTable[5]).toBe(10); + expect(yTable[6]).toBe(9); + expect(yTable[7]).toBe(10); + expect(yTable[8]).toBe(11); + + expect(yStride).toEqual(3); + + expect(result.length).toEqual(3); + + result[0] = 2; + result[1] = 3; + result[2] = 4; + timesCalled++; + return result; + } + }; + + var property = new SampledPositionProperty(); + property.addSamplesPackedArray(data, epoch); + property.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : MockInterpolation + }); + expect(property.getValue(epoch)).toEqual(new Cartesian3(7, 8, 9)); + expect(property.getValue(new JulianDate(0, 3))).toEqual(new Cartesian3(2, 3, 4)); + + expect(timesCalled).toEqual(1); + }); + + it('Returns undefined if trying to interpolate with less than enough samples.', function() { + var value = new Cartesian3(1, 2, 3); + var time = new JulianDate(0, 0); + + var property = new SampledPositionProperty(); + property.addSample(time, value); + + expect(property.getValue(time)).toEqual(value); + expect(property.getValue(time.addSeconds(4))).toBeUndefined(); + }); + + it('throws with no time parameter', function() { + var property = new SampledPositionProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('throws with no reference frame parameter', function() { + var property = new SampledPositionProperty(); + var time = new JulianDate(); + expect(function() { + property.getValueInReferenceFrame(time, undefined); + }).toThrowDeveloperError(); + }); + + it('equals works when interpolators differ', function() { + var left = new SampledPositionProperty(); + var right = new SampledPositionProperty(); + + expect(left.equals(right)).toEqual(true); + right.setInterpolationOptions({ + interpolationAlgorithm : LagrangePolynomialApproximation + }); + expect(left.equals(right)).toEqual(false); + }); + + it('equals works when interpolator degree differ', function() { + var left = new SampledPositionProperty(); + + left.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + var right = new SampledPositionProperty(); + right.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + expect(left.equals(right)).toEqual(true); + right.setInterpolationOptions({ + interpolationDegree : 3, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + expect(left.equals(right)).toEqual(false); + }); + + it('equals works when reference frames differ', function() { + var left = new SampledPositionProperty(ReferenceFrame.FIXED); + var right = new SampledPositionProperty(ReferenceFrame.INERTIAL); + expect(left.equals(right)).toEqual(false); + }); + + it('equals works when samples differ', function() { + var left = new SampledPositionProperty(); + var right = new SampledPositionProperty(); + expect(left.equals(right)).toEqual(true); + + var time = new JulianDate(); + var value = new Cartesian3(1, 2, 3); + left.addSample(time, value); + expect(left.equals(right)).toEqual(false); + + right.addSample(time, value); + expect(left.equals(right)).toEqual(true); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/SampledPropertySpec.js b/Specs/DataSource/SampledPropertySpec.js new file mode 100644 index 000000000000..f6d98048e3d5 --- /dev/null +++ b/Specs/DataSource/SampledPropertySpec.js @@ -0,0 +1,372 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/SampledProperty', + 'Core/defined', + 'Core/JulianDate', + 'Core/LinearApproximation', + 'Core/LagrangePolynomialApproximation' + ], function( + SampledProperty, + defined, + JulianDate, + LinearApproximation, + LagrangePolynomialApproximation) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor sets expected defaults', function() { + var property = new SampledProperty(Number); + expect(property.interpolationDegree).toEqual(1); + expect(property.interpolationAlgorithm).toEqual(LinearApproximation); + expect(property.isConstant).toEqual(true); + }); + + it('isConstant works', function() { + var property = new SampledProperty(Number); + expect(property.isConstant).toEqual(true); + property.addSample(new JulianDate(0, 0), 1); + expect(property.isConstant).toEqual(false); + }); + + it('addSamplesPackedArray works', function() { + var data = [0, 7, 1, 8, 2, 9]; + var epoch = new JulianDate(0, 0); + + var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.addSamplesPackedArray(data, epoch); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(property.getValue(epoch)).toEqual(7); + expect(property.getValue(new JulianDate(0, 0.5))).toEqual(7.5); + }); + + it('addSample works', function() { + var values = [7, 8, 9]; + var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; + + var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.addSample(times[0], values[0]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.addSample(times[1], values[1]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.addSample(times[2], values[2]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + expect(property.getValue(times[0])).toEqual(values[0]); + expect(property.getValue(times[1])).toEqual(values[1]); + expect(property.getValue(times[2])).toEqual(values[2]); + expect(property.getValue(new JulianDate(0.5, 0))).toEqual(7.5); + }); + + it('addSamples works', function() { + var values = [7, 8, 9]; + var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; + + var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + property.addSamples(times, values); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(property.getValue(times[0])).toEqual(values[0]); + expect(property.getValue(times[1])).toEqual(values[1]); + expect(property.getValue(times[2])).toEqual(values[2]); + expect(property.getValue(new JulianDate(0.5, 0))).toEqual(7.5); + }); + + it('works with PackableForInterpolation', function() { + var CustomType = function(value) { + this.x = value; + }; + + CustomType.packedLength = 1; + + CustomType.packedInterpolationLength = 2; + + CustomType.pack = function(value, array, startingIndex) { + array[startingIndex] = value.x; + }; + + CustomType.unpack = function(array, startingIndex, result) { + return array[startingIndex]; + }; + + CustomType.convertPackedArrayForInterpolation = function(packedArray, startingIndex, lastIndex, result) { + for ( var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { + var offset = i * 2; + result[offset] = packedArray[i] * 0.5; + result[offset + 1] = packedArray[i] * 0.5; + } + }; + + CustomType.unpackInterpolationResult = function(array, sourceArray, firstIndex, lastIndex, result) { + if (!defined(result)) { + result = new CustomType(); + } + result.x = array[0] + array[1]; + return result; + }; + + var values = [new CustomType(0), new CustomType(2), new CustomType(4)]; + var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; + + var property = new SampledProperty(CustomType); + property.addSample(times[0], values[0]); + property.addSample(times[1], values[1]); + property.addSample(times[2], values[2]); + + expect(property.getValue(new JulianDate(0.5, 0)).x).toEqual(1); + }); + + it('can set interpolationAlgorithm and degree', function() { + var data = [0, 7, 2, 9, 4, 11]; + var epoch = new JulianDate(0, 0); + + var timesCalled = 0; + var MockInterpolation = { + type : 'Mock', + getRequiredDataPoints : function(degree) { + return 3; + }, + + interpolateOrderZero : function(x, xTable, yTable, yStride, result) { + expect(x).toEqual(-1); + + expect(xTable.length).toEqual(3); + expect(xTable[0]).toBe(-4); + expect(xTable[1]).toBe(-2); + expect(xTable[2]).toBe(0); + + expect(yTable.length).toEqual(3); + expect(yTable[0]).toBe(7); + expect(yTable[1]).toBe(9); + expect(yTable[2]).toBe(11); + + expect(yStride).toEqual(1); + + expect(result.length).toEqual(1); + + result[0] = 2; + timesCalled++; + return result; + } + }; + + var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.addSamplesPackedArray(data, epoch); + + expect(property.getValue(epoch)).toEqual(7); + expect(property.getValue(new JulianDate(0, 1))).toEqual(8); + + property.setInterpolationOptions({ + interpolationAlgorithm : MockInterpolation, + interpolationDegree : 2 + }); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(property.getValue(epoch)).toEqual(7); + expect(property.getValue(new JulianDate(0, 3))).toEqual(2); + + expect(timesCalled).toEqual(1); + }); + + it('Returns undefined if trying to interpolate with less than enough samples.', function() { + var value = 7; + var time = new JulianDate(0, 0); + + var property = new SampledProperty(Number); + property.addSample(time, value); + + expect(property.getValue(time)).toEqual(value); + expect(property.getValue(time.addSeconds(4))).toBeUndefined(); + }); + + it('mergeNewSamples works with huge data sets.', function() { + var times = []; + var values = []; + var epoch = new JulianDate(); + + var data = []; + var expectedTimes = []; + var expectedValues = []; + + for ( var i = 0; i < 200000; i++) { + data.push(i); + data.push(i); + expectedTimes.push(epoch.addSeconds(i)); + expectedValues.push(i); + } + + SampledProperty._mergeNewSamples(epoch, times, values, data, 1); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + it('mergeNewSamples works for sorted non-intersecting data.', function() { + var times = []; + var values = []; + var epoch = new JulianDate(); + + var newData = [0, 'a', 1, 'b', 2, 'c']; + var newData2 = [3, 'd', 4, 'e', 5, 'f']; + + var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; + var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; + + SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); + SampledProperty._mergeNewSamples(epoch, times, values, newData2, 1); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + it('mergeNewSamples works for ISO8601 dates', function() { + var times = []; + var values = []; + var epoch = JulianDate.fromIso8601('2010-01-01T12:00:00'); + + var newData = ['2010-01-01T12:00:00', 'a', '2010-01-01T12:00:01', 'b', '2010-01-01T12:00:02', 'c']; + var newData2 = ['2010-01-01T12:00:03', 'd', '2010-01-01T12:00:04', 'e', '2010-01-01T12:00:05', 'f']; + + var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; + var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; + + SampledProperty._mergeNewSamples(undefined, times, values, newData, 1); + SampledProperty._mergeNewSamples(undefined, times, values, newData2, 1); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + it('mergeNewSamples works for elements of size 2.', function() { + var times = []; + var values = []; + var epoch = new JulianDate(); + + var newData = [1, 'b', 'b', 4, 'e', 'e', 0, 'a', 'a']; + var newData2 = [2, 'c', 'c', 3, 'd', 'd']; + + var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4)]; + var expectedValues = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'e', 'e']; + + SampledProperty._mergeNewSamples(epoch, times, values, newData, 2); + SampledProperty._mergeNewSamples(epoch, times, values, newData2, 2); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + it('mergeNewSamples works for unsorted intersecting data.', function() { + var times = []; + var values = []; + var epoch = new JulianDate(); + + var newData = [1, 'b', 4, 'e', 0, 'a']; + var newData2 = [5, 'f', 2, 'c', 3, 'd']; + + var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; + var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; + + SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); + SampledProperty._mergeNewSamples(epoch, times, values, newData2, 1); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + it('mergeNewSamples works for data with repeated values.', function() { + var times = []; + var values = []; + var epoch = new JulianDate(); + + var newData = [0, 'a', 1, 'b', 1, 'c', 0, 'd', 4, 'e', 5, 'f']; + var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(4), epoch.addSeconds(5)]; + var expectedValues = ['d', 'c', 'e', 'f']; + SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); + + expect(times).toEqual(expectedTimes, JulianDate.compare); + expect(values).toEqual(expectedValues); + }); + + var interwovenData = [{ + epoch : JulianDate.fromIso8601("20130205T150405.704999999999927Z"), + values : [0.0, 1, 120.0, 2, 240.0, 3, 360.0, 4, 480.0, 6, 600.0, 8, 720.0, 10, 840.0, 12, 960.0, 14, 1080.0, 16] + }, { + epoch : JulianDate.fromIso8601("20130205T151151.60499999999956Z"), + values : [0.0, 5, 120.0, 7, 240.0, 9, 360.0, 11, 480.0, 13, 600.0, 15, 720.0, 17, 840.0, 18, 960.0, 19, 1080.0, 20] + }]; + + it('mergeNewSamples works with interwoven data', function() { + var times = []; + var values = []; + SampledProperty._mergeNewSamples(interwovenData[0].epoch, times, values, interwovenData[0].values, 1); + SampledProperty._mergeNewSamples(interwovenData[1].epoch, times, values, interwovenData[1].values, 1); + for ( var i = 0; i < values.length; i++) { + expect(values[i]).toBe(i + 1); + } + }); + + it('constructor throws without type parameter.', function() { + expect(function() { + return new SampledProperty(undefined); + }).toThrowDeveloperError(); + }); + + it('equals works when interpolators differ', function() { + var left = new SampledProperty(Number); + var right = new SampledProperty(Number); + + expect(left.equals(right)).toEqual(true); + right.setInterpolationOptions({ + interpolationAlgorithm : LagrangePolynomialApproximation + }); + expect(left.equals(right)).toEqual(false); + }); + + it('equals works when interpolator degree differ', function() { + var left = new SampledProperty(Number); + + left.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + var right = new SampledProperty(Number); + right.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + expect(left.equals(right)).toEqual(true); + right.setInterpolationOptions({ + interpolationDegree : 3, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + + expect(left.equals(right)).toEqual(false); + }); + + it('equals works when samples differ', function() { + var left = new SampledProperty(Number); + var right = new SampledProperty(Number); + expect(left.equals(right)).toEqual(true); + + var time = new JulianDate(); + left.addSample(time, 5); + expect(left.equals(right)).toEqual(false); + + right.addSample(time, 5); + expect(left.equals(right)).toEqual(true); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js new file mode 100644 index 000000000000..e0427f665e73 --- /dev/null +++ b/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js @@ -0,0 +1,181 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/TimeIntervalCollectionPositionProperty', + 'DataSource/PositionProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/ReferenceFrame', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection' + ], function( + TimeIntervalCollectionPositionProperty, + PositionProperty, + Cartesian3, + JulianDate, + ReferenceFrame, + TimeInterval, + TimeIntervalCollection) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('default constructor has expected values', function() { + var property = new TimeIntervalCollectionPositionProperty(); + expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.getValue(new JulianDate())).toBeUndefined(); + expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); + }); + + it('getValue works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionPositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(result1).not.toBe(interval1.data); + expect(result1).toEqual(interval1.data); + + var result2 = property.getValue(interval2.stop); + expect(result2).not.toBe(interval2.data); + expect(result2).toEqual(interval2.data); + }); + + it('getValue works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionPositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = new Cartesian3(); + var result1 = property.getValue(interval1.start, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data); + + var result2 = property.getValue(interval2.stop, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data); + }); + + it('getValue returns in fixed frame', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + + var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.INERTIAL); + property.intervals.addInterval(interval1); + + var valueInertial = new Cartesian3(1, 2, 3); + var valueFixed = PositionProperty.convertToReferenceFrame(interval1.start, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); + + var result = property.getValue(interval1.start); + expect(result).toEqual(valueFixed); + }); + + it('getValueInReferenceFrame works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var valueInertial = PositionProperty.convertToReferenceFrame(interval1.start, interval1.data, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL); + + var expected = new Cartesian3(); + var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(valueInertial); + + var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data); + }); + + it('getValueInReferenceFrame works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var valueInertial = PositionProperty.convertToReferenceFrame(interval1.start, interval1.data, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL); + + var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL); + expect(result1).toEqual(valueInertial); + + var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED); + expect(result2).toEqual(interval2.data); + }); + + it('returns undefined for valid interval without data', function() { + var property = new TimeIntervalCollectionPositionProperty(); + + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, undefined); + property.intervals.addInterval(interval); + + var result = property.getValue(interval.start); + expect(result).toBeUndefined(); + }); + + it('throws with no time parameter', function() { + var property = new TimeIntervalCollectionPositionProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('throws with no reference frame parameter', function() { + var property = new TimeIntervalCollectionPositionProperty(); + var time = new JulianDate(); + expect(function() { + property.getValueInReferenceFrame(time, undefined); + }).toThrowDeveloperError(); + }); + + it('equals works for differing referenceFrames', function() { + var left = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + var right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.INERTIAL); + expect(left.equals(right)).toEqual(false); + + right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + expect(left.equals(right)).toEqual(true); + }); + + it('equals works for differing intervals', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var left = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); + right.intervals.addInterval(interval1); + + expect(left.equals(right)).toEqual(false); + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged event', function() { + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + + var property = new TimeIntervalCollectionPositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + + property.intervals.addInterval(interval); + property.definitionChanged.raiseEvent.reset(); + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/TimeIntervalCollectionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPropertySpec.js new file mode 100644 index 000000000000..c10003c07998 --- /dev/null +++ b/Specs/DataSource/TimeIntervalCollectionPropertySpec.js @@ -0,0 +1,129 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/TimeIntervalCollectionProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection' + ], function( + TimeIntervalCollectionProperty, + Cartesian3, + JulianDate, + TimeInterval, + TimeIntervalCollection) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('default constructor has expected values', function() { + var property = new TimeIntervalCollectionProperty(); + expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.getValue(new JulianDate())).toBeUndefined(); + expect(property.isConstant).toBe(true); + }); + + it('works with basic types', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, 5); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, 6); + + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + expect(property.getValue(interval1.start)).toBe(interval1.data); + expect(property.getValue(interval2.stop)).toBe(interval2.data); + expect(property.isConstant).toBe(false); + }); + + it('works with clonable objects', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(result1).not.toBe(interval1.data); + expect(result1).toEqual(interval1.data); + + var result2 = property.getValue(interval2.stop); + expect(result2).not.toBe(interval2.data); + expect(result2).toEqual(interval2.data); + }); + + it('works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = new Cartesian3(); + var result1 = property.getValue(interval1.start, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data); + + var result2 = property.getValue(interval2.stop, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data); + }); + + it('throws with no time parameter', function() { + var property = new TimeIntervalCollectionProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('equals works for differing basic type intervals', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, 5); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, 6); + + var left = new TimeIntervalCollectionProperty(); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new TimeIntervalCollectionProperty(); + right.intervals.addInterval(interval1); + + expect(left.equals(right)).toEqual(false); + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + }); + + it('equals works for differing complex type intervals', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); + + var left = new TimeIntervalCollectionProperty(); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new TimeIntervalCollectionProperty(); + right.intervals.addInterval(interval1); + + expect(left.equals(right)).toEqual(false); + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged event', function() { + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + + var property = new TimeIntervalCollectionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + + property.intervals.addInterval(interval); + property.definitionChanged.raiseEvent.reset(); + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); +}); \ No newline at end of file From 2cabf1b2256fca5ce1066199d01ed968ede293a7 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 26 Jan 2014 23:33:10 -0500 Subject: [PATCH 02/81] Ongoing property work. --- .../DataSource/CompositePositionProperty.js | 148 ++++++++++++ Source/DataSource/CompositeProperty.js | 6 +- Source/DataSource/MaterialProperty.js | 101 ++++++++ .../TimeIntervalCollectionPositionProperty.js | 6 +- .../TimeIntervalCollectionProperty.js | 6 +- .../CompositePositionPropertySpec.js | 219 ++++++++++++++++++ Specs/DataSource/CompositePropertySpec.js | 19 +- .../ConstantPositionPropertySpec.js | 3 +- .../DataSource/SampledPositionPropertySpec.js | 3 +- Specs/DataSource/SampledPropertySpec.js | 3 +- ...eIntervalCollectionPositionPropertySpec.js | 3 +- .../TimeIntervalCollectionPropertySpec.js | 3 +- 12 files changed, 499 insertions(+), 21 deletions(-) create mode 100644 Source/DataSource/CompositePositionProperty.js create mode 100644 Source/DataSource/MaterialProperty.js create mode 100644 Specs/DataSource/CompositePositionPropertySpec.js diff --git a/Source/DataSource/CompositePositionProperty.js b/Source/DataSource/CompositePositionProperty.js new file mode 100644 index 000000000000..0258f49c4ae4 --- /dev/null +++ b/Source/DataSource/CompositePositionProperty.js @@ -0,0 +1,148 @@ +/*global define*/ +define(['../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame', + './CompositeProperty', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame, + CompositeProperty, + Property) { + "use strict"; + + /** + * A {@link CompositeProperty} which is also a {@link PositionProperty}. + * + * @alias CompositePositionProperty + * @constructor + */ + var CompositePositionProperty = function(referenceFrame) { + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); + }; + + defineProperties(CompositePositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof CompositePositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositePositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof CompositePositionProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._composite.intervals; + } + }, + /** + * Gets or sets the reference frame which this position presents itself as. + * Each PositionProperty making up this object has it's own reference frame, + * so this property merely exposes a "preferred" reference frame for clients + * to use. + * @memberof CompositePositionProperty.prototype + * + * @Type {ReferenceFrame} The preferred reference frame. + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + }, + set : function(value) { + this._referenceFrame = value; + } + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * @memberof CompositePositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + CompositePositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof CompositePositionProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + CompositePositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + //>>includeEnd('debug'); + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValueInReferenceFrame(time, referenceFrame, result); + } + return undefined; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof CompositePositionProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + CompositePositionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositePositionProperty && // + this._referenceFrame === other._referenceFrame && // + this._composite.equals(other._composite, Property.equals)); + }; + + return CompositePositionProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/CompositeProperty.js b/Source/DataSource/CompositeProperty.js index de04dba8db01..5c5281285d89 100644 --- a/Source/DataSource/CompositeProperty.js +++ b/Source/DataSource/CompositeProperty.js @@ -69,9 +69,9 @@ define(['./Property', subscribeAll(that, eventHelper, definitionChanged, intervals); definitionChanged.raiseEvent(that); }; - intervals.addInterval = wrapFunction(intervals, intervals.addInterval, intervalsChanged); - intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, intervalsChanged); - intervals.clear = wrapFunction(intervals, intervals.clear, intervalsChanged); + intervals.addInterval = wrapFunction(intervals, intervalsChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, intervalsChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, intervalsChanged, intervals.clear); this._intervals = intervals; this._definitionChanged = definitionChanged; diff --git a/Source/DataSource/MaterialProperty.js b/Source/DataSource/MaterialProperty.js new file mode 100644 index 000000000000..64053a0f3e70 --- /dev/null +++ b/Source/DataSource/MaterialProperty.js @@ -0,0 +1,101 @@ +/*global define*/ +define(['../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Scene/Material' + ], function( + defined, + defineProperties, + DeveloperError, + Material) { + "use strict"; + + /** + * The interface for all {@link MaterialProperty} objects that represent {@link Material} uniforms. + * This type defines an interface and cannot be instantiated directly. + * + * @alias MaterialProperty + * @constructor + * + * @see ColorMaterialProperty + * @see CompositeMaterialProperty + * @see GridMaterialProperty + * @see ImageMaterialProperty + */ + var MaterialProperty = function() { + DeveloperError.throwInstantiationError(); + }; + + defineProperties(MaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof MaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof MaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof MaterialProperty + * @function + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; + + /** + * Gets the value of the property at the provided time. + * @memberof MaterialProperty + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof MaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; + + /** + * @private + */ + MaterialProperty.getValue = function(time, materialProperty, material) { + if (defined(materialProperty)) { + var type = materialProperty.getType(time); + if (defined(type)) { + if (!defined(material) || (material.type !== type)) { + material = Material.fromType(type); + } + materialProperty.getValue(time, material.uniforms); + } + } + return material; + }; + + return MaterialProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/TimeIntervalCollectionPositionProperty.js b/Source/DataSource/TimeIntervalCollectionPositionProperty.js index 6fcfb7fd5832..40c2eb1c3aa9 100644 --- a/Source/DataSource/TimeIntervalCollectionPositionProperty.js +++ b/Source/DataSource/TimeIntervalCollectionPositionProperty.js @@ -40,9 +40,9 @@ define(['./PositionProperty', var raiseDefinitionChanged = function() { definitionChanged.raiseEvent(that); }; - intervals.addInterval = wrapFunction(intervals, intervals.addInterval, raiseDefinitionChanged); - intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, raiseDefinitionChanged); - intervals.clear = wrapFunction(intervals, intervals.clear, raiseDefinitionChanged); + intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); this._intervals = intervals; this._definitionChanged = definitionChanged; diff --git a/Source/DataSource/TimeIntervalCollectionProperty.js b/Source/DataSource/TimeIntervalCollectionProperty.js index d77a27ecd6d3..2d6765962749 100644 --- a/Source/DataSource/TimeIntervalCollectionProperty.js +++ b/Source/DataSource/TimeIntervalCollectionProperty.js @@ -65,9 +65,9 @@ define(['./Property', var raiseDefinitionChanged = function() { definitionChanged.raiseEvent(that); }; - intervals.addInterval = wrapFunction(intervals, intervals.addInterval, raiseDefinitionChanged); - intervals.removeInterval = wrapFunction(intervals, intervals.removeInterval, raiseDefinitionChanged); - intervals.clear = wrapFunction(intervals, intervals.clear, raiseDefinitionChanged); + intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); this._intervals = intervals; this._definitionChanged = definitionChanged; diff --git a/Specs/DataSource/CompositePositionPropertySpec.js b/Specs/DataSource/CompositePositionPropertySpec.js new file mode 100644 index 000000000000..7edcf333cd21 --- /dev/null +++ b/Specs/DataSource/CompositePositionPropertySpec.js @@ -0,0 +1,219 @@ +/*global defineSuite*/ +defineSuite(['DataSource/CompositePositionProperty', + 'DataSource/ConstantPositionProperty', + 'DataSource/PositionProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/ReferenceFrame', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection' + ], function( + CompositePositionProperty, + ConstantPositionProperty, + PositionProperty, + Cartesian3, + JulianDate, + ReferenceFrame, + TimeInterval, + TimeIntervalCollection) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('default constructor has expected values', function() { + var property = new CompositePositionProperty(); + expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.getValue(new JulianDate())).toBeUndefined(); + expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); + }); + + it('constructor sets expected values', function() { + var property = new CompositePositionProperty(ReferenceFrame.INERTIAL); + expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); + }); + + it('can modify reference frame', function() { + var property = new CompositePositionProperty(); + expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); + property.referenceFrame = ReferenceFrame.INERTIAL; + expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); + }); + + it('works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(result1).not.toBe(interval1.data.getValue(interval1.start)); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop); + expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('getValue works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = new Cartesian3(); + var result1 = property.getValue(interval1.start, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('getValue works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('getValue returns in fixed frame', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var valueInertial = new Cartesian3(1, 2, 3); + var valueFixed = PositionProperty.convertToReferenceFrame(interval1.start, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); + + var result1 = property.getValue(interval1.start); + expect(result1).toEqual(valueFixed); + + var result2 = property.getValue(interval2.stop); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('getValueInReferenceFrame works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = new Cartesian3(); + var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL)); + + var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED)); + }); + + it('getValueInReferenceFrame works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); + + var property = new CompositePositionProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL); + expect(result1).toEqual(interval1.data.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL)); + + var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED); + expect(result2).toEqual(interval2.data.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED)); + }); + + it('equals works', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var left = new CompositePositionProperty(); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new CompositePositionProperty(); + right.intervals.addInterval(interval1); + expect(left.equals(right)).toEqual(false); + + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + + right.referenceFrame = ReferenceFrame.INTERTIAL; + expect(left.equals(right)).toEqual(false); + }); + + it('getValue throws with no time parameter', function() { + var property = new CompositePositionProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('getValueInReferenceFrame throws with no referenceFrame parameter', function() { + var property = new CompositePositionProperty(); + var time = new JulianDate(); + expect(function() { + property.getValueInReferenceFrame(time, undefined); + }).toThrowDeveloperError(); + }); + + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/CompositePropertySpec.js b/Specs/DataSource/CompositePropertySpec.js index 0cc4e03a589d..db876de99e84 100644 --- a/Specs/DataSource/CompositePropertySpec.js +++ b/Specs/DataSource/CompositePropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/CompositeProperty', +defineSuite(['DataSource/CompositeProperty', 'DataSource/ConstantProperty', 'Core/Cartesian3', 'Core/JulianDate', @@ -101,6 +100,22 @@ defineSuite([ property.definitionChanged.raiseEvent.reset(); }); + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); + it('getValue throws with no time parameter', function() { var property = new CompositeProperty(); expect(function() { diff --git a/Specs/DataSource/ConstantPositionPropertySpec.js b/Specs/DataSource/ConstantPositionPropertySpec.js index 5014ab5e22f3..5ddb76a4fc44 100644 --- a/Specs/DataSource/ConstantPositionPropertySpec.js +++ b/Specs/DataSource/ConstantPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/ConstantPositionProperty', +defineSuite(['DataSource/ConstantPositionProperty', 'DataSource/PositionProperty', 'Core/Cartesian3', 'Core/JulianDate', diff --git a/Specs/DataSource/SampledPositionPropertySpec.js b/Specs/DataSource/SampledPositionPropertySpec.js index dfe90281af67..3de56a7158ee 100644 --- a/Specs/DataSource/SampledPositionPropertySpec.js +++ b/Specs/DataSource/SampledPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/SampledPositionProperty', +defineSuite(['DataSource/SampledPositionProperty', 'DataSource/PositionProperty', 'Core/Cartesian3', 'Core/defined', diff --git a/Specs/DataSource/SampledPropertySpec.js b/Specs/DataSource/SampledPropertySpec.js index f6d98048e3d5..bd4a54c0623c 100644 --- a/Specs/DataSource/SampledPropertySpec.js +++ b/Specs/DataSource/SampledPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/SampledProperty', +defineSuite(['DataSource/SampledProperty', 'Core/defined', 'Core/JulianDate', 'Core/LinearApproximation', diff --git a/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js index e0427f665e73..5356632e935a 100644 --- a/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js +++ b/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/TimeIntervalCollectionPositionProperty', +defineSuite(['DataSource/TimeIntervalCollectionPositionProperty', 'DataSource/PositionProperty', 'Core/Cartesian3', 'Core/JulianDate', diff --git a/Specs/DataSource/TimeIntervalCollectionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPropertySpec.js index c10003c07998..a79b892ebd7c 100644 --- a/Specs/DataSource/TimeIntervalCollectionPropertySpec.js +++ b/Specs/DataSource/TimeIntervalCollectionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DataSource/TimeIntervalCollectionProperty', +defineSuite(['DataSource/TimeIntervalCollectionProperty', 'Core/Cartesian3', 'Core/JulianDate', 'Core/TimeInterval', From 82bb80015ca611676d8e36c5fef6654644dbcd51 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 27 Jan 2014 16:36:46 -0500 Subject: [PATCH 03/81] Ongoing property work. --- Source/DataSource/ColorMaterialProperty.js | 127 ++++++++++ .../DataSource/CompositeMaterialProperty.js | 127 ++++++++++ Source/DataSource/GridMaterialProperty.js | 217 +++++++++++++++++ Specs/DataSource/ColorMaterialPropertySpec.js | 98 ++++++++ .../CompositeMaterialPropertySpec.js | 138 +++++++++++ Specs/DataSource/GridMaterialPropertySpec.js | 225 ++++++++++++++++++ 6 files changed, 932 insertions(+) create mode 100644 Source/DataSource/ColorMaterialProperty.js create mode 100644 Source/DataSource/CompositeMaterialProperty.js create mode 100644 Source/DataSource/GridMaterialProperty.js create mode 100644 Specs/DataSource/ColorMaterialPropertySpec.js create mode 100644 Specs/DataSource/CompositeMaterialPropertySpec.js create mode 100644 Specs/DataSource/GridMaterialPropertySpec.js diff --git a/Source/DataSource/ColorMaterialProperty.js b/Source/DataSource/ColorMaterialProperty.js new file mode 100644 index 000000000000..34757b7f2779 --- /dev/null +++ b/Source/DataSource/ColorMaterialProperty.js @@ -0,0 +1,127 @@ +/*global define*/ +define(['../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './ConstantProperty', + './Property' + ], function( + Color, + defined, + defineProperties, + Event, + ConstantProperty, + Property) { + "use strict"; + + /** + * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. + * @alias ColorMaterialProperty + * @constructor + */ + var ColorMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this.color = new ConstantProperty(Color.WHITE); + }; + + defineProperties(ColorMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ColorMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return !defined(this._color) || this._color.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ColorMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * A {@link Color} {@link Property} which determines the material's color. + * @memberof ColorMaterialProperty.prototype + * @type {Property} + * @default new ConstantProperty(Color.WHITE) + */ + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(ColorMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof ColorMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + ColorMaterialProperty.prototype.getType = function(time) { + return 'Color'; + }; + + /** + * Gets the value of the property at the provided time. + * @memberof ColorMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + ColorMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; + return result; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof ColorMaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + ColorMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof ColorMaterialProperty && // + Property.equals(this._color, other._color)); + }; + + ColorMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); + }; + + return ColorMaterialProperty; +}); diff --git a/Source/DataSource/CompositeMaterialProperty.js b/Source/DataSource/CompositeMaterialProperty.js new file mode 100644 index 000000000000..ede417155b95 --- /dev/null +++ b/Source/DataSource/CompositeMaterialProperty.js @@ -0,0 +1,127 @@ +/*global define*/ +define(['../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './CompositeProperty', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Event, + CompositeProperty, + Property) { + "use strict"; + + /** + * A {@link CompositeProperty} which is also a {@link MaterialProperty}. + * + * @alias CompositeMaterialProperty + * @constructor + */ + var CompositeMaterialProperty = function() { + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); + }; + + defineProperties(CompositeMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof CompositeMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof CompositeMaterialProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._composite._intervals; + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof CompositeMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + CompositeMaterialProperty.prototype.getType = function(time) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required'); + } + //>>includeEnd('debug'); + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getType(time); + } + return undefined; + }; + + /** + * Gets the value of the property at the provided time. + * @memberof CompositeMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + CompositeMaterialProperty.prototype.getValue = function(time, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required'); + } + //>>includeEnd('debug'); + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValue(time, result); + } + return undefined; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof CompositeMaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + CompositeMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositeMaterialProperty && // + this._composite.equals(other._composite, Property.equals)); + }; + + return CompositeMaterialProperty; +}); \ No newline at end of file diff --git a/Source/DataSource/GridMaterialProperty.js b/Source/DataSource/GridMaterialProperty.js new file mode 100644 index 000000000000..4ef4db809446 --- /dev/null +++ b/Source/DataSource/GridMaterialProperty.js @@ -0,0 +1,217 @@ +/*global define*/ +define(['../Core/Cartesian2', + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './ConstantProperty', + './Property' + ], function( + Cartesian2, + Color, + defined, + defineProperties, + Event, + ConstantProperty, + Property) { + "use strict"; + + /** + * A {@link MaterialProperty} that maps to grid {@link Material} uniforms. + * @alias GridMaterialProperty + * @constructor + */ + var GridMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._cellAlpha = undefined; + this._cellAlphaSubscription = undefined; + this._lineCount = undefined; + this._lineCountSubscription = undefined; + this._lineThickness = undefined; + this._lineThicknessSubscription = undefined; + + this.color = new ConstantProperty(Color.WHITE); + this.cellAlpha = new ConstantProperty(0.1); + this.lineCount = new ConstantProperty(new Cartesian2(8, 8)); + this.lineThickness = new ConstantProperty(new Cartesian2(1.0, 1.0)); + }; + + defineProperties(GridMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof GridMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._color) || this._color.isConstant) && // + (!defined(this._cellAlpha) || this._cellAlpha.isConstant) && // + (!defined(this._lineCount) || this._lineCount.isConstant) && // + (!defined(this._lineThickness) || this._lineThickness.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof GridMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * A {@link Color} {@link Property} which determines the grid's color. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default new ConstantProperty(Color.WHITE) + */ + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A numeric {@link Property} which determines the grid cells alpha value, when combined with the color alpha. + * @type {Property} + * @default new ConstantProperty(0.1) + */ + cellAlpha : { + get : function() { + return this._cellAlpha; + }, + set : function(value) { + if (this._cellAlpha !== value) { + if (this._cellAlphaSubscription) { + this._cellAlphaSubscription(); + this._cellAlphaSubscription = undefined; + } + this._cellAlpha = value; + if (defined(value)) { + this._cellAlphaSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A {@link Cartesian2} {@link Property} which determines the number of rows and columns in the grid. + * @type {Property} + * @default new ConstantProperty(new Cartesian2(8, 8)) + */ + lineCount : { + get : function() { + return this._lineCount; + }, + set : function(value) { + if (this._lineCount !== value) { + if (this._lineCountSubscription) { + this._lineCountSubscription(); + this._lineCountSubscription = undefined; + } + this._lineCount = value; + if (defined(value)) { + this._lineCountSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A {@link Cartesian2} {@link Property} which determines the thickness of rows and columns in the grid. + * @type {Property} + * @default new ConstantProperty(new Cartesian2(1.0, 1.0)) + */ + lineThickness : { + get : function() { + return this._lineThickness; + }, + set : function(value) { + if (this._lineThickness !== value) { + if (this._lineThicknessSubscription) { + this._lineThicknessSubscription(); + this._lineThicknessSubscription = undefined; + } + this._lineThickness = value; + if (defined(value)) { + this._lineThicknessSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof GridMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + GridMaterialProperty.prototype.getType = function(time) { + return 'Grid'; + }; + + /** + * Gets the value of the property at the provided time. + * @memberof GridMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + GridMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; + result.cellAlpha = defined(this._cellAlpha) ? this._cellAlpha.getValue(time) : undefined; + result.lineCount = defined(this._lineCount) ? this._lineCount.getValue(time, result.lineCount) : undefined; + result.lineThickness = defined(this._lineThickness) ? this._lineThickness.getValue(time, result.lineThickness) : undefined; + return result; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof GridMaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + GridMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof GridMaterialProperty && // + Property.equals(this._color, other._color) && // + Property.equals(this._cellAlpha, other._cellAlpha) && // + Property.equals(this._lineCount, other._lineCount) && // + Property.equals(this._lineThickness, other._lineThickness)); + }; + + GridMaterialProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + + return GridMaterialProperty; +}); diff --git a/Specs/DataSource/ColorMaterialPropertySpec.js b/Specs/DataSource/ColorMaterialPropertySpec.js new file mode 100644 index 000000000000..b026498f1cac --- /dev/null +++ b/Specs/DataSource/ColorMaterialPropertySpec.js @@ -0,0 +1,98 @@ +/*global defineSuite*/ +defineSuite(['DataSource/ColorMaterialProperty', + 'DataSource/ConstantProperty', + 'DataSource/TimeIntervalCollectionProperty', + 'Core/Color', + 'Core/JulianDate', + 'Core/TimeInterval' + ], function( + ColorMaterialProperty, + ConstantProperty, + TimeIntervalCollectionProperty, + Color, + JulianDate, + TimeInterval) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor provides the expected defaults', function() { + var property = new ColorMaterialProperty(); + expect(property.color).toBeDefined(); + expect(property.getType()).toEqual('Color'); + expect(property.isConstant).toBe(true); + + var result = property.getValue(); + expect(result.color).toEqual(Color.WHITE); + }); + + it('works with constant values', function() { + var property = new ColorMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + + var result = property.getValue(new JulianDate()); + expect(result.color).toEqual(Color.RED); + }); + + it('works with undefined values', function() { + var property = new ColorMaterialProperty(); + property.color.setValue(undefined); + + var result = property.getValue(); + expect(result.hasOwnProperty('color')).toEqual(true); + expect(result.color).toBeUndefined(); + }); + + it('works with dynamic values', function() { + var property = new ColorMaterialProperty(); + property.color = new TimeIntervalCollectionProperty(); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + + expect(property.isConstant).toBe(false); + + var result = property.getValue(start); + expect(result.color).toEqual(Color.BLUE); + }); + + it('works with a result parameter', function() { + var property = new ColorMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + + var result = { + color : Color.BLUE.clone() + }; + var returnedResult = property.getValue(new JulianDate(), result); + expect(returnedResult).toBe(result); + expect(result.color).toEqual(Color.RED); + }); + + it('equals works', function() { + var left = new ColorMaterialProperty(); + left.color = new ConstantProperty(Color.WHITE); + + var right = new ColorMaterialProperty(); + right.color = new ConstantProperty(Color.WHITE); + expect(left.equals(right)).toEqual(true); + + right.color = new ConstantProperty(Color.BLACK); + expect(left.equals(right)).toEqual(false); + }); + + it('raises definitionChanged when a color property is assigned or modified', function() { + var property = new ColorMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.WHITE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.BLACK); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/CompositeMaterialPropertySpec.js b/Specs/DataSource/CompositeMaterialPropertySpec.js new file mode 100644 index 000000000000..ffce5db2df7a --- /dev/null +++ b/Specs/DataSource/CompositeMaterialPropertySpec.js @@ -0,0 +1,138 @@ +/*global defineSuite*/ +defineSuite(['DataSource/CompositeMaterialProperty', + 'DataSource/ColorMaterialProperty', + 'DataSource/GridMaterialProperty', + 'Core/Color', + 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection' + ], function( + CompositeMaterialProperty, + ColorMaterialProperty, + GridMaterialProperty, + Color, + JulianDate, + TimeInterval, + TimeIntervalCollection) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('default constructor has expected values', function() { + var property = new CompositeMaterialProperty(); + expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.getType(new JulianDate())).toBeUndefined(); + expect(property.getValue(new JulianDate())).toBeUndefined(); + }); + + it('works without a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); + + var property = new CompositeMaterialProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var result1 = property.getValue(interval1.start); + expect(property.getType(interval1.start)).toEqual('Color'); + expect(result1).not.toBe(interval1.data.getValue(interval1.start)); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop); + expect(property.getType(interval2.stop)).toEqual('Grid'); + expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('works with a result parameter', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); + + var property = new CompositeMaterialProperty(); + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + + var expected = {}; + var result1 = property.getValue(interval1.start, expected); + expect(result1).toBe(expected); + expect(result1).toEqual(interval1.data.getValue(interval1.start)); + + var result2 = property.getValue(interval2.stop, expected); + expect(result2).toBe(expected); + expect(result2).toEqual(interval2.data.getValue(interval2.stop)); + }); + + it('equals works', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); + + var left = new CompositeMaterialProperty(); + left.intervals.addInterval(interval1); + left.intervals.addInterval(interval2); + + var right = new CompositeMaterialProperty(); + right.intervals.addInterval(interval1); + + expect(left.equals(right)).toEqual(false); + + right.intervals.addInterval(interval2); + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + + var property = new CompositeMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.color.setValue(Color.BLUE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + + var property = new CompositeMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.color.setValue(Color.BLUE); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); + + it('getValue throws with no time parameter', function() { + var property = new CompositeMaterialProperty(); + expect(function() { + property.getValue(undefined); + }).toThrowDeveloperError(); + }); + + it('getType throws with no time parameter', function() { + var property = new CompositeMaterialProperty(); + expect(function() { + property.getType(undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/GridMaterialPropertySpec.js b/Specs/DataSource/GridMaterialPropertySpec.js new file mode 100644 index 000000000000..6b00f43b21ff --- /dev/null +++ b/Specs/DataSource/GridMaterialPropertySpec.js @@ -0,0 +1,225 @@ +/*global defineSuite*/ +defineSuite(['DataSource/GridMaterialProperty', + 'DataSource/ConstantProperty', + 'DataSource/SampledProperty', + 'DataSource/TimeIntervalCollectionProperty', + 'Core/Cartesian2', + 'Core/Color', + 'Core/JulianDate', + 'Core/TimeInterval' + ], function( + GridMaterialProperty, + ConstantProperty, + SampledProperty, + TimeIntervalCollectionProperty, + Cartesian2, + Color, + JulianDate, + TimeInterval) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('works with basic types', function() { + var property = new GridMaterialProperty(); + expect(property.color).toBeDefined(); + expect(property.cellAlpha).toBeDefined(); + expect(property.lineCount).toBeDefined(); + expect(property.lineThickness).toBeDefined(); + + expect(property.getType()).toEqual('Grid'); + + var result = property.getValue(); + expect(result.color).toEqual(Color.WHITE); + expect(result.cellAlpha).toEqual(0.1); + expect(result.lineCount).toEqual(new Cartesian2(8, 8)); + expect(result.lineThickness).toEqual(new Cartesian2(1.0, 1.0)); + }); + + it('works with constant values', function() { + var property = new GridMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + property.cellAlpha = new ConstantProperty(1.0); + property.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); + property.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); + + var result = property.getValue(new JulianDate()); + expect(result.color).toEqual(Color.RED); + expect(result.cellAlpha).toEqual(1); + expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); + expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); + }); + + it('works with undefined values', function() { + var property = new GridMaterialProperty(); + property.color.setValue(undefined); + property.cellAlpha.setValue(undefined); + property.lineCount.setValue(undefined); + property.lineThickness.setValue(undefined); + + var result = property.getValue(); + expect(result.hasOwnProperty('color')).toEqual(true); + expect(result.hasOwnProperty('cellAlpha')).toEqual(true); + expect(result.hasOwnProperty('lineCount')).toEqual(true); + expect(result.hasOwnProperty('lineThickness')).toEqual(true); + expect(result.color).toBeUndefined(); + expect(result.cellAlpha).toBeUndefined(); + expect(result.lineCount).toBeUndefined(); + expect(result.lineThickness).toBeUndefined(); + }); + + it('works with dynamic values', function() { + var property = new GridMaterialProperty(); + property.color = new TimeIntervalCollectionProperty(); + property.cellAlpha = new TimeIntervalCollectionProperty(); + property.lineCount = new TimeIntervalCollectionProperty(); + property.lineThickness = new TimeIntervalCollectionProperty(); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + property.cellAlpha.intervals.addInterval(new TimeInterval(start, stop, true, true, 1.0)); + property.lineCount.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(3.4, 5.0))); + property.lineThickness.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); + + var result = property.getValue(start); + expect(result.color).toEqual(Color.BLUE); + expect(result.cellAlpha).toEqual(1); + expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); + expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); + }); + + it('works with a result parameter', function() { + var property = new GridMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + property.cellAlpha = new ConstantProperty(1.0); + property.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); + property.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); + + var result = {}; + var returnedResult = property.getValue(new JulianDate(), result); + expect(result).toBe(returnedResult); + expect(result.color).toEqual(Color.RED); + expect(result.cellAlpha).toEqual(1.0); + expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); + expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); + }); + + it('equals works', function() { + var left = new GridMaterialProperty(); + left.color = new ConstantProperty(Color.RED); + left.cellAlpha = new ConstantProperty(1.0); + left.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); + left.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); + + var right = new GridMaterialProperty(); + right.color = new ConstantProperty(Color.RED); + right.cellAlpha = new ConstantProperty(1.0); + right.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); + right.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); + + expect(left.equals(right)).toEqual(true); + + right.color = new ConstantProperty(Color.BLUE); + expect(left.equals(right)).toEqual(false); + + right.color = left.color; + right.cellAlpha = new ConstantProperty(0.5); + expect(left.equals(right)).toEqual(false); + + right.cellAlpha = left.cellAlpha; + right.lineCount = new ConstantProperty(new Cartesian2(4, 5.0)); + expect(left.equals(right)).toEqual(false); + + right.lineCount = left.lineCount; + right.lineThickness = new ConstantProperty(new Cartesian2(3, 2)); + expect(left.equals(right)).toEqual(false); + + right.lineThickness = left.lineThickness; + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new GridMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.WHITE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.BLACK); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha = new ConstantProperty(0.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha.setValue(1.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha = property.cellAlpha; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount = new ConstantProperty(5.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount.setValue(10.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount = property.lineCount; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness = new ConstantProperty(5.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness.setValue(10.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness = property.lineThickness; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new GridMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.color = undefined; + property.cellAlpha = undefined; + property.lineCount = undefined; + property.lineThickness = undefined; + expect(property.isConstant).toBe(true); + + property.color = new SampledProperty(Color); + property.color.addSample(new JulianDate(), Color.WHITE); + expect(property.isConstant).toBe(false); + + property.color = undefined; + expect(property.isConstant).toBe(true); + property.cellAlpha = new SampledProperty(Number); + property.cellAlpha.addSample(new JulianDate(), 0); + expect(property.isConstant).toBe(false); + + property.cellAlpha = undefined; + expect(property.isConstant).toBe(true); + property.lineCount = new SampledProperty(Number); + property.lineCount.addSample(new JulianDate(), 1); + expect(property.isConstant).toBe(false); + + property.lineCount = undefined; + expect(property.isConstant).toBe(true); + property.lineThickness= new SampledProperty(Number); + property.lineThickness.addSample(new JulianDate(), 1); + expect(property.isConstant).toBe(false); + }); +}); \ No newline at end of file From 9e7a77f2389dc68f1fc5aaf234244010aef433cf Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 27 Jan 2014 17:50:49 -0500 Subject: [PATCH 04/81] Ongoing property work. --- Source/DataSource/ColorMaterialProperty.js | 3 + Source/DataSource/GridMaterialProperty.js | 3 + Source/DataSource/ImageMaterialProperty.js | 159 +++++++++++++++ .../PolylineOutlineMaterialProperty.js | 189 ++++++++++++++++++ Specs/DataSource/GridMaterialPropertySpec.js | 2 +- Specs/DataSource/ImageMaterialPropertySpec.js | 147 ++++++++++++++ .../PolylineOutlineMaterialPropertySpec.js | 170 ++++++++++++++++ 7 files changed, 672 insertions(+), 1 deletion(-) create mode 100644 Source/DataSource/ImageMaterialProperty.js create mode 100644 Source/DataSource/PolylineOutlineMaterialProperty.js create mode 100644 Specs/DataSource/ImageMaterialPropertySpec.js create mode 100644 Specs/DataSource/PolylineOutlineMaterialPropertySpec.js diff --git a/Source/DataSource/ColorMaterialProperty.js b/Source/DataSource/ColorMaterialProperty.js index 34757b7f2779..e5ba98f9daee 100644 --- a/Source/DataSource/ColorMaterialProperty.js +++ b/Source/DataSource/ColorMaterialProperty.js @@ -119,6 +119,9 @@ define(['../Core/Color', Property.equals(this._color, other._color)); }; + /** + * @private + */ ColorMaterialProperty.prototype._raiseDefinitionChanged = function(){ this._definitionChanged.raiseEvent(this); }; diff --git a/Source/DataSource/GridMaterialProperty.js b/Source/DataSource/GridMaterialProperty.js index 4ef4db809446..44bb03791ed7 100644 --- a/Source/DataSource/GridMaterialProperty.js +++ b/Source/DataSource/GridMaterialProperty.js @@ -209,6 +209,9 @@ define(['../Core/Cartesian2', Property.equals(this._lineThickness, other._lineThickness)); }; + /** + * @private + */ GridMaterialProperty.prototype._raiseDefinitionChanged = function() { this._definitionChanged.raiseEvent(this); }; diff --git a/Source/DataSource/ImageMaterialProperty.js b/Source/DataSource/ImageMaterialProperty.js new file mode 100644 index 000000000000..d31884a5af05 --- /dev/null +++ b/Source/DataSource/ImageMaterialProperty.js @@ -0,0 +1,159 @@ +/*global define*/ +define([ + '../Core/Cartesian2', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './ConstantProperty', + './Property' + ], function( + Cartesian2, + defined, + defineProperties, + Event, + ConstantProperty, + Property) { + "use strict"; + + /** + * A {@link MaterialProperty} that maps to image {@link Material} uniforms. + * @alias ImageMaterialProperty + * @constructor + */ + var ImageMaterialProperty = function() { + this._definitionChanged = new Event(); + this._image = undefined; + this._imageSubscription = undefined; + this._repeat = undefined; + this._repeatSubscription = undefined; + this.repeat = new ConstantProperty(new Cartesian2(1, 1)); + }; + + defineProperties(ImageMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ImageMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._image) || this._image.isConstant) && (!defined(this._repeat) || this._repeat.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ImageMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * A string {@link Property} which is the url of the desired image. + * @memberof ImageMaterialProperty.prototype + * @type {Property} + */ + image : { + get : function() { + return this._image; + }, + set : function(value) { + if (this._image !== value) { + if (this._imageSubscription) { + this._imageSubscription(); + this._imageSubscription = undefined; + } + this._image = value; + if (defined(value)) { + this._imageSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A {@link Cartesian2} {@link Property} which determines the number of times the image repeats in each direction. + * @memberof ImageMaterialProperty.prototype + * @type {Property} + * @default new ConstantProperty(new Cartesian2(1, 1)) + */ + repeat : { + get : function() { + return this._repeat; + }, + set : function(value) { + if (this._repeat !== value) { + if (this._repeatSubscription) { + this._repeatSubscription(); + this._repeatSubscription = undefined; + } + this._repeat = value; + if (defined(value)) { + this._repeatSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof ImageMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + ImageMaterialProperty.prototype.getType = function(time) { + return 'Image'; + }; + + /** + * Gets the value of the property at the provided time. + * @memberof ImageMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + ImageMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + + result.image = defined(this._image) ? this._image.getValue(time) : undefined; + result.repeat = defined(this._repeat) ? this._repeat.getValue(time, result.repeat) : undefined; + return result; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof ImageMaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + ImageMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof ImageMaterialProperty && // + Property.equals(this._image, other._image) && // + Property.equals(this._repeat, other._repeat)); + }; + + /** + * @private + */ + ImageMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); + }; + + return ImageMaterialProperty; +}); diff --git a/Source/DataSource/PolylineOutlineMaterialProperty.js b/Source/DataSource/PolylineOutlineMaterialProperty.js new file mode 100644 index 000000000000..8ddf10f2297c --- /dev/null +++ b/Source/DataSource/PolylineOutlineMaterialProperty.js @@ -0,0 +1,189 @@ +/*global define*/ +define(['../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './ConstantProperty', + './Property' + ], function( + Color, + defined, + defineProperties, + Event, + ConstantProperty, + Property) { + "use strict"; + + /** + * A {@link MaterialProperty} that maps to polyline outline {@link Material} uniforms. + * @alias PolylineOutlineMaterialProperty + * @constructor + */ + var PolylineOutlineMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this.color = new ConstantProperty(Color.WHITE); + this.outlineColor = new ConstantProperty(Color.BLACK); + this.outlineWidth = new ConstantProperty(0.0); + }; + + defineProperties(PolylineOutlineMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A value is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._color) || this._color.isConstant) && + (!defined(this._outlineColor) || this._outlineColor.isConstant) && + (!defined(this._outlineWidth) || this._outlineWidth.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * A {@link Color} {@link Property} which determines the polyline's color. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Property} + * @default new ConstantProperty(Color.WHITE) + */ + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A {@link Color} {@link Property} which determines the polyline's outline color. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Property} + * @default new ConstantProperty(Color.BLACK) + */ + outlineColor : { + get : function() { + return this._outlineColor; + }, + set : function(value) { + if (this._outlineColor !== value) { + if (this._outlineColorSubscription) { + this._outlineColorSubscription(); + this._outlineColorSubscription = undefined; + } + this._outlineColor = value; + if (defined(value)) { + this._outlineColorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + /** + * A Number {@link Property} which determines the polyline's outline width. + * @type {Property} + * @default new ConstantProperty(0) + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + }, + set : function(value) { + if (this._outlineWidth !== value) { + if (this._outlineWidthSubscription) { + this._outlineWidthSubscription(); + this._outlineWidthSubscription = undefined; + } + this._outlineWidth = value; + if (defined(value)) { + this._outlineWidthSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @memberof PolylineOutlineMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the type. + * @type {String} The type of material. + */ + PolylineOutlineMaterialProperty.prototype.getType = function(time) { + return 'PolylineOutline'; + }; + + /** + * Gets the value of the property at the provided time. + * @memberof PolylineOutlineMaterialProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + */ + PolylineOutlineMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; + result.outlineColor = defined(this._outlineColor) ? this._outlineColor.getValue(time, result.outlineColor) : undefined; + result.outlineWidth = defined(this._outlineWidth) ? this._outlineWidth.getValue(time) : undefined; + return result; + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof PolylineOutlineMaterialProperty + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + PolylineOutlineMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof PolylineOutlineMaterialProperty && // + Property.equals(this._color, other._color) && // + Property.equals(this._outlineColor, other._outlineColor) && // + Property.equals(this._outlineWidth, other._outlineWidth)); + }; + + /** + * @private + */ + PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); + }; + + return PolylineOutlineMaterialProperty; +}); diff --git a/Specs/DataSource/GridMaterialPropertySpec.js b/Specs/DataSource/GridMaterialPropertySpec.js index 6b00f43b21ff..54351e7318df 100644 --- a/Specs/DataSource/GridMaterialPropertySpec.js +++ b/Specs/DataSource/GridMaterialPropertySpec.js @@ -19,7 +19,7 @@ defineSuite(['DataSource/GridMaterialProperty', "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('works with basic types', function() { + it('constructor provides the expected defaults', function() { var property = new GridMaterialProperty(); expect(property.color).toBeDefined(); expect(property.cellAlpha).toBeDefined(); diff --git a/Specs/DataSource/ImageMaterialPropertySpec.js b/Specs/DataSource/ImageMaterialPropertySpec.js new file mode 100644 index 000000000000..5cfe5e31033c --- /dev/null +++ b/Specs/DataSource/ImageMaterialPropertySpec.js @@ -0,0 +1,147 @@ +/*global defineSuite*/ +defineSuite([ + 'DataSource/ImageMaterialProperty', + 'DataSource/ConstantProperty', + 'DataSource/TimeIntervalCollectionProperty', + 'Core/Cartesian2', + 'Core/JulianDate', + 'Core/TimeInterval' + ], function( + ImageMaterialProperty, + ConstantProperty, + TimeIntervalCollectionProperty, + Cartesian2, + JulianDate, + TimeInterval) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor provides the expected defaults', function() { + var property = new ImageMaterialProperty(); + expect(property.getType()).toEqual('Image'); + + var result = property.getValue(); + expect(result.image).toBeUndefined(); + expect(result.repeat).toEqual(new Cartesian2(1.0, 1.0)); + }); + + it('works with constant values', function() { + var property = new ImageMaterialProperty(); + property.image = new ConstantProperty('http://test.invalid/image.png'); + property.repeat = new ConstantProperty(new Cartesian2(2, 3)); + + var result = property.getValue(new JulianDate()); + expect(result.image).toEqual('http://test.invalid/image.png'); + expect(result.repeat).toEqual(new Cartesian2(2, 3)); + }); + + it('works with undefined values', function() { + var property = new ImageMaterialProperty(); + property.image = new ConstantProperty(); + property.repeat = new ConstantProperty(); + + var result = property.getValue(); + expect(result.hasOwnProperty('image')).toEqual(true); + expect(result.hasOwnProperty('repeat')).toEqual(true); + expect(result.image).toBeUndefined(); + expect(result.repeat).toBeUndefined(); + }); + + it('works with dynamic values', function() { + var property = new ImageMaterialProperty(); + property.image = new TimeIntervalCollectionProperty(); + property.repeat = new TimeIntervalCollectionProperty(); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.image.intervals.addInterval(new TimeInterval(start, stop, true, true, 'http://test.invalid/image.png')); + property.repeat.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); + + var result = property.getValue(start); + expect(result.image).toEqual('http://test.invalid/image.png'); + expect(result.repeat).toEqual(new Cartesian2(2, 3)); + }); + + it('works with a result parameter', function() { + var property = new ImageMaterialProperty(); + property.image = new ConstantProperty('http://test.invalid/image.png'); + property.repeat = new ConstantProperty(new Cartesian2(2, 3)); + + var result = {}; + var returnedResult = property.getValue(new JulianDate(), result); + expect(result).toBe(returnedResult); + expect(result.image).toEqual('http://test.invalid/image.png'); + expect(result.repeat).toEqual(new Cartesian2(2, 3)); + }); + + it('equals works', function() { + var left = new ImageMaterialProperty(); + left.image = new ConstantProperty('http://test.invalid/image.png'); + left.repeat = new ConstantProperty(new Cartesian2(2, 3)); + + var right = new ImageMaterialProperty(); + right.image = new ConstantProperty('http://test.invalid/image.png'); + right.repeat = new ConstantProperty(new Cartesian2(2, 3)); + + expect(left.equals(right)).toEqual(true); + + right.image = new ConstantProperty('http://test.invalid/image2.png'); + expect(left.equals(right)).toEqual(false); + + right.image = left.image; + right.repeat = new ConstantProperty(new Cartesian2(3, 2)); + expect(left.equals(right)).toEqual(false); + + right.repeat = left.repeat; + expect(left.equals(right)).toEqual(true); + }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new ImageMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.image = new ConstantProperty('http://test.invalid/image.png'); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.image.setValue('http://test.invalid/image2.png'); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.image = property.image; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.repeat = new ConstantProperty(new Cartesian2(1.5, 1.5)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.repeat.setValue(new Cartesian2(1.0, 1.0)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.repeat = property.repeat; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new ImageMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.image = undefined; + property.repeat = undefined; + expect(property.isConstant).toBe(true); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.image = new TimeIntervalCollectionProperty(); + property.image.intervals.addInterval(new TimeInterval(start, stop, true, true, 'http://test.invalid/image.png')); + expect(property.isConstant).toBe(false); + + property.image = undefined; + expect(property.isConstant).toBe(true); + property.repeat = new TimeIntervalCollectionProperty(); + property.repeat.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); + expect(property.isConstant).toBe(false); + }); +}); \ No newline at end of file diff --git a/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js b/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js new file mode 100644 index 000000000000..b4303427f0f2 --- /dev/null +++ b/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js @@ -0,0 +1,170 @@ +/*global defineSuite*/ +defineSuite(['DataSource/PolylineOutlineMaterialProperty', + 'DataSource/ConstantProperty', + 'DataSource/TimeIntervalCollectionProperty', + 'Core/Color', + 'Core/JulianDate', + 'Core/TimeInterval' + ], function( + PolylineOutlineMaterialProperty, + ConstantProperty, + TimeIntervalCollectionProperty, + Color, + JulianDate, + TimeInterval) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor provides the expected defaults', function() { + var property = new PolylineOutlineMaterialProperty(); + expect(property.getType()).toEqual('PolylineOutline'); + + var result = property.getValue(); + expect(result.color).toEqual(Color.WHITE); + expect(result.outlineColor).toEqual(Color.BLACK); + expect(result.outlineWidth).toEqual(0.0); + }); + + it('works with constant values', function() { + var property = new PolylineOutlineMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + property.outlineColor = new ConstantProperty(Color.BLUE); + + var result = property.getValue(new JulianDate()); + expect(result.color).toEqual(Color.RED); + expect(result.outlineColor).toEqual(Color.BLUE); + }); + + it('works with undefined values', function() { + var property = new PolylineOutlineMaterialProperty(); + property.color.setValue(undefined); + property.outlineColor.setValue(undefined); + + var result = property.getValue(); + expect(result.hasOwnProperty('color')).toEqual(true); + expect(result.hasOwnProperty('outlineColor')).toEqual(true); + expect(result.color).toBeUndefined(); + expect(result.outlineColor).toBeUndefined(); + }); + + it('works with dynamic values', function() { + var property = new PolylineOutlineMaterialProperty(); + property.color = new TimeIntervalCollectionProperty(); + property.outlineColor = new TimeIntervalCollectionProperty(); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + property.outlineColor.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.RED)); + + var result = property.getValue(start); + expect(result.color).toEqual(Color.BLUE); + expect(result.outlineColor).toEqual(Color.RED); + }); + + it('works with a result parameter', function() { + var property = new PolylineOutlineMaterialProperty(); + property.color = new ConstantProperty(Color.RED); + property.outlineColor = new ConstantProperty(Color.BLUE); + + var result = { + color : Color.YELLOW.clone(), + outlineColor : Color.BROWN.clone() + }; + var returnedResult = property.getValue(new JulianDate(), result); + expect(returnedResult).toBe(result); + expect(result.color).toEqual(Color.RED); + expect(result.outlineColor).toEqual(Color.BLUE); + }); + + it('equals works', function() { + var left = new PolylineOutlineMaterialProperty(); + left.color = new ConstantProperty(Color.WHITE); + left.outlineColor = new ConstantProperty(Color.BLACK); + left.outlineWidth = new ConstantProperty(5); + + var right = new PolylineOutlineMaterialProperty(); + right.color = new ConstantProperty(Color.WHITE); + right.outlineColor = new ConstantProperty(Color.BLACK); + right.outlineWidth = new ConstantProperty(5); + expect(left.equals(right)).toEqual(true); + + right.color = new ConstantProperty(Color.RED); + expect(left.equals(right)).toEqual(false); + + right.color = left.color; + right.outlineColor = new ConstantProperty(Color.BLUE); + expect(left.equals(right)).toEqual(false); + + right.outlineColor = left.outlineColor; + right.outlineWidth = new ConstantProperty(6); + expect(left.equals(right)).toEqual(false); + }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new PolylineOutlineMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.RED); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.YELLOW); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor = new ConstantProperty(Color.BLUE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor.setValue(Color.GREEN); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor = property.outlineColor; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + + property.outlineWidth = new ConstantProperty(2.5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineWidth.setValue(1.5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineWidth = property.outlineWidth; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new PolylineOutlineMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.color = undefined; + property.outlineColor = undefined; + property.outlineWidth = undefined; + expect(property.isConstant).toBe(true); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.color = new TimeIntervalCollectionProperty(); + property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.RED)); + expect(property.isConstant).toBe(false); + + property.color = undefined; + expect(property.isConstant).toBe(true); + property.outlineColor = new TimeIntervalCollectionProperty(); + property.outlineColor.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + expect(property.isConstant).toBe(false); + + property.outlineColor = undefined; + expect(property.isConstant).toBe(true); + property.outlineWidth = new TimeIntervalCollectionProperty(); + property.outlineWidth.intervals.addInterval(new TimeInterval(start, stop, true, true, 2.0)); + expect(property.isConstant).toBe(false); + }); +}); \ No newline at end of file From b65c741623406a69d7355c5294df4b805566a346 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 27 Jan 2014 21:26:57 -0500 Subject: [PATCH 05/81] Minor doc update. --- Source/DataSource/ColorMaterialProperty.js | 2 +- Source/DataSource/CompositeMaterialProperty.js | 3 ++- Source/DataSource/CompositePositionProperty.js | 3 ++- Source/DataSource/CompositeProperty.js | 3 ++- Source/DataSource/ConstantPositionProperty.js | 2 +- Source/DataSource/GridMaterialProperty.js | 2 +- Source/DataSource/ImageMaterialProperty.js | 2 +- Source/DataSource/MaterialProperty.js | 2 +- Source/DataSource/PolylineOutlineMaterialProperty.js | 2 +- Source/DataSource/PositionProperty.js | 2 +- Source/DataSource/Property.js | 2 +- Source/DataSource/SampledPositionProperty.js | 2 +- Source/DataSource/SampledProperty.js | 2 +- Source/DataSource/TimeIntervalCollectionPositionProperty.js | 2 +- Source/DataSource/TimeIntervalCollectionProperty.js | 3 ++- 15 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/DataSource/ColorMaterialProperty.js b/Source/DataSource/ColorMaterialProperty.js index e5ba98f9daee..adca27bc069f 100644 --- a/Source/DataSource/ColorMaterialProperty.js +++ b/Source/DataSource/ColorMaterialProperty.js @@ -28,7 +28,7 @@ define(['../Core/Color', defineProperties(ColorMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof ColorMaterialProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/CompositeMaterialProperty.js b/Source/DataSource/CompositeMaterialProperty.js index ede417155b95..5670ff18f5b9 100644 --- a/Source/DataSource/CompositeMaterialProperty.js +++ b/Source/DataSource/CompositeMaterialProperty.js @@ -30,7 +30,8 @@ define(['../Core/defined', defineProperties(CompositeMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. * @memberof CompositeMaterialProperty.prototype * @type {Boolean} */ diff --git a/Source/DataSource/CompositePositionProperty.js b/Source/DataSource/CompositePositionProperty.js index 0258f49c4ae4..9ff47061d6ab 100644 --- a/Source/DataSource/CompositePositionProperty.js +++ b/Source/DataSource/CompositePositionProperty.js @@ -35,7 +35,8 @@ define(['../Core/defaultValue', defineProperties(CompositePositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. * @memberof CompositePositionProperty.prototype * @type {Boolean} */ diff --git a/Source/DataSource/CompositeProperty.js b/Source/DataSource/CompositeProperty.js index 5c5281285d89..47e22fd45e81 100644 --- a/Source/DataSource/CompositeProperty.js +++ b/Source/DataSource/CompositeProperty.js @@ -79,7 +79,8 @@ define(['./Property', defineProperties(CompositeProperty.prototype, { /** - * Gets a value indicating if this property is constant. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. * @memberof CompositeProperty.prototype * @type {Boolean} */ diff --git a/Source/DataSource/ConstantPositionProperty.js b/Source/DataSource/ConstantPositionProperty.js index ff2f74412afc..8e88b49da1c9 100644 --- a/Source/DataSource/ConstantPositionProperty.js +++ b/Source/DataSource/ConstantPositionProperty.js @@ -38,7 +38,7 @@ define(['./PositionProperty', defineProperties(ConstantPositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof PositionProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/GridMaterialProperty.js b/Source/DataSource/GridMaterialProperty.js index 44bb03791ed7..c7b4fc1b3f05 100644 --- a/Source/DataSource/GridMaterialProperty.js +++ b/Source/DataSource/GridMaterialProperty.js @@ -40,7 +40,7 @@ define(['../Core/Cartesian2', defineProperties(GridMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof GridMaterialProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/ImageMaterialProperty.js b/Source/DataSource/ImageMaterialProperty.js index d31884a5af05..a67febcdb35e 100644 --- a/Source/DataSource/ImageMaterialProperty.js +++ b/Source/DataSource/ImageMaterialProperty.js @@ -31,7 +31,7 @@ define([ defineProperties(ImageMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof ImageMaterialProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/MaterialProperty.js b/Source/DataSource/MaterialProperty.js index 64053a0f3e70..d8f76a1166a1 100644 --- a/Source/DataSource/MaterialProperty.js +++ b/Source/DataSource/MaterialProperty.js @@ -28,7 +28,7 @@ define(['../Core/defined', defineProperties(MaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof MaterialProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/PolylineOutlineMaterialProperty.js b/Source/DataSource/PolylineOutlineMaterialProperty.js index 8ddf10f2297c..c4a62747c3ea 100644 --- a/Source/DataSource/PolylineOutlineMaterialProperty.js +++ b/Source/DataSource/PolylineOutlineMaterialProperty.js @@ -34,7 +34,7 @@ define(['../Core/Color', defineProperties(PolylineOutlineMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof PolylineOutlineMaterialProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/PositionProperty.js b/Source/DataSource/PositionProperty.js index 429c4648973c..566fd7f9b412 100644 --- a/Source/DataSource/PositionProperty.js +++ b/Source/DataSource/PositionProperty.js @@ -35,7 +35,7 @@ define(['../Core/Cartesian3', defineProperties(PositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof PositionProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/Property.js b/Source/DataSource/Property.js index 9a7333d0293f..dcde7be20682 100644 --- a/Source/DataSource/Property.js +++ b/Source/DataSource/Property.js @@ -29,7 +29,7 @@ define(['../Core/defined', defineProperties(Property.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof Property.prototype * @type {Boolean} diff --git a/Source/DataSource/SampledPositionProperty.js b/Source/DataSource/SampledPositionProperty.js index 5418779e66e7..dd5d72e7e9f2 100644 --- a/Source/DataSource/SampledPositionProperty.js +++ b/Source/DataSource/SampledPositionProperty.js @@ -42,7 +42,7 @@ define(['./PositionProperty', defineProperties(SampledPositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof SampledPositionProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/SampledProperty.js b/Source/DataSource/SampledProperty.js index b082b133e9dd..a2a259e1d208 100644 --- a/Source/DataSource/SampledProperty.js +++ b/Source/DataSource/SampledProperty.js @@ -194,7 +194,7 @@ define(['../Core/binarySearch', defineProperties(SampledProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof SampledProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/TimeIntervalCollectionPositionProperty.js b/Source/DataSource/TimeIntervalCollectionPositionProperty.js index 40c2eb1c3aa9..49b6f152b4fb 100644 --- a/Source/DataSource/TimeIntervalCollectionPositionProperty.js +++ b/Source/DataSource/TimeIntervalCollectionPositionProperty.js @@ -51,7 +51,7 @@ define(['./PositionProperty', defineProperties(TimeIntervalCollectionPositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. A value is considered + * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof TimeIntervalCollectionPositionProperty.prototype * @type {Boolean} diff --git a/Source/DataSource/TimeIntervalCollectionProperty.js b/Source/DataSource/TimeIntervalCollectionProperty.js index 2d6765962749..fb80c7a13627 100644 --- a/Source/DataSource/TimeIntervalCollectionProperty.js +++ b/Source/DataSource/TimeIntervalCollectionProperty.js @@ -75,7 +75,8 @@ define(['./Property', defineProperties(TimeIntervalCollectionProperty.prototype, { /** - * Gets a value indicating if this property is constant. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. * @memberof TimeIntervalCollectionProperty.prototype * @type {Boolean} */ From fb5f5622a85dc14d1c45e22878ecbb2e4eaf5179 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 28 Jan 2014 07:27:58 -0500 Subject: [PATCH 06/81] Move properties back into DynamicScene for now. --- Source/DataSource/ColorMaterialProperty.js | 130 ----- .../DataSource/CompositeMaterialProperty.js | 128 ----- .../DataSource/CompositePositionProperty.js | 149 ----- Source/DataSource/CompositeProperty.js | 156 ------ Source/DataSource/ConstantPositionProperty.js | 154 ----- Source/DataSource/ConstantProperty.js | 123 ---- Source/DataSource/GridMaterialProperty.js | 220 -------- Source/DataSource/ImageMaterialProperty.js | 159 ------ Source/DataSource/MaterialProperty.js | 101 ---- .../PolylineOutlineMaterialProperty.js | 189 ------- Source/DataSource/PositionProperty.js | 131 ----- Source/DataSource/Property.js | 83 --- Source/DataSource/SampledPositionProperty.js | 218 -------- Source/DataSource/SampledProperty.js | 528 ------------------ .../TimeIntervalCollectionPositionProperty.js | 158 ------ .../TimeIntervalCollectionProperty.js | 153 ----- Source/DynamicScene/ColorMaterialProperty.js | 72 ++- .../DynamicScene/CompositeMaterialProperty.js | 46 +- .../DynamicScene/CompositePositionProperty.js | 44 +- Source/DynamicScene/CompositeProperty.js | 68 ++- .../DynamicScene/ConstantPositionProperty.js | 77 ++- Source/DynamicScene/ConstantProperty.js | 114 ++-- Source/DynamicScene/CzmlDataSource.js | 10 +- Source/DynamicScene/GridMaterialProperty.js | 157 +++++- Source/DynamicScene/ImageMaterialProperty.js | 93 ++- Source/DynamicScene/MaterialProperty.js | 43 +- .../PolylineOutlineMaterialProperty.js | 125 ++++- Source/DynamicScene/PositionProperty.js | 49 +- Source/DynamicScene/Property.js | 41 +- .../DynamicScene/SampledPositionProperty.js | 71 ++- Source/DynamicScene/SampledProperty.js | 92 ++- .../TimeIntervalCollectionPositionProperty.js | 52 +- .../TimeIntervalCollectionProperty.js | 74 ++- Specs/DataSource/ColorMaterialPropertySpec.js | 98 ---- .../CompositeMaterialPropertySpec.js | 138 ----- .../CompositePositionPropertySpec.js | 219 -------- Specs/DataSource/CompositePropertySpec.js | 125 ----- .../ConstantPositionPropertySpec.js | 130 ----- Specs/DataSource/ConstantPropertySpec.js | 97 ---- Specs/DataSource/GridMaterialPropertySpec.js | 225 -------- Specs/DataSource/ImageMaterialPropertySpec.js | 147 ----- .../PolylineOutlineMaterialPropertySpec.js | 170 ------ .../DataSource/SampledPositionPropertySpec.js | 263 --------- Specs/DataSource/SampledPropertySpec.js | 371 ------------ ...eIntervalCollectionPositionPropertySpec.js | 180 ------ .../TimeIntervalCollectionPropertySpec.js | 128 ----- .../DynamicScene/ColorMaterialPropertySpec.js | 32 +- .../CompositeMaterialPropertySpec.js | 51 +- .../CompositePositionPropertySpec.js | 47 +- Specs/DynamicScene/CompositePropertySpec.js | 47 +- .../ConstantPositionPropertySpec.js | 43 +- Specs/DynamicScene/ConstantPropertySpec.js | 28 +- .../DynamicScene/GridMaterialPropertySpec.js | 106 +++- .../DynamicScene/ImageMaterialPropertySpec.js | 64 ++- .../PolylineOutlineMaterialPropertySpec.js | 85 ++- .../SampledPositionPropertySpec.js | 35 +- Specs/DynamicScene/SampledPropertySpec.js | 65 ++- ...eIntervalCollectionPositionPropertySpec.js | 22 +- .../TimeIntervalCollectionPropertySpec.js | 24 +- 59 files changed, 1559 insertions(+), 5389 deletions(-) delete mode 100644 Source/DataSource/ColorMaterialProperty.js delete mode 100644 Source/DataSource/CompositeMaterialProperty.js delete mode 100644 Source/DataSource/CompositePositionProperty.js delete mode 100644 Source/DataSource/CompositeProperty.js delete mode 100644 Source/DataSource/ConstantPositionProperty.js delete mode 100644 Source/DataSource/ConstantProperty.js delete mode 100644 Source/DataSource/GridMaterialProperty.js delete mode 100644 Source/DataSource/ImageMaterialProperty.js delete mode 100644 Source/DataSource/MaterialProperty.js delete mode 100644 Source/DataSource/PolylineOutlineMaterialProperty.js delete mode 100644 Source/DataSource/PositionProperty.js delete mode 100644 Source/DataSource/Property.js delete mode 100644 Source/DataSource/SampledPositionProperty.js delete mode 100644 Source/DataSource/SampledProperty.js delete mode 100644 Source/DataSource/TimeIntervalCollectionPositionProperty.js delete mode 100644 Source/DataSource/TimeIntervalCollectionProperty.js delete mode 100644 Specs/DataSource/ColorMaterialPropertySpec.js delete mode 100644 Specs/DataSource/CompositeMaterialPropertySpec.js delete mode 100644 Specs/DataSource/CompositePositionPropertySpec.js delete mode 100644 Specs/DataSource/CompositePropertySpec.js delete mode 100644 Specs/DataSource/ConstantPositionPropertySpec.js delete mode 100644 Specs/DataSource/ConstantPropertySpec.js delete mode 100644 Specs/DataSource/GridMaterialPropertySpec.js delete mode 100644 Specs/DataSource/ImageMaterialPropertySpec.js delete mode 100644 Specs/DataSource/PolylineOutlineMaterialPropertySpec.js delete mode 100644 Specs/DataSource/SampledPositionPropertySpec.js delete mode 100644 Specs/DataSource/SampledPropertySpec.js delete mode 100644 Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js delete mode 100644 Specs/DataSource/TimeIntervalCollectionPropertySpec.js diff --git a/Source/DataSource/ColorMaterialProperty.js b/Source/DataSource/ColorMaterialProperty.js deleted file mode 100644 index adca27bc069f..000000000000 --- a/Source/DataSource/ColorMaterialProperty.js +++ /dev/null @@ -1,130 +0,0 @@ -/*global define*/ -define(['../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './ConstantProperty', - './Property' - ], function( - Color, - defined, - defineProperties, - Event, - ConstantProperty, - Property) { - "use strict"; - - /** - * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. - * @alias ColorMaterialProperty - * @constructor - */ - var ColorMaterialProperty = function() { - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this.color = new ConstantProperty(Color.WHITE); - }; - - defineProperties(ColorMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof ColorMaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return !defined(this._color) || this._color.isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof ColorMaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * A {@link Color} {@link Property} which determines the material's color. - * @memberof ColorMaterialProperty.prototype - * @type {Property} - * @default new ConstantProperty(Color.WHITE) - */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (this._colorSubscription) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(ColorMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof ColorMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - ColorMaterialProperty.prototype.getType = function(time) { - return 'Color'; - }; - - /** - * Gets the value of the property at the provided time. - * @memberof ColorMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - ColorMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; - return result; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof ColorMaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - ColorMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof ColorMaterialProperty && // - Property.equals(this._color, other._color)); - }; - - /** - * @private - */ - ColorMaterialProperty.prototype._raiseDefinitionChanged = function(){ - this._definitionChanged.raiseEvent(this); - }; - - return ColorMaterialProperty; -}); diff --git a/Source/DataSource/CompositeMaterialProperty.js b/Source/DataSource/CompositeMaterialProperty.js deleted file mode 100644 index 5670ff18f5b9..000000000000 --- a/Source/DataSource/CompositeMaterialProperty.js +++ /dev/null @@ -1,128 +0,0 @@ -/*global define*/ -define(['../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './CompositeProperty', - './Property' - ], function( - defined, - defineProperties, - DeveloperError, - Event, - CompositeProperty, - Property) { - "use strict"; - - /** - * A {@link CompositeProperty} which is also a {@link MaterialProperty}. - * - * @alias CompositeMaterialProperty - * @constructor - */ - var CompositeMaterialProperty = function() { - this._definitionChanged = new Event(); - this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); - }; - - defineProperties(CompositeMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositeMaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._composite.isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositeMaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the interval collection. - * @memberof CompositeMaterialProperty.prototype - * - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._composite._intervals; - } - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof CompositeMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - CompositeMaterialProperty.prototype.getType = function(time) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - //>>includeEnd('debug'); - - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getType(time); - } - return undefined; - }; - - /** - * Gets the value of the property at the provided time. - * @memberof CompositeMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - CompositeMaterialProperty.prototype.getValue = function(time, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - //>>includeEnd('debug'); - - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValue(time, result); - } - return undefined; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof CompositeMaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - CompositeMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositeMaterialProperty && // - this._composite.equals(other._composite, Property.equals)); - }; - - return CompositeMaterialProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/CompositePositionProperty.js b/Source/DataSource/CompositePositionProperty.js deleted file mode 100644 index 9ff47061d6ab..000000000000 --- a/Source/DataSource/CompositePositionProperty.js +++ /dev/null @@ -1,149 +0,0 @@ -/*global define*/ -define(['../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - './CompositeProperty', - './Property' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - CompositeProperty, - Property) { - "use strict"; - - /** - * A {@link CompositeProperty} which is also a {@link PositionProperty}. - * - * @alias CompositePositionProperty - * @constructor - */ - var CompositePositionProperty = function(referenceFrame) { - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - this._definitionChanged = new Event(); - this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); - }; - - defineProperties(CompositePositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositePositionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._composite.isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositePositionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the interval collection. - * @memberof CompositePositionProperty.prototype - * - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._composite.intervals; - } - }, - /** - * Gets or sets the reference frame which this position presents itself as. - * Each PositionProperty making up this object has it's own reference frame, - * so this property merely exposes a "preferred" reference frame for clients - * to use. - * @memberof CompositePositionProperty.prototype - * - * @Type {ReferenceFrame} The preferred reference frame. - */ - referenceFrame : { - get : function() { - return this._referenceFrame; - }, - set : function(value) { - this._referenceFrame = value; - } - } - }); - - /** - * Gets the value of the property at the provided time in the fixed frame. - * @memberof CompositePositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - CompositePositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; - - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @memberof CompositePositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. - */ - CompositePositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - //>>includeEnd('debug'); - - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValueInReferenceFrame(time, referenceFrame, result); - } - return undefined; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof CompositePositionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - CompositePositionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositePositionProperty && // - this._referenceFrame === other._referenceFrame && // - this._composite.equals(other._composite, Property.equals)); - }; - - return CompositePositionProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/CompositeProperty.js b/Source/DataSource/CompositeProperty.js deleted file mode 100644 index 47e22fd45e81..000000000000 --- a/Source/DataSource/CompositeProperty.js +++ /dev/null @@ -1,156 +0,0 @@ -/*global define*/ -define(['./Property', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/EventHelper', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' - ], function( - Property, - defined, - defineProperties, - DeveloperError, - Event, - EventHelper, - TimeIntervalCollection, - wrapFunction) { - "use strict"; - - function subscribeAll(property, eventHelper, definitionChanged, intervals) { - var callback = function() { - definitionChanged.raiseEvent(property); - }; - - var items = []; - eventHelper.removeAll(); - var length = intervals.getLength(); - for (var i = 0; i < length; i++) { - var interval = intervals.get(i); - if (defined(interval.data) && items.indexOf(interval.data) === -1) { - eventHelper.add(interval.data.definitionChanged, callback); - } - } - } - - /** - * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the - * data property of each {@link TimeInterval} is another Property instance which is - * evaluated at the provided time. - * - * @alias CompositeProperty - * @constructor - * - * @see CompositeMaterialProperty - * @see CompositePositionProperty - * - * @example - * var constantProperty = ...; - * var sampledProperty = ...; - * - * //Create a composite property from two previously defined properties - * //where the property is valid on August 1st, 2012 and uses a constant - * //property for the first half of the day and a sampled property for the - * //remaining half. - * var composite = new Cesium.CompositeProperty(); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T12:00:00.00Z', true, true, constantProperty)); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', false, false, sampledProperty)); - */ - var CompositeProperty = function() { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var eventHelper = new EventHelper(); - var intervalsChanged = function() { - subscribeAll(that, eventHelper, definitionChanged, intervals); - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, intervalsChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, intervalsChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, intervalsChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; - }; - - defineProperties(CompositeProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositeProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._intervals.isEmpty(); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositeProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the interval collection. - * @memberof CompositeProperty.prototype - * - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._intervals; - } - } - }); - - /** - * Gets the value of the property at the provided time. - * @memberof CompositeProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - CompositeProperty.prototype.getValue = function(time, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - //>>includeEnd('debug'); - - var innerProperty = this._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValue(time, result); - } - return undefined; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof CompositeProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - CompositeProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositeProperty && // - this._intervals.equals(other._intervals, Property.equals)); - }; - - return CompositeProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/ConstantPositionProperty.js b/Source/DataSource/ConstantPositionProperty.js deleted file mode 100644 index 8e88b49da1c9..000000000000 --- a/Source/DataSource/ConstantPositionProperty.js +++ /dev/null @@ -1,154 +0,0 @@ -/*global define*/ -define(['./PositionProperty', - './Property', - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame' - ], function( - PositionProperty, - Property, - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame) { - "use strict"; - - /** - * A {@link PositionProperty} whose value does not change in respect to the - * {@link ReferenceFrame} in which is it defined. - * - * @alias ConstantPositionProperty - * @constructor - * - * @param {Cartesian3} [value] The property value. - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - var ConstantPositionProperty = function(value, referenceFrame) { - this._definitionChanged = new Event(); - this._value = Cartesian3.clone(value); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - }; - - defineProperties(ConstantPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PositionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return !defined(this._value) || this._referenceFrame === ReferenceFrame.FIXED; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PositionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof ConstantPositionProperty.prototype - * @Type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; - } - } - }); - - /** - * Gets the value of the property at the provided time in the fixed frame. - * @memberof ConstantPositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - ConstantPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; - - /** - * Sets the value of the property. - * If the value is an object, the object must provide clone and equals functions. - * @memberof ConstantPositionProperty - * - * @param {Cartesian3} value The property value. - * @param {ReferenceFrame} [referenceFrame=this.referenceFrame] The reference frame in which the position is defined. - */ - ConstantPositionProperty.prototype.setValue = function(value, referenceFrame) { - var definitionChanged = false; - if (!Cartesian3.equals(this._value, value)) { - definitionChanged = true; - this._value = Cartesian3.clone(value); - } - if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { - definitionChanged = true; - this._referenceFrame = defaultValue(this._referenceFrame, referenceFrame); - } - if (definitionChanged) { - this._definitionChanged.raiseEvent(this); - } - }; - - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @memberof ConstantPositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. - */ - ConstantPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - //>>includeEnd('debug'); - - return PositionProperty.convertToReferenceFrame(time, this._value, this._referenceFrame, referenceFrame, result); - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof ConstantPositionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - ConstantPositionProperty.prototype.equals = function(other) { - return this === other || - (other instanceof ConstantPositionProperty && - Cartesian3.equals(this._value, other._value) && - this._referenceFrame === other._referenceFrame); - }; - - return ConstantPositionProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/ConstantProperty.js b/Source/DataSource/ConstantProperty.js deleted file mode 100644 index 8abfc5e8c9d3..000000000000 --- a/Source/DataSource/ConstantProperty.js +++ /dev/null @@ -1,123 +0,0 @@ -/*global define*/ -define(['../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Enumeration', - '../Core/Event' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Enumeration, - Event) { - "use strict"; - - /** - * A {@link Property} whose value does not change with respect to simulation time. - * If the value is an object, the object must provide clone and equals functions. - * - * @alias ConstantProperty - * @constructor - * - * @param {Object|Number|String|Boolean} [value] The property value. - * - * @exception {DeveloperError} value.clone is a required function. - * @exception {DeveloperError} value.equals is a required function. - */ - var ConstantProperty = function(value) { - this._value = undefined; - this._simple = true; - this._definitionChanged = new Event(); - this.setValue(value); - }; - - defineProperties(ConstantProperty.prototype, { - /** - * Gets a value indicating if this property is constant. - * This property always returns true. - * @memberof ConstantProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return true; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof ConstantProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - } - }); - - /** - * Gets the value of the property. - * @memberof ConstantProperty - * - * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ConstantProperty.prototype.getValue = function(time, result) { - return this._simple ? this._value : this._value.clone(result); - }; - - /** - * Sets the value of the property. - * If the value is an object, the object must provide clone and equals functions. - * @memberof ConstantProperty - * - * @param {Object|Number|String|Boolean} value The property value. - * - * @exception {DeveloperError} value.clone is a required function. - * @exception {DeveloperError} value.equals is a required function. - */ - ConstantProperty.prototype.setValue = function(value) { - var oldValue = this._value; - var simple = this._simple; - if ((simple && oldValue !== value) || (!simple && !oldValue.equals(value))) { - simple = typeof value !== 'object' || Array.isArray(value) || value instanceof Enumeration; - - //>>includeStart('debug', pragmas.debug); - if (!simple) { - if (typeof value.clone !== 'function') { - throw new DeveloperError('clone is a required function.'); - } - if (typeof value.equals !== 'function') { - throw new DeveloperError('equals is a required function.'); - } - } - //>>includeEnd('debug'); - - this._value = simple ? value : value.clone(); - this._simple = simple; - this._definitionChanged.raiseEvent(this); - } - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof ConstantProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - ConstantProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof ConstantProperty && // - ((this._simple && (this._value === other._value)) || // - (!this._simple && this._value.equals(other._value)))); - }; - - return ConstantProperty; -}); diff --git a/Source/DataSource/GridMaterialProperty.js b/Source/DataSource/GridMaterialProperty.js deleted file mode 100644 index c7b4fc1b3f05..000000000000 --- a/Source/DataSource/GridMaterialProperty.js +++ /dev/null @@ -1,220 +0,0 @@ -/*global define*/ -define(['../Core/Cartesian2', - '../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './ConstantProperty', - './Property' - ], function( - Cartesian2, - Color, - defined, - defineProperties, - Event, - ConstantProperty, - Property) { - "use strict"; - - /** - * A {@link MaterialProperty} that maps to grid {@link Material} uniforms. - * @alias GridMaterialProperty - * @constructor - */ - var GridMaterialProperty = function() { - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._cellAlpha = undefined; - this._cellAlphaSubscription = undefined; - this._lineCount = undefined; - this._lineCountSubscription = undefined; - this._lineThickness = undefined; - this._lineThicknessSubscription = undefined; - - this.color = new ConstantProperty(Color.WHITE); - this.cellAlpha = new ConstantProperty(0.1); - this.lineCount = new ConstantProperty(new Cartesian2(8, 8)); - this.lineThickness = new ConstantProperty(new Cartesian2(1.0, 1.0)); - }; - - defineProperties(GridMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof GridMaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return (!defined(this._color) || this._color.isConstant) && // - (!defined(this._cellAlpha) || this._cellAlpha.isConstant) && // - (!defined(this._lineCount) || this._lineCount.isConstant) && // - (!defined(this._lineThickness) || this._lineThickness.isConstant); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof GridMaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * A {@link Color} {@link Property} which determines the grid's color. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default new ConstantProperty(Color.WHITE) - */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (this._colorSubscription) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A numeric {@link Property} which determines the grid cells alpha value, when combined with the color alpha. - * @type {Property} - * @default new ConstantProperty(0.1) - */ - cellAlpha : { - get : function() { - return this._cellAlpha; - }, - set : function(value) { - if (this._cellAlpha !== value) { - if (this._cellAlphaSubscription) { - this._cellAlphaSubscription(); - this._cellAlphaSubscription = undefined; - } - this._cellAlpha = value; - if (defined(value)) { - this._cellAlphaSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A {@link Cartesian2} {@link Property} which determines the number of rows and columns in the grid. - * @type {Property} - * @default new ConstantProperty(new Cartesian2(8, 8)) - */ - lineCount : { - get : function() { - return this._lineCount; - }, - set : function(value) { - if (this._lineCount !== value) { - if (this._lineCountSubscription) { - this._lineCountSubscription(); - this._lineCountSubscription = undefined; - } - this._lineCount = value; - if (defined(value)) { - this._lineCountSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A {@link Cartesian2} {@link Property} which determines the thickness of rows and columns in the grid. - * @type {Property} - * @default new ConstantProperty(new Cartesian2(1.0, 1.0)) - */ - lineThickness : { - get : function() { - return this._lineThickness; - }, - set : function(value) { - if (this._lineThickness !== value) { - if (this._lineThicknessSubscription) { - this._lineThicknessSubscription(); - this._lineThicknessSubscription = undefined; - } - this._lineThickness = value; - if (defined(value)) { - this._lineThicknessSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof GridMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - GridMaterialProperty.prototype.getType = function(time) { - return 'Grid'; - }; - - /** - * Gets the value of the property at the provided time. - * @memberof GridMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - GridMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; - result.cellAlpha = defined(this._cellAlpha) ? this._cellAlpha.getValue(time) : undefined; - result.lineCount = defined(this._lineCount) ? this._lineCount.getValue(time, result.lineCount) : undefined; - result.lineThickness = defined(this._lineThickness) ? this._lineThickness.getValue(time, result.lineThickness) : undefined; - return result; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof GridMaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - GridMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof GridMaterialProperty && // - Property.equals(this._color, other._color) && // - Property.equals(this._cellAlpha, other._cellAlpha) && // - Property.equals(this._lineCount, other._lineCount) && // - Property.equals(this._lineThickness, other._lineThickness)); - }; - - /** - * @private - */ - GridMaterialProperty.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); - }; - - return GridMaterialProperty; -}); diff --git a/Source/DataSource/ImageMaterialProperty.js b/Source/DataSource/ImageMaterialProperty.js deleted file mode 100644 index a67febcdb35e..000000000000 --- a/Source/DataSource/ImageMaterialProperty.js +++ /dev/null @@ -1,159 +0,0 @@ -/*global define*/ -define([ - '../Core/Cartesian2', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './ConstantProperty', - './Property' - ], function( - Cartesian2, - defined, - defineProperties, - Event, - ConstantProperty, - Property) { - "use strict"; - - /** - * A {@link MaterialProperty} that maps to image {@link Material} uniforms. - * @alias ImageMaterialProperty - * @constructor - */ - var ImageMaterialProperty = function() { - this._definitionChanged = new Event(); - this._image = undefined; - this._imageSubscription = undefined; - this._repeat = undefined; - this._repeatSubscription = undefined; - this.repeat = new ConstantProperty(new Cartesian2(1, 1)); - }; - - defineProperties(ImageMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof ImageMaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return (!defined(this._image) || this._image.isConstant) && (!defined(this._repeat) || this._repeat.isConstant); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof ImageMaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * A string {@link Property} which is the url of the desired image. - * @memberof ImageMaterialProperty.prototype - * @type {Property} - */ - image : { - get : function() { - return this._image; - }, - set : function(value) { - if (this._image !== value) { - if (this._imageSubscription) { - this._imageSubscription(); - this._imageSubscription = undefined; - } - this._image = value; - if (defined(value)) { - this._imageSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A {@link Cartesian2} {@link Property} which determines the number of times the image repeats in each direction. - * @memberof ImageMaterialProperty.prototype - * @type {Property} - * @default new ConstantProperty(new Cartesian2(1, 1)) - */ - repeat : { - get : function() { - return this._repeat; - }, - set : function(value) { - if (this._repeat !== value) { - if (this._repeatSubscription) { - this._repeatSubscription(); - this._repeatSubscription = undefined; - } - this._repeat = value; - if (defined(value)) { - this._repeatSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof ImageMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - ImageMaterialProperty.prototype.getType = function(time) { - return 'Image'; - }; - - /** - * Gets the value of the property at the provided time. - * @memberof ImageMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - ImageMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - - result.image = defined(this._image) ? this._image.getValue(time) : undefined; - result.repeat = defined(this._repeat) ? this._repeat.getValue(time, result.repeat) : undefined; - return result; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof ImageMaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - ImageMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof ImageMaterialProperty && // - Property.equals(this._image, other._image) && // - Property.equals(this._repeat, other._repeat)); - }; - - /** - * @private - */ - ImageMaterialProperty.prototype._raiseDefinitionChanged = function(){ - this._definitionChanged.raiseEvent(this); - }; - - return ImageMaterialProperty; -}); diff --git a/Source/DataSource/MaterialProperty.js b/Source/DataSource/MaterialProperty.js deleted file mode 100644 index d8f76a1166a1..000000000000 --- a/Source/DataSource/MaterialProperty.js +++ /dev/null @@ -1,101 +0,0 @@ -/*global define*/ -define(['../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Scene/Material' - ], function( - defined, - defineProperties, - DeveloperError, - Material) { - "use strict"; - - /** - * The interface for all {@link MaterialProperty} objects that represent {@link Material} uniforms. - * This type defines an interface and cannot be instantiated directly. - * - * @alias MaterialProperty - * @constructor - * - * @see ColorMaterialProperty - * @see CompositeMaterialProperty - * @see GridMaterialProperty - * @see ImageMaterialProperty - */ - var MaterialProperty = function() { - DeveloperError.throwInstantiationError(); - }; - - defineProperties(MaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof MaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof MaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof MaterialProperty - * @function - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; - - /** - * Gets the value of the property at the provided time. - * @memberof MaterialProperty - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof MaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; - - /** - * @private - */ - MaterialProperty.getValue = function(time, materialProperty, material) { - if (defined(materialProperty)) { - var type = materialProperty.getType(time); - if (defined(type)) { - if (!defined(material) || (material.type !== type)) { - material = Material.fromType(type); - } - materialProperty.getValue(time, material.uniforms); - } - } - return material; - }; - - return MaterialProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/PolylineOutlineMaterialProperty.js b/Source/DataSource/PolylineOutlineMaterialProperty.js deleted file mode 100644 index c4a62747c3ea..000000000000 --- a/Source/DataSource/PolylineOutlineMaterialProperty.js +++ /dev/null @@ -1,189 +0,0 @@ -/*global define*/ -define(['../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './ConstantProperty', - './Property' - ], function( - Color, - defined, - defineProperties, - Event, - ConstantProperty, - Property) { - "use strict"; - - /** - * A {@link MaterialProperty} that maps to polyline outline {@link Material} uniforms. - * @alias PolylineOutlineMaterialProperty - * @constructor - */ - var PolylineOutlineMaterialProperty = function() { - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this.color = new ConstantProperty(Color.WHITE); - this.outlineColor = new ConstantProperty(Color.BLACK); - this.outlineWidth = new ConstantProperty(0.0); - }; - - defineProperties(PolylineOutlineMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return (!defined(this._color) || this._color.isConstant) && - (!defined(this._outlineColor) || this._outlineColor.isConstant) && - (!defined(this._outlineWidth) || this._outlineWidth.isConstant); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * A {@link Color} {@link Property} which determines the polyline's color. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Property} - * @default new ConstantProperty(Color.WHITE) - */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (this._colorSubscription) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A {@link Color} {@link Property} which determines the polyline's outline color. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Property} - * @default new ConstantProperty(Color.BLACK) - */ - outlineColor : { - get : function() { - return this._outlineColor; - }, - set : function(value) { - if (this._outlineColor !== value) { - if (this._outlineColorSubscription) { - this._outlineColorSubscription(); - this._outlineColorSubscription = undefined; - } - this._outlineColor = value; - if (defined(value)) { - this._outlineColorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - /** - * A Number {@link Property} which determines the polyline's outline width. - * @type {Property} - * @default new ConstantProperty(0) - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - }, - set : function(value) { - if (this._outlineWidth !== value) { - if (this._outlineWidthSubscription) { - this._outlineWidthSubscription(); - this._outlineWidthSubscription = undefined; - } - this._outlineWidth = value; - if (defined(value)) { - this._outlineWidthSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @memberof PolylineOutlineMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the type. - * @type {String} The type of material. - */ - PolylineOutlineMaterialProperty.prototype.getType = function(time) { - return 'PolylineOutline'; - }; - - /** - * Gets the value of the property at the provided time. - * @memberof PolylineOutlineMaterialProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - PolylineOutlineMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; - result.outlineColor = defined(this._outlineColor) ? this._outlineColor.getValue(time, result.outlineColor) : undefined; - result.outlineWidth = defined(this._outlineWidth) ? this._outlineWidth.getValue(time) : undefined; - return result; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof PolylineOutlineMaterialProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - PolylineOutlineMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof PolylineOutlineMaterialProperty && // - Property.equals(this._color, other._color) && // - Property.equals(this._outlineColor, other._outlineColor) && // - Property.equals(this._outlineWidth, other._outlineWidth)); - }; - - /** - * @private - */ - PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged = function(){ - this._definitionChanged.raiseEvent(this); - }; - - return PolylineOutlineMaterialProperty; -}); diff --git a/Source/DataSource/PositionProperty.js b/Source/DataSource/PositionProperty.js deleted file mode 100644 index 566fd7f9b412..000000000000 --- a/Source/DataSource/PositionProperty.js +++ /dev/null @@ -1,131 +0,0 @@ -/*global define*/ -define(['../Core/Cartesian3', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Matrix3', - '../Core/ReferenceFrame', - '../Core/Transforms' - ], function( - Cartesian3, - defined, - defineProperties, - DeveloperError, - Matrix3, - ReferenceFrame, - Transforms) { - "use strict"; - - /** - * The interface for all {@link Property} objects that define a world - * location as a {@link Cartesian3} with an associated {@link ReferenceFrame}. - * This type defines an interface and cannot be instantiated directly. - * - * @alias PositionProperty - * @constructor - * - * @see CompositePositionProperty - * @see ConstantPositionProperty - * @see SampledPositionProperty - * @see TimeIntervalCollectionPositionProperty - */ - var PositionProperty = function(){ - DeveloperError.throwInstantiationError(); - }; - - defineProperties(PositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PositionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PositionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the reference frame that the position is defined in. - * @memberof PositionProperty.prototype - * @Type {ReferenceFrame} - */ - referenceFrame : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Gets the value of the property at the provided time in the fixed frame. - * @memberof PositionProperty - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - PositionProperty.prototype.getValue = DeveloperError.throwInstantiationError; - - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @memberof PositionProperty - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. - */ - PositionProperty.prototype.getValueInReferenceFrame = DeveloperError.throwInstantiationError; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof PositionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; - - var scratchMatrix3 = new Matrix3(); - - /** - * @private - */ - PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) { - if (!defined(value)) { - return value; - } - - if (inputFrame === outputFrame) { - return Cartesian3.clone(value, result); - } - - var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3); - if (!defined(icrfToFixed)) { - icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchMatrix3); - } - if (inputFrame === ReferenceFrame.INERTIAL) { - return Matrix3.multiplyByVector(icrfToFixed, value, result); - } - if (inputFrame === ReferenceFrame.FIXED) { - return Matrix3.multiplyByVector(Matrix3.transpose(icrfToFixed, scratchMatrix3), value, result); - } - }; - - return PositionProperty; -}); diff --git a/Source/DataSource/Property.js b/Source/DataSource/Property.js deleted file mode 100644 index dcde7be20682..000000000000 --- a/Source/DataSource/Property.js +++ /dev/null @@ -1,83 +0,0 @@ -/*global define*/ -define(['../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError' - ], function( - defined, - defineProperties, - DeveloperError) { - "use strict"; - - /** - * The interface for all properties, which represent a value that can optionally vary over time. - * This type defines an interface and cannot be instantiated directly. - * - * @alias Property - * @constructor - * - * @see CompositeProperty - * @see ConstantProperty - * @see SampledProperty - * @see TimeIntervalCollectionProperty - * @see MaterialProperty - * @see PositionProperty - * @see ReferenceProperty - */ - var Property = function() { - DeveloperError.throwInstantiationError(); - }; - - defineProperties(Property.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof Property.prototype - * @type {Boolean} - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof Property.prototype - * @type {Event} - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Gets the value of the property at the provided time. - * @memberof Property - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - Property.prototype.getValue = DeveloperError.throwInstantiationError; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof Property - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - Property.prototype.equals = DeveloperError.throwInstantiationError; - - /** - * @private - */ - Property.equals = function(left, right) { - return left === right || (defined(left) && left.equals(right)); - }; - - return Property; -}); \ No newline at end of file diff --git a/Source/DataSource/SampledPositionProperty.js b/Source/DataSource/SampledPositionProperty.js deleted file mode 100644 index dd5d72e7e9f2..000000000000 --- a/Source/DataSource/SampledPositionProperty.js +++ /dev/null @@ -1,218 +0,0 @@ -/*global define*/ -define(['./PositionProperty', - './Property', - './SampledProperty', - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame' - ], function( - PositionProperty, - Property, - SampledProperty, - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame) { - "use strict"; - - /** - * A {@link SampledProperty} which is also a {@link PositionProperty}. - * - * @alias SampledPositionProperty - * @constructor - * - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - var SampledPositionProperty = function(referenceFrame) { - this._property = new SampledProperty(Cartesian3); - this._definitionChanged = new Event(); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - - this._property._definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); - }; - - defineProperties(SampledPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof SampledPositionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._property.isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof SampledPositionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof SampledPositionProperty.prototype - * @Type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; - } - }, - /** - * Gets the degree of interpolation to perform when retrieving a value. - * @memberof SampledPositionProperty.prototype - * - * @type {Object} - * @default 1 - */ - interpolationDegree : { - get : function() { - return this._property.interpolationDegree; - } - }, - /** - * Gets the interpolation algorithm to use when retrieving a value. - * @memberof SampledPositionProperty.prototype - * - * @type {InterpolationAlgorithm} - * @default LinearApproximation - */ - interpolationAlgorithm : { - get : function() { - return this._property.interpolationAlgorithm; - } - } - }); - - /** - * Gets the value of the property at the provided time. - * @memberof SampledPositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - SampledPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; - - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @memberof SampledPositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. - */ - SampledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - //>>includeEnd('debug'); - - result = this._property.getValue(time, result); - if (defined(result)) { - return PositionProperty.convertToReferenceFrame(time, result, this._referenceFrame, referenceFrame, result); - } - return result; - }; - - /** - * Sets the algorithm and degree to use when interpolating a position. - * @memberof SampledPositionProperty - * - * @param {Object} options The options - * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - * - * @exception {DeveloperError} options is required. - */ - SampledPositionProperty.prototype.setInterpolationOptions = function(options) { - this._property.setInterpolationOptions(options); - }; - - /** - * Adds a new sample - * @memberof SampledPositionProperty - * - * @param {JulianDate} time The sample time. - * @param {Cartesian3} value The value at the provided time. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} value is required. - */ - SampledPositionProperty.prototype.addSample = function(time, value) { - this._property.addSample(time, value); - }; - - /** - * Adds an array of samples - * @memberof SampledPositionProperty - * - * @param {Array} times An array of JulianDate instances where each index is a sample time. - * @param {Array} values The array of Cartesian3 instances, where each value corresponds to the provided times index. - * - * @exception {DeveloperError} times is required. - * @exception {DeveloperError} values is required. - * @exception {DeveloperError} times and values must be the same length.. - */ - SampledPositionProperty.prototype.addSamples = function(times, values) { - this._property.addSamples(times, values); - }; - - /** - * Adds samples as a single packed array where each new sample is represented as a date, followed by the packed representation of the corresponding value. - * @memberof SampledPositionProperty - * - * @param {Array} packedSamples The array of packed samples. - * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. - * - * @exception {DeveloperError} packedSamples is required. - */ - SampledPositionProperty.prototype.addSamplesPackedArray = function(data, epoch) { - this._property.addSamplesPackedArray(data, epoch); - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof SampledPositionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - SampledPositionProperty.prototype.equals = function(other) { - return this === other || // - (Property.equals(this._property, other._property) && // - this._referenceFrame === other._referenceFrame); - }; - - return SampledPositionProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/SampledProperty.js b/Source/DataSource/SampledProperty.js deleted file mode 100644 index a2a259e1d208..000000000000 --- a/Source/DataSource/SampledProperty.js +++ /dev/null @@ -1,528 +0,0 @@ -/*global define*/ -define(['../Core/binarySearch', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/JulianDate', - '../Core/LinearApproximation' - ], function( - binarySearch, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - JulianDate, - LinearApproximation) { - "use strict"; - - var PackableNumber = { - packedLength : 1, - pack : function(value, array, startingIndex) { - startingIndex = defaultValue(startingIndex, 0); - array[startingIndex] = value; - }, - unpack : function(array, startingIndex, result) { - startingIndex = defaultValue(startingIndex, 0); - return array[startingIndex]; - } - }; - - //We can't use splice for inserting new elements because function apply can't handle - //a huge number of arguments. See https://code.google.com/p/chromium/issues/detail?id=56588 - function arrayInsert(array, startIndex, items) { - var i; - var arrayLength = array.length; - var itemsLength = items.length; - var newLength = arrayLength + itemsLength; - - array.length = newLength; - if (arrayLength !== startIndex) { - var q = arrayLength - 1; - for (i = newLength - 1; i >= startIndex; i--) { - array[i] = array[q--]; - } - } - - for (i = 0; i < itemsLength; i++) { - array[startIndex++] = items[i]; - } - } - - function convertDate(date, epoch) { - if (date instanceof JulianDate) { - return date; - } - if (typeof date === 'string') { - return JulianDate.fromIso8601(date); - } - return epoch.addSeconds(date); - } - - var timesSpliceArgs = []; - var valuesSpliceArgs = []; - - var mergeNewSamples = function(epoch, times, values, newData, packedLength) { - var newDataIndex = 0; - var i; - var prevItem; - var timesInsertionPoint; - var valuesInsertionPoint; - var currentTime; - var nextTime; - - while (newDataIndex < newData.length) { - currentTime = convertDate(newData[newDataIndex], epoch); - timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare); - var timesSpliceArgsCount = 0; - var valuesSpliceArgsCount = 0; - - if (timesInsertionPoint < 0) { - //Doesn't exist, insert as many additional values as we can. - timesInsertionPoint = ~timesInsertionPoint; - - valuesInsertionPoint = timesInsertionPoint * packedLength; - prevItem = undefined; - nextTime = times[timesInsertionPoint]; - while (newDataIndex < newData.length) { - currentTime = convertDate(newData[newDataIndex], epoch); - if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) { - break; - } - timesSpliceArgs[timesSpliceArgsCount++] = currentTime; - newDataIndex = newDataIndex + 1; - for (i = 0; i < packedLength; i++) { - valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex]; - newDataIndex = newDataIndex + 1; - } - prevItem = currentTime; - } - - if (timesSpliceArgsCount > 0) { - valuesSpliceArgs.length = valuesSpliceArgsCount; - arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs); - - timesSpliceArgs.length = timesSpliceArgsCount; - arrayInsert(times, timesInsertionPoint, timesSpliceArgs); - } - } else { - //Found an exact match - for (i = 0; i < packedLength; i++) { - newDataIndex++; - values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex]; - } - newDataIndex++; - } - } - }; - - /** - * A {@link Property} whose value is interpolated for a given time from the - * provided set of samples and specified interpolation algorithm and degree. - * @alias SampledProperty - * @constructor - * - * @param {Number|Object} type The type of property, which must be a Number or implement {@link Packable}. - * - * @exception {DeveloperError} type is required. - * - * @see SampledPositionProperty - * - * @example - * //Create a linearly interpolated Cartesian2 - * var property = new Cesium.SampledProperty(Cesium.Cartesian2); - * property.interpolationDegree = 1; - * property.interpolationAlgorithm = LinearApproximation; - * - * //Populate it with data - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:00.00Z`), new Cesium.Cartesian2(0, 0)); - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-02T00:00:00.00Z`), new Cesium.Cartesian2(4, 7)); - * - * //Retrieve an interpolated value - * var result = property.getValue(Cesium.JulianDate.fromIso8601(`2012-08-01T12:00:00.00Z`)); - * - * @example - * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation - * var property = new Cesium.SampledProperty(Number); - * property.setInterpolationOptions({ - * interpolationDegree : 3, - * interpolationAlgorithm : Cesium.HermitePolynomialApproximation - * }); - * - * //Populate it with data - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:00.00Z`), 1.0); - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:01:00.00Z`), 6.0); - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:02:00.00Z`), 12.0); - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:03:30.00Z`), 5.0); - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:06:30.00Z`), 2.0); - * - * //Samples can be added in any order. - * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:30.00Z`), 6.2); - * - * //Retrieve an interpolated value - * var result = property.getValue(Cesium.JulianDate.fromIso8601(`2012-08-01T00:02:34.00Z`)); - */ - var SampledProperty = function(type) { - //>>includeStart('debug', pragmas.debug); - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - //>>includeEnd('debug'); - - var innerType = type; - if (innerType === Number) { - innerType = PackableNumber; - } - var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, innerType.packedLength); - - this._type = type; - this._innerType = innerType; - this._interpolationDegree = 1; - this._interpolationAlgorithm = LinearApproximation; - this._numberOfPoints = 0; - this._times = []; - this._values = []; - this._xTable = []; - this._yTable = []; - this._packedInterpolationLength = packedInterpolationLength; - this._updateTableLength = true; - this._interpolationResult = new Array(packedInterpolationLength); - this._definitionChanged = new Event(); - }; - - defineProperties(SampledProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof SampledProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._values.length === 0; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof SampledProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the type of property. - * @memberof SampledProperty.prototype - * @type {Object} - */ - type : { - get : function() { - return this._type; - } - }, - /** - * Gets the degree of interpolation to perform when retrieving a value. - * @memberof SampledProperty.prototype - * @type {Number} - * @default 1 - */ - interpolationDegree : { - get : function() { - return this._interpolationDegree; - } - }, - /** - * Gets the interpolation algorithm to use when retrieving a value. - * @memberof SampledProperty.prototype - * @type {InterpolationAlgorithm} - * @default LinearApproximation - */ - interpolationAlgorithm : { - get : function() { - return this._interpolationAlgorithm; - } - } - }); - - /** - * Gets the value of the property at the provided time. - * @memberof SampledProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - SampledProperty.prototype.getValue = function(time, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - //>>includeEnd('debug'); - - var innerType = this._innerType; - var times = this._times; - var values = this._values; - var index = binarySearch(times, time, JulianDate.compare); - if (index < 0) { - var xTable = this._xTable; - var yTable = this._yTable; - var interpolationAlgorithm = this._interpolationAlgorithm; - var packedInterpolationLength = this._packedInterpolationLength; - - if (this._updateTableLength) { - this._updateTableLength = false; - var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree), times.length); - if (numberOfPoints !== this._numberOfPoints) { - this._numberOfPoints = numberOfPoints; - xTable.length = numberOfPoints; - yTable.length = numberOfPoints * packedInterpolationLength; - } - } - - var degree = this._numberOfPoints - 1; - if (degree < 1) { - return undefined; - } - index = ~index; - - if (index >= times.length) { - index = times.length - 1; - } - - var firstIndex = 0; - var lastIndex = times.length - 1; - var pointsInCollection = lastIndex - firstIndex + 1; - - if (pointsInCollection < degree + 1) { - // Use the entire range. - } else { - var computedFirstIndex = index - ((degree / 2) | 0) - 1; - if (computedFirstIndex < firstIndex) { - computedFirstIndex = firstIndex; - } - var computedLastIndex = computedFirstIndex + degree; - if (computedLastIndex > lastIndex) { - computedLastIndex = lastIndex; - computedFirstIndex = computedLastIndex - degree; - if (computedFirstIndex < firstIndex) { - computedFirstIndex = firstIndex; - } - } - - firstIndex = computedFirstIndex; - lastIndex = computedLastIndex; - } - var length = lastIndex - firstIndex + 1; - - // Build the tables - for ( var i = 0; i < length; ++i) { - xTable[i] = times[lastIndex].getSecondsDifference(times[firstIndex + i]); - } - - if (!defined(innerType.convertPackedArrayForInterpolation)) { - var destinationIndex = 0; - var packedLength = innerType.packedLength; - var sourceIndex = firstIndex * packedLength; - var stop = (lastIndex + 1) * packedLength; - - while (sourceIndex < stop) { - yTable[destinationIndex] = values[sourceIndex]; - sourceIndex++; - destinationIndex++; - } - } else { - innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable); - } - - // Interpolate! - var x = times[lastIndex].getSecondsDifference(time); - var interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult); - - if (!defined(innerType.unpackInterpolationResult)) { - return innerType.unpack(interpolationResult, 0, result); - } - return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result); - } - return innerType.unpack(this._values, index * innerType.packedLength, result); - }; - - /** - * Sets the algorithm and degree to use when interpolating a value. - * @memberof SampledProperty - * - * @param {Object} options The options - * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - * - * @exception {DeveloperError} options is required. - */ - SampledProperty.prototype.setInterpolationOptions = function(options) { - //>>includeStart('debug', pragmas.debug); - if (!defined(options)) { - throw new DeveloperError('options is required.'); - } - //>>includeEnd('debug'); - - var valuesChanged = false; - - var interpolationAlgorithm = options.interpolationAlgorithm; - var interpolationDegree = options.interpolationDegree; - - if (this._interpolationAlgorithm !== interpolationAlgorithm) { - this._interpolationAlgorithm = interpolationAlgorithm; - valuesChanged = true; - } - - if (this._interpolationDegree !== interpolationDegree) { - this._interpolationDegree = interpolationDegree; - valuesChanged = true; - } - - if (valuesChanged) { - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - } - }; - - /** - * Adds a new sample - * @memberof SampledProperty - * - * @param {JulianDate} time The sample time. - * @param {Object} value The value at the provided time. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} value is required. - */ - SampledProperty.prototype.addSample = function(time, value) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - //>>includeEnd('debug'); - - var innerType = this._innerType; - var data = [time]; - innerType.pack(value, data, 1); - mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; - - /** - * Adds an array of samples - * @memberof SampledProperty - * - * @param {Array} times An array of JulianDate instances where each index is a sample time. - * @param {Array} values The array of values, where each value corresponds to the provided times index. - * - * @exception {DeveloperError} times is required. - * @exception {DeveloperError} values is required. - * @exception {DeveloperError} times and values must be the same length.. - */ - SampledProperty.prototype.addSamples = function(times, values) { - //>>includeStart('debug', pragmas.debug); - if (!defined(times)) { - throw new DeveloperError('times is required.'); - } - if (!defined(values)) { - throw new DeveloperError('values is required.'); - } - if (times.length !== values.length) { - throw new DeveloperError('times and values must be the same length.'); - } - //>>includeEnd('debug'); - - var innerType = this._innerType; - var length = times.length; - var data = []; - for ( var i = 0; i < length; i++) { - data.push(times[i]); - innerType.pack(values[i], data, data.length); - } - mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; - - /** - * Adds samples as a single packed array where each new sample is represented as a date, followed by the packed representation of the corresponding value. - * @memberof SampledProperty - * - * @param {Array} packedSamples The array of packed samples. - * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. - * - * @exception {DeveloperError} packedSamples is required. - */ - SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { - //>>includeStart('debug', pragmas.debug); - if (!defined(packedSamples)) { - throw new DeveloperError('packedSamples is required.'); - } - //>>includeEnd('debug'); - - mergeNewSamples(epoch, this._times, this._values, packedSamples, this._innerType.packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof SampledProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - SampledProperty.prototype.equals = function(other) { - if (this === other) { - return true; - } - if (!defined(other)) { - return false; - } - - var times = this._times; - var otherTimes = other._times; - var length = times.length; - - if (length !== otherTimes.length) { - return false; - } - - var i; - for (i = 0; i < length; i++) { - if (!JulianDate.equals(times[i], otherTimes[i])) { - return false; - } - } - - var values = this._values; - var otherValues = other._values; - for (i = 0; i < length; i++) { - if (values[i] !== otherValues[i]) { - return false; - } - } - - return this._type === other._type && // - this._interpolationDegree === other._interpolationDegree && // - this._interpolationAlgorithm === other._interpolationAlgorithm; - }; - - //Exposed for testing. - SampledProperty._mergeNewSamples = mergeNewSamples; - - return SampledProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/TimeIntervalCollectionPositionProperty.js b/Source/DataSource/TimeIntervalCollectionPositionProperty.js deleted file mode 100644 index 49b6f152b4fb..000000000000 --- a/Source/DataSource/TimeIntervalCollectionPositionProperty.js +++ /dev/null @@ -1,158 +0,0 @@ -/*global define*/ -define(['./PositionProperty', - './Property', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' - ], function( - PositionProperty, - Property, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - TimeIntervalCollection, - wrapFunction) { - "use strict"; - - /** - * A {@link TimeIntervalCollectionProperty} which is also a {@link PositionProperty}. - * - * @alias TimeIntervalCollectionPositionProperty - * @constructor - * - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - var TimeIntervalCollectionPositionProperty = function(referenceFrame) { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var raiseDefinitionChanged = function() { - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - }; - - defineProperties(TimeIntervalCollectionPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._intervals.isEmpty(); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the interval collection. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._intervals; - } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @Type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; - } - } - }); - - /** - * Gets the value of the property at the provided time in the fixed frame. - * @memberof CompositePositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - */ - TimeIntervalCollectionPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; - - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @memberof CompositePositionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. - */ - TimeIntervalCollectionPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - //>>includeEnd('debug'); - - var position = this._intervals.findDataForIntervalContainingDate(time); - if (defined(position)) { - return PositionProperty.convertToReferenceFrame(time, position, this._referenceFrame, referenceFrame, result); - } - return undefined; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof TimeIntervalCollectionPositionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - TimeIntervalCollectionPositionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof TimeIntervalCollectionPositionProperty && // - this._intervals.equals(other._intervals, Property.equals) && // - this._referenceFrame === other._referenceFrame); - }; - - return TimeIntervalCollectionPositionProperty; -}); \ No newline at end of file diff --git a/Source/DataSource/TimeIntervalCollectionProperty.js b/Source/DataSource/TimeIntervalCollectionProperty.js deleted file mode 100644 index fb80c7a13627..000000000000 --- a/Source/DataSource/TimeIntervalCollectionProperty.js +++ /dev/null @@ -1,153 +0,0 @@ -/*global define*/ -define(['./Property', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Enumeration', - '../Core/Event', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' - ], function( - Property, - defined, - defineProperties, - DeveloperError, - Enumeration, - Event, - TimeIntervalCollection, - wrapFunction) { - "use strict"; - - /** - * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the - * data property of each {@link TimeInterval} represents the value at time. - * - * @alias TimeIntervalCollectionProperty - * @constructor - * - * @example - * //Create a Cartesian2 interval property which contains data on August 1st, 2012 - * //and uses a different value every 6 hours. - * var composite = new Cesium.TimeIntervalCollectionProperty(); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', true, false, new Cesium.Cartesian2(2.0, 3.4))); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, new Cesium.Cartesian2(12.0, 2.7))); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-01T18:00:00.00Z', true, false, new Cesium.Cartesian2(5.0, 12.4))); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T18:00:00.00Z/2012-08-02T00:00:00.00Z', true, true, new Cesium.Cartesian2(85.0, 4.1))); - * - * @example - * //Create a TimeIntervalCollectionProperty that contains user-defined objects. - * function cloneMyObject(value, result) { - * return { - * value : value.value - * }; - * } - * - * var myObject = { - * value : 6, - * clone : cloneMyObject - * }; - * var myObject2 = { - * value : 12, - * clone : cloneMyObject - * }; - * - * var composite = new Cesium.TimeIntervalCollectionProperty(); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', true, false, myObject)); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, myObject2)); - */ - var TimeIntervalCollectionProperty = function() { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var raiseDefinitionChanged = function() { - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; - }; - - defineProperties(TimeIntervalCollectionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof TimeIntervalCollectionProperty.prototype - * @type {Boolean} - */ - isConstant : { - get : function() { - return this._intervals.isEmpty(); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof TimeIntervalCollectionProperty.prototype - * @type {Event} - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the interval collection. - * @memberof TimeIntervalCollectionProperty.prototype - * - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._intervals; - } - } - }); - - /** - * Gets the value of the property at the provided time. - * @memberof TimeIntervalCollectionProperty - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} This value requires a clone function be specified for the TimeIntervalCollectionProperty constructor. - */ - TimeIntervalCollectionProperty.prototype.getValue = function(time, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - //>>includeEnd('debug'); - - var value = this._intervals.findDataForIntervalContainingDate(time); - if (defined(value) && (typeof value === 'object' && !Array.isArray(value) && !(value instanceof Enumeration))) { - return value.clone(result); - } - return value; - }; - - /** - * Compares this property to the provided property and returns - * true if they are equal, false otherwise. - * @memberof TimeIntervalCollectionProperty - * - * @param {Property} [other] The other property. - * @returns {Boolean} true if left and right are equal, false otherwise. - */ - TimeIntervalCollectionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof TimeIntervalCollectionProperty && // - this._intervals.equals(other._intervals, Property.equals)); - }; - - return TimeIntervalCollectionProperty; -}); \ No newline at end of file diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 6c94ffc75fdc..adca27bc069f 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -1,12 +1,15 @@ /*global define*/ -define([ - '../Core/Color', +define(['../Core/Color', '../Core/defined', + '../Core/defineProperties', + '../Core/Event', './ConstantProperty', './Property' ], function( Color, defined, + defineProperties, + Event, ConstantProperty, Property) { "use strict"; @@ -17,13 +20,61 @@ define([ * @constructor */ var ColorMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this.color = new ConstantProperty(Color.WHITE); + }; + + defineProperties(ColorMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ColorMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return !defined(this._color) || this._color.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ColorMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * A {@link Color} {@link Property} which determines the material's color. + * @memberof ColorMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.WHITE) */ - this.color = new ConstantProperty(Color.WHITE); - }; + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(ColorMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); /** * Gets the {@link Material} type at the provided time. @@ -50,7 +101,7 @@ define([ if (!defined(result)) { result = {}; } - result.color = defined(this.color) ? this.color.getValue(time, result.color) : undefined; + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; return result; }; @@ -64,8 +115,15 @@ define([ */ ColorMaterialProperty.prototype.equals = function(other) { return this === other || // - (other instanceof ColorMaterialProperty && // - Property.equals(this.color, other.color)); + (other instanceof ColorMaterialProperty && // + Property.equals(this._color, other._color)); + }; + + /** + * @private + */ + ColorMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); }; return ColorMaterialProperty; diff --git a/Source/DynamicScene/CompositeMaterialProperty.js b/Source/DynamicScene/CompositeMaterialProperty.js index fd33066bd200..5670ff18f5b9 100644 --- a/Source/DynamicScene/CompositeMaterialProperty.js +++ b/Source/DynamicScene/CompositeMaterialProperty.js @@ -1,15 +1,16 @@ /*global define*/ -define([ - '../Core/defined', +define(['../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/TimeIntervalCollection', + '../Core/Event', + './CompositeProperty', './Property' ], function( defined, defineProperties, DeveloperError, - TimeIntervalCollection, + Event, + CompositeProperty, Property) { "use strict"; @@ -20,10 +21,37 @@ define([ * @constructor */ var CompositeMaterialProperty = function() { - this._intervals = new TimeIntervalCollection(); + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); }; defineProperties(CompositeMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositeMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the interval collection. * @memberof CompositeMaterialProperty.prototype @@ -32,7 +60,7 @@ define([ */ intervals : { get : function() { - return this._intervals; + return this._composite._intervals; } } }); @@ -51,7 +79,7 @@ define([ } //>>includeEnd('debug'); - var innerProperty = this._intervals.findDataForIntervalContainingDate(time); + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); if (defined(innerProperty)) { return innerProperty.getType(time); } @@ -75,7 +103,7 @@ define([ } //>>includeEnd('debug'); - var innerProperty = this._intervals.findDataForIntervalContainingDate(time); + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); if (defined(innerProperty)) { return innerProperty.getValue(time, result); } @@ -93,7 +121,7 @@ define([ CompositeMaterialProperty.prototype.equals = function(other) { return this === other || // (other instanceof CompositeMaterialProperty && // - this._intervals.equals(other._intervals, Property.equals)); + this._composite.equals(other._composite, Property.equals)); }; return CompositeMaterialProperty; diff --git a/Source/DynamicScene/CompositePositionProperty.js b/Source/DynamicScene/CompositePositionProperty.js index be56ec107895..9ff47061d6ab 100644 --- a/Source/DynamicScene/CompositePositionProperty.js +++ b/Source/DynamicScene/CompositePositionProperty.js @@ -1,19 +1,20 @@ /*global define*/ -define([ - '../Core/defaultValue', +define(['../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/TimeIntervalCollection', + '../Core/Event', '../Core/ReferenceFrame', + './CompositeProperty', './Property' ], function( defaultValue, defined, defineProperties, DeveloperError, - TimeIntervalCollection, + Event, ReferenceFrame, + CompositeProperty, Property) { "use strict"; @@ -24,11 +25,38 @@ define([ * @constructor */ var CompositePositionProperty = function(referenceFrame) { - this._intervals = new TimeIntervalCollection(); this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); }; defineProperties(CompositePositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositePositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositePositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the interval collection. * @memberof CompositePositionProperty.prototype @@ -37,7 +65,7 @@ define([ */ intervals : { get : function() { - return this._intervals; + return this._composite.intervals; } }, /** @@ -95,7 +123,7 @@ define([ } //>>includeEnd('debug'); - var innerProperty = this._intervals.findDataForIntervalContainingDate(time); + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); if (defined(innerProperty)) { return innerProperty.getValueInReferenceFrame(time, referenceFrame, result); } @@ -114,7 +142,7 @@ define([ return this === other || // (other instanceof CompositePositionProperty && // this._referenceFrame === other._referenceFrame && // - this._intervals.equals(other._intervals, Property.equals)); + this._composite.equals(other._composite, Property.equals)); }; return CompositePositionProperty; diff --git a/Source/DynamicScene/CompositeProperty.js b/Source/DynamicScene/CompositeProperty.js index f0258ef38eed..47e22fd45e81 100644 --- a/Source/DynamicScene/CompositeProperty.js +++ b/Source/DynamicScene/CompositeProperty.js @@ -1,18 +1,39 @@ /*global define*/ -define([ +define(['./Property', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', + '../Core/Event', + '../Core/EventHelper', '../Core/TimeIntervalCollection', - './Property' + '../Core/wrapFunction' ], function( + Property, defined, defineProperties, DeveloperError, + Event, + EventHelper, TimeIntervalCollection, - Property) { + wrapFunction) { "use strict"; + function subscribeAll(property, eventHelper, definitionChanged, intervals) { + var callback = function() { + definitionChanged.raiseEvent(property); + }; + + var items = []; + eventHelper.removeAll(); + var length = intervals.getLength(); + for (var i = 0; i < length; i++) { + var interval = intervals.get(i); + if (defined(interval.data) && items.indexOf(interval.data) === -1) { + eventHelper.add(interval.data.definitionChanged, callback); + } + } + } + /** * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the * data property of each {@link TimeInterval} is another Property instance which is @@ -37,10 +58,49 @@ define([ * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', false, false, sampledProperty)); */ var CompositeProperty = function() { - this._intervals = new TimeIntervalCollection(); + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var eventHelper = new EventHelper(); + var intervalsChanged = function() { + subscribeAll(that, eventHelper, definitionChanged, intervals); + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, intervalsChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, intervalsChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, intervalsChanged, intervals.clear); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; }; defineProperties(CompositeProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositeProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the interval collection. * @memberof CompositeProperty.prototype diff --git a/Source/DynamicScene/ConstantPositionProperty.js b/Source/DynamicScene/ConstantPositionProperty.js index 990a8ead59e9..8e88b49da1c9 100644 --- a/Source/DynamicScene/ConstantPositionProperty.js +++ b/Source/DynamicScene/ConstantPositionProperty.js @@ -1,24 +1,23 @@ /*global define*/ -define([ - './ConstantProperty', - './PositionProperty', +define(['./PositionProperty', + './Property', '../Core/Cartesian3', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/ReferenceFrame', - './Property' + '../Core/Event', + '../Core/ReferenceFrame' ], function( - ConstantProperty, PositionProperty, + Property, Cartesian3, defaultValue, defined, defineProperties, DeveloperError, - ReferenceFrame, - Property) { + Event, + ReferenceFrame) { "use strict"; /** @@ -28,21 +27,39 @@ define([ * @alias ConstantPositionProperty * @constructor * - * @param {Cartesian3} value The property value. + * @param {Cartesian3} [value] The property value. * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - * - * @exception {DeveloperError} value is required. - * - * @example - * //Create a constant position in the inertial frame. - * var constantProperty = new Cesium.ConstantPositionProperty(new Cesium.Cartesian3(-4225824.0, 1261219.0, -5148934.0), Cesium.ReferenceFrame.INERTIAL); */ var ConstantPositionProperty = function(value, referenceFrame) { - this._property = new ConstantProperty(value); + this._definitionChanged = new Event(); + this._value = Cartesian3.clone(value); this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); }; defineProperties(ConstantPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return !defined(this._value) || this._referenceFrame === ReferenceFrame.FIXED; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the reference frame in which the position is defined. * @memberof ConstantPositionProperty.prototype @@ -70,6 +87,29 @@ define([ return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); }; + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof ConstantPositionProperty + * + * @param {Cartesian3} value The property value. + * @param {ReferenceFrame} [referenceFrame=this.referenceFrame] The reference frame in which the position is defined. + */ + ConstantPositionProperty.prototype.setValue = function(value, referenceFrame) { + var definitionChanged = false; + if (!Cartesian3.equals(this._value, value)) { + definitionChanged = true; + this._value = Cartesian3.clone(value); + } + if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { + definitionChanged = true; + this._referenceFrame = defaultValue(this._referenceFrame, referenceFrame); + } + if (definitionChanged) { + this._definitionChanged.raiseEvent(this); + } + }; + /** * Gets the value of the property at the provided time and in the provided reference frame. * @memberof ConstantPositionProperty @@ -92,8 +132,7 @@ define([ } //>>includeEnd('debug'); - var value = this._property.getValue(time, result); - return PositionProperty.convertToReferenceFrame(time, value, this._referenceFrame, referenceFrame, value); + return PositionProperty.convertToReferenceFrame(time, this._value, this._referenceFrame, referenceFrame, result); }; /** @@ -107,7 +146,7 @@ define([ ConstantPositionProperty.prototype.equals = function(other) { return this === other || (other instanceof ConstantPositionProperty && - Property.equals(this._property, other._property) && + Cartesian3.equals(this._value, other._value) && this._referenceFrame === other._referenceFrame); }; diff --git a/Source/DynamicScene/ConstantProperty.js b/Source/DynamicScene/ConstantProperty.js index 38b33e3ec366..8abfc5e8c9d3 100644 --- a/Source/DynamicScene/ConstantProperty.js +++ b/Source/DynamicScene/ConstantProperty.js @@ -1,71 +1,107 @@ /*global define*/ -define([ - '../Core/defaultValue', +define(['../Core/defaultValue', '../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Enumeration' + '../Core/Enumeration', + '../Core/Event' ], function( defaultValue, defined, + defineProperties, DeveloperError, - Enumeration) { + Enumeration, + Event) { "use strict"; /** - * A {@link Property} whose value never changes. + * A {@link Property} whose value does not change with respect to simulation time. + * If the value is an object, the object must provide clone and equals functions. * * @alias ConstantProperty * @constructor * - * @param {Object|Number|String} value The property value. - * This parameter is only required if the value is not a number or string and does not have a clone function. + * @param {Object|Number|String|Boolean} [value] The property value. * - * @exception {DeveloperError} value is required. - * @exception {DeveloperError} clone is a required function. - * - * @see ConstantPositionProperty - * - * @example - * //Create a constant value from a Cartesian2 instance. - * var constantProperty = new ConstantProperty(new Cartesian2(10, 12)); + * @exception {DeveloperError} value.clone is a required function. + * @exception {DeveloperError} value.equals is a required function. */ var ConstantProperty = function(value) { - //>>includeStart('debug', pragmas.debug); - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - //>>includeEnd('debug'); - - var simple = typeof value !== 'object' || Array.isArray(value) || value instanceof Enumeration; + this._value = undefined; + this._simple = true; + this._definitionChanged = new Event(); + this.setValue(value); + }; - //>>includeStart('debug', pragmas.debug); - if (!simple) { - if (typeof value.clone !== 'function') { - throw new DeveloperError('clone is a required function.'); + defineProperties(ConstantProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * This property always returns true. + * @memberof ConstantProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return true; } - if (typeof value.equals !== 'function') { - throw new DeveloperError('equals is a required function.'); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof ConstantProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } } - //>>includeEnd('debug'); - - this._value = value; - this._simple = simple; - }; + }); /** - * Gets the value of the property at the provided time. - * @memberof CompositeProperty + * Gets the value of the property. + * @memberof ConstantProperty * - * @param {JulianDate} time The time for which to retrieve the value. This parameter is unused since the value never changes. + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ ConstantProperty.prototype.getValue = function(time, result) { - if (this._simple) { - return this._value; + return this._simple ? this._value : this._value.clone(result); + }; + + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof ConstantProperty + * + * @param {Object|Number|String|Boolean} value The property value. + * + * @exception {DeveloperError} value.clone is a required function. + * @exception {DeveloperError} value.equals is a required function. + */ + ConstantProperty.prototype.setValue = function(value) { + var oldValue = this._value; + var simple = this._simple; + if ((simple && oldValue !== value) || (!simple && !oldValue.equals(value))) { + simple = typeof value !== 'object' || Array.isArray(value) || value instanceof Enumeration; + + //>>includeStart('debug', pragmas.debug); + if (!simple) { + if (typeof value.clone !== 'function') { + throw new DeveloperError('clone is a required function.'); + } + if (typeof value.equals !== 'function') { + throw new DeveloperError('equals is a required function.'); + } + } + //>>includeEnd('debug'); + + this._value = simple ? value : value.clone(); + this._simple = simple; + this._definitionChanged.raiseEvent(this); } - return this._value.clone(result); }; /** diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 25dd79675631..ccddab2cae15 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -317,11 +317,11 @@ define([ function updateInterpolationSettings(packetData, property) { var interpolator = interpolators[packetData.interpolationAlgorithm]; - if (defined(interpolator)) { - property.interpolationAlgorithm = interpolator; - } - if (defined(packetData.interpolationDegree)) { - property.interpolationDegree = packetData.interpolationDegree; + if (defined(interpolator) || defined(packetData.interpolationDegree)) { + property.setInterpolationOptions({ + interpolationAlgorithm : interpolator, + interpolationDegree : packetData.interpolationDegree + }); } } diff --git a/Source/DynamicScene/GridMaterialProperty.js b/Source/DynamicScene/GridMaterialProperty.js index 0f7bfd12e213..c7b4fc1b3f05 100644 --- a/Source/DynamicScene/GridMaterialProperty.js +++ b/Source/DynamicScene/GridMaterialProperty.js @@ -1,14 +1,17 @@ /*global define*/ -define([ - '../Core/Cartesian2', +define(['../Core/Cartesian2', '../Core/Color', '../Core/defined', + '../Core/defineProperties', + '../Core/Event', './ConstantProperty', './Property' ], function( Cartesian2, Color, defined, + defineProperties, + Event, ConstantProperty, Property) { "use strict"; @@ -19,34 +22,143 @@ define([ * @constructor */ var GridMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._cellAlpha = undefined; + this._cellAlphaSubscription = undefined; + this._lineCount = undefined; + this._lineCountSubscription = undefined; + this._lineThickness = undefined; + this._lineThicknessSubscription = undefined; + + this.color = new ConstantProperty(Color.WHITE); + this.cellAlpha = new ConstantProperty(0.1); + this.lineCount = new ConstantProperty(new Cartesian2(8, 8)); + this.lineThickness = new ConstantProperty(new Cartesian2(1.0, 1.0)); + }; + + defineProperties(GridMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof GridMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._color) || this._color.isConstant) && // + (!defined(this._cellAlpha) || this._cellAlpha.isConstant) && // + (!defined(this._lineCount) || this._lineCount.isConstant) && // + (!defined(this._lineThickness) || this._lineThickness.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof GridMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * A {@link Color} {@link Property} which determines the grid's color. + * @memberof GridMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.WHITE) */ - this.color = new ConstantProperty(Color.WHITE); - + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A numeric {@link Property} which determines the grid cells alpha value, when combined with the color alpha. * @type {Property} * @default new ConstantProperty(0.1) */ - this.cellAlpha = new ConstantProperty(0.1); - + cellAlpha : { + get : function() { + return this._cellAlpha; + }, + set : function(value) { + if (this._cellAlpha !== value) { + if (this._cellAlphaSubscription) { + this._cellAlphaSubscription(); + this._cellAlphaSubscription = undefined; + } + this._cellAlpha = value; + if (defined(value)) { + this._cellAlphaSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A {@link Cartesian2} {@link Property} which determines the number of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(8, 8)) */ - this.lineCount = new ConstantProperty(new Cartesian2(8, 8)); - + lineCount : { + get : function() { + return this._lineCount; + }, + set : function(value) { + if (this._lineCount !== value) { + if (this._lineCountSubscription) { + this._lineCountSubscription(); + this._lineCountSubscription = undefined; + } + this._lineCount = value; + if (defined(value)) { + this._lineCountSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A {@link Cartesian2} {@link Property} which determines the thickness of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(1.0, 1.0)) */ - this.lineThickness = new ConstantProperty(new Cartesian2(1.0, 1.0)); - }; + lineThickness : { + get : function() { + return this._lineThickness; + }, + set : function(value) { + if (this._lineThickness !== value) { + if (this._lineThicknessSubscription) { + this._lineThicknessSubscription(); + this._lineThicknessSubscription = undefined; + } + this._lineThickness = value; + if (defined(value)) { + this._lineThicknessSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); /** * Gets the {@link Material} type at the provided time. @@ -73,10 +185,10 @@ define([ if (!defined(result)) { result = {}; } - result.color = defined(this.color) ? this.color.getValue(time, result.color) : undefined; - result.cellAlpha = defined(this.cellAlpha) ? this.cellAlpha.getValue(time) : undefined; - result.lineCount = defined(this.lineCount) ? this.lineCount.getValue(time, result.lineCount) : undefined; - result.lineThickness = defined(this.lineThickness) ? this.lineThickness.getValue(time, result.lineThickness) : undefined; + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; + result.cellAlpha = defined(this._cellAlpha) ? this._cellAlpha.getValue(time) : undefined; + result.lineCount = defined(this._lineCount) ? this._lineCount.getValue(time, result.lineCount) : undefined; + result.lineThickness = defined(this._lineThickness) ? this._lineThickness.getValue(time, result.lineThickness) : undefined; return result; }; @@ -90,11 +202,18 @@ define([ */ GridMaterialProperty.prototype.equals = function(other) { return this === other || // - (other instanceof GridMaterialProperty && // - Property.equals(this.color, other.color) && // - Property.equals(this.cellAlpha, other.cellAlpha) && // - Property.equals(this.lineCount, other.lineCount) && // - Property.equals(this.lineThickness, other.lineThickness)); + (other instanceof GridMaterialProperty && // + Property.equals(this._color, other._color) && // + Property.equals(this._cellAlpha, other._cellAlpha) && // + Property.equals(this._lineCount, other._lineCount) && // + Property.equals(this._lineThickness, other._lineThickness)); + }; + + /** + * @private + */ + GridMaterialProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); }; return GridMaterialProperty; diff --git a/Source/DynamicScene/ImageMaterialProperty.js b/Source/DynamicScene/ImageMaterialProperty.js index b32c85b41053..a67febcdb35e 100644 --- a/Source/DynamicScene/ImageMaterialProperty.js +++ b/Source/DynamicScene/ImageMaterialProperty.js @@ -2,11 +2,15 @@ define([ '../Core/Cartesian2', '../Core/defined', + '../Core/defineProperties', + '../Core/Event', './ConstantProperty', './Property' ], function( Cartesian2, defined, + defineProperties, + Event, ConstantProperty, Property) { "use strict"; @@ -17,18 +21,86 @@ define([ * @constructor */ var ImageMaterialProperty = function() { + this._definitionChanged = new Event(); + this._image = undefined; + this._imageSubscription = undefined; + this._repeat = undefined; + this._repeatSubscription = undefined; + this.repeat = new ConstantProperty(new Cartesian2(1, 1)); + }; + + defineProperties(ImageMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ImageMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._image) || this._image.isConstant) && (!defined(this._repeat) || this._repeat.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ImageMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * A string {@link Property} which is the url of the desired image. + * @memberof ImageMaterialProperty.prototype * @type {Property} */ - this.image = undefined; + image : { + get : function() { + return this._image; + }, + set : function(value) { + if (this._image !== value) { + if (this._imageSubscription) { + this._imageSubscription(); + this._imageSubscription = undefined; + } + this._image = value; + if (defined(value)) { + this._imageSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A {@link Cartesian2} {@link Property} which determines the number of times the image repeats in each direction. + * @memberof ImageMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(new Cartesian2(1, 1)) */ - this.repeat = new ConstantProperty(new Cartesian2(1, 1)); - }; + repeat : { + get : function() { + return this._repeat; + }, + set : function(value) { + if (this._repeat !== value) { + if (this._repeatSubscription) { + this._repeatSubscription(); + this._repeatSubscription = undefined; + } + this._repeat = value; + if (defined(value)) { + this._repeatSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); /** * Gets the {@link Material} type at the provided time. @@ -56,8 +128,8 @@ define([ result = {}; } - result.image = defined(this.image) ? this.image.getValue(time) : undefined; - result.repeat = defined(this.repeat) ? this.repeat.getValue(time, result.repeat) : undefined; + result.image = defined(this._image) ? this._image.getValue(time) : undefined; + result.repeat = defined(this._repeat) ? this._repeat.getValue(time, result.repeat) : undefined; return result; }; @@ -72,8 +144,15 @@ define([ ImageMaterialProperty.prototype.equals = function(other) { return this === other || // (other instanceof ImageMaterialProperty && // - Property.equals(this.image, other.image) && // - Property.equals(this.repeat, other.repeat)); + Property.equals(this._image, other._image) && // + Property.equals(this._repeat, other._repeat)); + }; + + /** + * @private + */ + ImageMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); }; return ImageMaterialProperty; diff --git a/Source/DynamicScene/MaterialProperty.js b/Source/DynamicScene/MaterialProperty.js index 3ad71a2d382d..d8f76a1166a1 100644 --- a/Source/DynamicScene/MaterialProperty.js +++ b/Source/DynamicScene/MaterialProperty.js @@ -1,20 +1,17 @@ /*global define*/ -define([ - '../Core/defined', +define(['../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError', '../Scene/Material' ], function( defined, + defineProperties, DeveloperError, Material) { "use strict"; - function throwInstantiationError() { - throw new DeveloperError('This type should not be instantiated directly.'); - } - /** - * The interface for all {@link Property} objects that represent {@link Material} uniforms. + * The interface for all {@link MaterialProperty} objects that represent {@link Material} uniforms. * This type defines an interface and cannot be instantiated directly. * * @alias MaterialProperty @@ -25,7 +22,31 @@ define([ * @see GridMaterialProperty * @see ImageMaterialProperty */ - var MaterialProperty = throwInstantiationError; + var MaterialProperty = function() { + DeveloperError.throwInstantiationError(); + }; + + defineProperties(MaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof MaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof MaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + } + }); /** * Gets the {@link Material} type at the provided time. @@ -35,7 +56,7 @@ define([ * @param {JulianDate} time The time for which to retrieve the type. * @type {String} The type of material. */ - MaterialProperty.prototype.getType = throwInstantiationError; + MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; /** * Gets the value of the property at the provided time. @@ -48,7 +69,7 @@ define([ * * @exception {DeveloperError} time is required. */ - MaterialProperty.prototype.getValue = throwInstantiationError; + MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; /** * Compares this property to the provided property and returns @@ -58,7 +79,7 @@ define([ * @param {Property} [other] The other property. * @returns {Boolean} true if left and right are equal, false otherwise. */ - MaterialProperty.prototype.equals = throwInstantiationError; + MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; /** * @private diff --git a/Source/DynamicScene/PolylineOutlineMaterialProperty.js b/Source/DynamicScene/PolylineOutlineMaterialProperty.js index 637aef6e5a5d..c4a62747c3ea 100644 --- a/Source/DynamicScene/PolylineOutlineMaterialProperty.js +++ b/Source/DynamicScene/PolylineOutlineMaterialProperty.js @@ -1,12 +1,15 @@ /*global define*/ -define([ - '../Core/Color', +define(['../Core/Color', '../Core/defined', + '../Core/defineProperties', + '../Core/Event', './ConstantProperty', './Property' ], function( Color, defined, + defineProperties, + Event, ConstantProperty, Property) { "use strict"; @@ -17,25 +20,116 @@ define([ * @constructor */ var PolylineOutlineMaterialProperty = function() { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this.color = new ConstantProperty(Color.WHITE); + this.outlineColor = new ConstantProperty(Color.BLACK); + this.outlineWidth = new ConstantProperty(0.0); + }; + + defineProperties(PolylineOutlineMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return (!defined(this._color) || this._color.isConstant) && + (!defined(this._outlineColor) || this._outlineColor.isConstant) && + (!defined(this._outlineWidth) || this._outlineWidth.isConstant); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * A {@link Color} {@link Property} which determines the polyline's color. + * @memberof PolylineOutlineMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.WHITE) */ - this.color = new ConstantProperty(Color.WHITE); + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (this._color !== value) { + if (this._colorSubscription) { + this._colorSubscription(); + this._colorSubscription = undefined; + } + this._color = value; + if (defined(value)) { + this._colorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A {@link Color} {@link Property} which determines the polyline's outline color. + * @memberof PolylineOutlineMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.BLACK) */ - this.outlineColor = new ConstantProperty(Color.BLACK); + outlineColor : { + get : function() { + return this._outlineColor; + }, + set : function(value) { + if (this._outlineColor !== value) { + if (this._outlineColorSubscription) { + this._outlineColorSubscription(); + this._outlineColorSubscription = undefined; + } + this._outlineColor = value; + if (defined(value)) { + this._outlineColorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, /** * A Number {@link Property} which determines the polyline's outline width. * @type {Property} * @default new ConstantProperty(0) */ - this.outlineWidth = new ConstantProperty(0); - }; + outlineWidth : { + get : function() { + return this._outlineWidth; + }, + set : function(value) { + if (this._outlineWidth !== value) { + if (this._outlineWidthSubscription) { + this._outlineWidthSubscription(); + this._outlineWidthSubscription = undefined; + } + this._outlineWidth = value; + if (defined(value)) { + this._outlineWidthSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); /** * Gets the {@link Material} type at the provided time. @@ -62,9 +156,9 @@ define([ if (!defined(result)) { result = {}; } - result.color = defined(this.color) ? this.color.getValue(time, result.color) : undefined; - result.outlineColor = defined(this.outlineColor) ? this.outlineColor.getValue(time, result.outlineColor) : undefined; - result.outlineWidth = defined(this.outlineWidth) ? this.outlineWidth.getValue(time) : undefined; + result.color = defined(this._color) ? this._color.getValue(time, result.color) : undefined; + result.outlineColor = defined(this._outlineColor) ? this._outlineColor.getValue(time, result.outlineColor) : undefined; + result.outlineWidth = defined(this._outlineWidth) ? this._outlineWidth.getValue(time) : undefined; return result; }; @@ -79,9 +173,16 @@ define([ PolylineOutlineMaterialProperty.prototype.equals = function(other) { return this === other || // (other instanceof PolylineOutlineMaterialProperty && // - Property.equals(this.color, other.color) && // - Property.equals(this.outlineColor, other.outlineColor) && // - Property.equals(this.outlineWidth, other.outlineWidth)); + Property.equals(this._color, other._color) && // + Property.equals(this._outlineColor, other._outlineColor) && // + Property.equals(this._outlineWidth, other._outlineWidth)); + }; + + /** + * @private + */ + PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged = function(){ + this._definitionChanged.raiseEvent(this); }; return PolylineOutlineMaterialProperty; diff --git a/Source/DynamicScene/PositionProperty.js b/Source/DynamicScene/PositionProperty.js index d60ebff864c7..566fd7f9b412 100644 --- a/Source/DynamicScene/PositionProperty.js +++ b/Source/DynamicScene/PositionProperty.js @@ -1,6 +1,5 @@ /*global define*/ -define([ - '../Core/Cartesian3', +define(['../Core/Cartesian3', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', @@ -17,14 +16,9 @@ define([ Transforms) { "use strict"; - function throwInstantiationError() { - throw new DeveloperError('This type should not be instantiated directly.'); - } - /** - * The interface for all position {@link Property} objects. Position properties - * represent a world location as a {@link Cartesian3} with an associated - * {@link ReferenceFrame}. + * The interface for all {@link Property} objects that define a world + * location as a {@link Cartesian3} with an associated {@link ReferenceFrame}. * This type defines an interface and cannot be instantiated directly. * * @alias PositionProperty @@ -35,21 +29,42 @@ define([ * @see SampledPositionProperty * @see TimeIntervalCollectionPositionProperty */ - var PositionProperty = throwInstantiationError; + var PositionProperty = function(){ + DeveloperError.throwInstantiationError(); + }; defineProperties(PositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + }, /** * Gets the reference frame that the position is defined in. * @memberof PositionProperty.prototype * @Type {ReferenceFrame} */ referenceFrame : { - get : throwInstantiationError + get : DeveloperError.throwInstantiationError } }); /** - * Gets the value of the property at the provided time. + * Gets the value of the property at the provided time in the fixed frame. * @memberof PositionProperty * @function * @@ -59,7 +74,7 @@ define([ * * @exception {DeveloperError} time is required. */ - PositionProperty.prototype.getValue = throwInstantiationError; + PositionProperty.prototype.getValue = DeveloperError.throwInstantiationError; /** * Gets the value of the property at the provided time and in the provided reference frame. @@ -74,7 +89,7 @@ define([ * @exception {DeveloperError} time is required. * @exception {DeveloperError} referenceFrame is required. */ - PositionProperty.prototype.getValueInReferenceFrame = throwInstantiationError; + PositionProperty.prototype.getValueInReferenceFrame = DeveloperError.throwInstantiationError; /** * Compares this property to the provided property and returns @@ -84,7 +99,7 @@ define([ * @param {Property} [other] The other property. * @returns {Boolean} true if left and right are equal, false otherwise. */ - PositionProperty.prototype.equals = throwInstantiationError; + PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; var scratchMatrix3 = new Matrix3(); @@ -92,6 +107,10 @@ define([ * @private */ PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) { + if (!defined(value)) { + return value; + } + if (inputFrame === outputFrame) { return Cartesian3.clone(value, result); } diff --git a/Source/DynamicScene/Property.js b/Source/DynamicScene/Property.js index 6af9b43a2f61..dcde7be20682 100644 --- a/Source/DynamicScene/Property.js +++ b/Source/DynamicScene/Property.js @@ -1,18 +1,15 @@ /*global define*/ define(['../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError' ], function( defined, + defineProperties, DeveloperError) { "use strict"; - function throwInstantiationError() { - throw new DeveloperError('This type should not be instantiated directly.'); - } - /** - * The interface for all properties, which represent a value that can - * optionally vary over time. + * The interface for all properties, which represent a value that can optionally vary over time. * This type defines an interface and cannot be instantiated directly. * * @alias Property @@ -24,9 +21,33 @@ define(['../Core/defined', * @see TimeIntervalCollectionProperty * @see MaterialProperty * @see PositionProperty - * @see RefereenceProperty + * @see ReferenceProperty */ - var Property = throwInstantiationError; + var Property = function() { + DeveloperError.throwInstantiationError(); + }; + + defineProperties(Property.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof Property.prototype + * @type {Boolean} + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof Property.prototype + * @type {Event} + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + } + }); /** * Gets the value of the property at the provided time. @@ -39,7 +60,7 @@ define(['../Core/defined', * * @exception {DeveloperError} time is required. */ - Property.prototype.getValue = throwInstantiationError; + Property.prototype.getValue = DeveloperError.throwInstantiationError; /** * Compares this property to the provided property and returns @@ -49,7 +70,7 @@ define(['../Core/defined', * @param {Property} [other] The other property. * @returns {Boolean} true if left and right are equal, false otherwise. */ - Property.prototype.equals = throwInstantiationError; + Property.prototype.equals = DeveloperError.throwInstantiationError; /** * @private diff --git a/Source/DynamicScene/SampledPositionProperty.js b/Source/DynamicScene/SampledPositionProperty.js index 418c17d1a7f5..dd5d72e7e9f2 100644 --- a/Source/DynamicScene/SampledPositionProperty.js +++ b/Source/DynamicScene/SampledPositionProperty.js @@ -1,24 +1,25 @@ /*global define*/ -define([ +define(['./PositionProperty', + './Property', + './SampledProperty', '../Core/Cartesian3', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/ReferenceFrame', - './PositionProperty', - './Property', - './SampledProperty' + '../Core/Event', + '../Core/ReferenceFrame' ], function( + PositionProperty, + Property, + SampledProperty, Cartesian3, defaultValue, defined, defineProperties, DeveloperError, - ReferenceFrame, - PositionProperty, - Property, - SampledProperty) { + Event, + ReferenceFrame) { "use strict"; /** @@ -31,10 +32,38 @@ define([ */ var SampledPositionProperty = function(referenceFrame) { this._property = new SampledProperty(Cartesian3); + this._definitionChanged = new Event(); this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + + this._property._definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); }; defineProperties(SampledPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledPositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._property.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledPositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the reference frame in which the position is defined. * @memberof SampledPositionProperty.prototype @@ -47,7 +76,7 @@ define([ } }, /** - * Gets or sets the degree of interpolation to perform when retrieving a value. + * Gets the degree of interpolation to perform when retrieving a value. * @memberof SampledPositionProperty.prototype * * @type {Object} @@ -56,13 +85,10 @@ define([ interpolationDegree : { get : function() { return this._property.interpolationDegree; - }, - set : function(value) { - this._property.interpolationDegree = value; } }, /** - * Gets or sets the interpolation algorithm to use when retrieving a value. + * Gets the interpolation algorithm to use when retrieving a value. * @memberof SampledPositionProperty.prototype * * @type {InterpolationAlgorithm} @@ -71,9 +97,6 @@ define([ interpolationAlgorithm : { get : function() { return this._property.interpolationAlgorithm; - }, - set : function(value) { - this._property.interpolationAlgorithm = value; } } }); @@ -121,6 +144,20 @@ define([ return result; }; + /** + * Sets the algorithm and degree to use when interpolating a position. + * @memberof SampledPositionProperty + * + * @param {Object} options The options + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * + * @exception {DeveloperError} options is required. + */ + SampledPositionProperty.prototype.setInterpolationOptions = function(options) { + this._property.setInterpolationOptions(options); + }; + /** * Adds a new sample * @memberof SampledPositionProperty diff --git a/Source/DynamicScene/SampledProperty.js b/Source/DynamicScene/SampledProperty.js index 71e8f6a460cb..a2a259e1d208 100644 --- a/Source/DynamicScene/SampledProperty.js +++ b/Source/DynamicScene/SampledProperty.js @@ -1,10 +1,10 @@ /*global define*/ -define([ - '../Core/binarySearch', +define(['../Core/binarySearch', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', + '../Core/Event', '../Core/JulianDate', '../Core/LinearApproximation' ], function( @@ -13,6 +13,7 @@ define([ defined, defineProperties, DeveloperError, + Event, JulianDate, LinearApproximation) { "use strict"; @@ -123,7 +124,7 @@ define([ * @alias SampledProperty * @constructor * - * @param {Object} type The type of property, which must be Number, String or implement {@link Packable}. + * @param {Number|Object} type The type of property, which must be a Number or implement {@link Packable}. * * @exception {DeveloperError} type is required. * @@ -145,8 +146,10 @@ define([ * @example * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation * var property = new Cesium.SampledProperty(Number); - * property.interpolationDegree = 3; - * property.interpolationAlgorithm = Cesium.HermitePolynomialApproximation; + * property.setInterpolationOptions({ + * interpolationDegree : 3, + * interpolationAlgorithm : Cesium.HermitePolynomialApproximation + * }); * * //Populate it with data * property.addSample(Cesium.JulianDate.fromIso8601(`2012-08-01T00:00:00.00Z`), 1.0); @@ -186,9 +189,33 @@ define([ this._packedInterpolationLength = packedInterpolationLength; this._updateTableLength = true; this._interpolationResult = new Array(packedInterpolationLength); + this._definitionChanged = new Event(); }; defineProperties(SampledProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._values.length === 0; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the type of property. * @memberof SampledProperty.prototype @@ -200,22 +227,18 @@ define([ } }, /** - * Gets or sets the degree of interpolation to perform when retrieving a value. + * Gets the degree of interpolation to perform when retrieving a value. * @memberof SampledProperty.prototype - * @type {Object} + * @type {Number} * @default 1 */ interpolationDegree : { get : function() { return this._interpolationDegree; - }, - set : function(value) { - this._interpolationDegree = value; - this._updateTableLength = true; } }, /** - * Gets or sets the interpolation algorithm to use when retrieving a value. + * Gets the interpolation algorithm to use when retrieving a value. * @memberof SampledProperty.prototype * @type {InterpolationAlgorithm} * @default LinearApproximation @@ -223,10 +246,6 @@ define([ interpolationAlgorithm : { get : function() { return this._interpolationAlgorithm; - }, - set : function(value) { - this._interpolationAlgorithm = value; - this._updateTableLength = true; } } }); @@ -335,6 +354,44 @@ define([ return innerType.unpack(this._values, index * innerType.packedLength, result); }; + /** + * Sets the algorithm and degree to use when interpolating a value. + * @memberof SampledProperty + * + * @param {Object} options The options + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * + * @exception {DeveloperError} options is required. + */ + SampledProperty.prototype.setInterpolationOptions = function(options) { + //>>includeStart('debug', pragmas.debug); + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + //>>includeEnd('debug'); + + var valuesChanged = false; + + var interpolationAlgorithm = options.interpolationAlgorithm; + var interpolationDegree = options.interpolationDegree; + + if (this._interpolationAlgorithm !== interpolationAlgorithm) { + this._interpolationAlgorithm = interpolationAlgorithm; + valuesChanged = true; + } + + if (this._interpolationDegree !== interpolationDegree) { + this._interpolationDegree = interpolationDegree; + valuesChanged = true; + } + + if (valuesChanged) { + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + } + }; + /** * Adds a new sample * @memberof SampledProperty @@ -360,6 +417,7 @@ define([ innerType.pack(value, data, 1); mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** @@ -395,6 +453,7 @@ define([ } mergeNewSamples(undefined, this._times, this._values, data, innerType.packedLength); this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** @@ -415,6 +474,7 @@ define([ mergeNewSamples(epoch, this._times, this._values, packedSamples, this._innerType.packedLength); this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** diff --git a/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js b/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js index 3a6142e79bbd..49b6f152b4fb 100644 --- a/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js +++ b/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js @@ -1,22 +1,25 @@ /*global define*/ -define([ +define(['./PositionProperty', + './Property', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', + '../Core/Event', '../Core/ReferenceFrame', '../Core/TimeIntervalCollection', - './PositionProperty', - './Property' + '../Core/wrapFunction' ], function( + PositionProperty, + Property, defaultValue, defined, defineProperties, DeveloperError, + Event, ReferenceFrame, TimeIntervalCollection, - PositionProperty, - Property) { + wrapFunction) { "use strict"; /** @@ -28,11 +31,48 @@ define([ * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. */ var TimeIntervalCollectionPositionProperty = function(referenceFrame) { - this._intervals = new TimeIntervalCollection(); + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var raiseDefinitionChanged = function() { + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); }; defineProperties(TimeIntervalCollectionPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the interval collection. * @memberof TimeIntervalCollectionPositionProperty.prototype diff --git a/Source/DynamicScene/TimeIntervalCollectionProperty.js b/Source/DynamicScene/TimeIntervalCollectionProperty.js index 4972ed12d310..fb80c7a13627 100644 --- a/Source/DynamicScene/TimeIntervalCollectionProperty.js +++ b/Source/DynamicScene/TimeIntervalCollectionProperty.js @@ -1,33 +1,30 @@ /*global define*/ -define([ +define(['./Property', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', '../Core/Enumeration', + '../Core/Event', '../Core/TimeIntervalCollection', - './Property' + '../Core/wrapFunction' ], function( + Property, defined, defineProperties, DeveloperError, Enumeration, + Event, TimeIntervalCollection, - Property) { + wrapFunction) { "use strict"; /** - * A {@link Property} which is defined by a TimeIntervalCollection, where the + * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the * data property of each {@link TimeInterval} represents the value at time. * * @alias TimeIntervalCollectionProperty * @constructor * - * @param {Function} [clone=value.clone] A function which takes the value and a result parameter and clones it. - * This parameter is only required if the value is not a number or string and does not have a clone function. - * - * @exception {DeveloperError} value is required. - * @exception {DeveloperError} clone is a required function. - * * @example * //Create a Cartesian2 interval property which contains data on August 1st, 2012 * //and uses a different value every 6 hours. @@ -39,26 +36,67 @@ define([ * * @example * //Create a TimeIntervalCollectionProperty that contains user-defined objects. - * var myObject = { - * value : 6 - * }; - * var myObject2 = { - * value : 12 - * }; * function cloneMyObject(value, result) { * return { * value : value.value * }; * } - * var composite = new Cesium.TimeIntervalCollectionProperty(cloneMyObject); + * + * var myObject = { + * value : 6, + * clone : cloneMyObject + * }; + * var myObject2 = { + * value : 12, + * clone : cloneMyObject + * }; + * + * var composite = new Cesium.TimeIntervalCollectionProperty(); * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', true, false, myObject)); * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, myObject2)); */ var TimeIntervalCollectionProperty = function() { - this._intervals = new TimeIntervalCollection(); + var intervals = new TimeIntervalCollection(); + var definitionChanged = new Event(); + + //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. + //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, + var that = this; + var raiseDefinitionChanged = function() { + definitionChanged.raiseEvent(that); + }; + intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); + intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); + intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); + + this._intervals = intervals; + this._definitionChanged = definitionChanged; }; defineProperties(TimeIntervalCollectionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof TimeIntervalCollectionProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + return this._intervals.isEmpty(); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof TimeIntervalCollectionProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** * Gets the interval collection. * @memberof TimeIntervalCollectionProperty.prototype diff --git a/Specs/DataSource/ColorMaterialPropertySpec.js b/Specs/DataSource/ColorMaterialPropertySpec.js deleted file mode 100644 index b026498f1cac..000000000000 --- a/Specs/DataSource/ColorMaterialPropertySpec.js +++ /dev/null @@ -1,98 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/ColorMaterialProperty', - 'DataSource/ConstantProperty', - 'DataSource/TimeIntervalCollectionProperty', - 'Core/Color', - 'Core/JulianDate', - 'Core/TimeInterval' - ], function( - ColorMaterialProperty, - ConstantProperty, - TimeIntervalCollectionProperty, - Color, - JulianDate, - TimeInterval) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor provides the expected defaults', function() { - var property = new ColorMaterialProperty(); - expect(property.color).toBeDefined(); - expect(property.getType()).toEqual('Color'); - expect(property.isConstant).toBe(true); - - var result = property.getValue(); - expect(result.color).toEqual(Color.WHITE); - }); - - it('works with constant values', function() { - var property = new ColorMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - - var result = property.getValue(new JulianDate()); - expect(result.color).toEqual(Color.RED); - }); - - it('works with undefined values', function() { - var property = new ColorMaterialProperty(); - property.color.setValue(undefined); - - var result = property.getValue(); - expect(result.hasOwnProperty('color')).toEqual(true); - expect(result.color).toBeUndefined(); - }); - - it('works with dynamic values', function() { - var property = new ColorMaterialProperty(); - property.color = new TimeIntervalCollectionProperty(); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); - - expect(property.isConstant).toBe(false); - - var result = property.getValue(start); - expect(result.color).toEqual(Color.BLUE); - }); - - it('works with a result parameter', function() { - var property = new ColorMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - - var result = { - color : Color.BLUE.clone() - }; - var returnedResult = property.getValue(new JulianDate(), result); - expect(returnedResult).toBe(result); - expect(result.color).toEqual(Color.RED); - }); - - it('equals works', function() { - var left = new ColorMaterialProperty(); - left.color = new ConstantProperty(Color.WHITE); - - var right = new ColorMaterialProperty(); - right.color = new ConstantProperty(Color.WHITE); - expect(left.equals(right)).toEqual(true); - - right.color = new ConstantProperty(Color.BLACK); - expect(left.equals(right)).toEqual(false); - }); - - it('raises definitionChanged when a color property is assigned or modified', function() { - var property = new ColorMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.color = new ConstantProperty(Color.WHITE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color.setValue(Color.BLACK); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/CompositeMaterialPropertySpec.js b/Specs/DataSource/CompositeMaterialPropertySpec.js deleted file mode 100644 index ffce5db2df7a..000000000000 --- a/Specs/DataSource/CompositeMaterialPropertySpec.js +++ /dev/null @@ -1,138 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/CompositeMaterialProperty', - 'DataSource/ColorMaterialProperty', - 'DataSource/GridMaterialProperty', - 'Core/Color', - 'Core/JulianDate', - 'Core/TimeInterval', - 'Core/TimeIntervalCollection' - ], function( - CompositeMaterialProperty, - ColorMaterialProperty, - GridMaterialProperty, - Color, - JulianDate, - TimeInterval, - TimeIntervalCollection) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('default constructor has expected values', function() { - var property = new CompositeMaterialProperty(); - expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); - expect(property.getType(new JulianDate())).toBeUndefined(); - expect(property.getValue(new JulianDate())).toBeUndefined(); - }); - - it('works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); - - var property = new CompositeMaterialProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(property.getType(interval1.start)).toEqual('Color'); - expect(result1).not.toBe(interval1.data.getValue(interval1.start)); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop); - expect(property.getType(interval2.stop)).toEqual('Grid'); - expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); - - var property = new CompositeMaterialProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = {}; - var result1 = property.getValue(interval1.start, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('equals works', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new GridMaterialProperty()); - - var left = new CompositeMaterialProperty(); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new CompositeMaterialProperty(); - right.intervals.addInterval(interval1); - - expect(left.equals(right)).toEqual(false); - - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged event in all cases', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); - - var property = new CompositeMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - interval1.data.color.setValue(Color.BLUE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - }); - - it('does not raise definitionChanged for an overwritten interval', function() { - var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); - - var property = new CompositeMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - - //interval2 overwrites interval1, so callCount should not increase. - interval1.data.color.setValue(Color.BLUE); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - }); - - it('getValue throws with no time parameter', function() { - var property = new CompositeMaterialProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('getType throws with no time parameter', function() { - var property = new CompositeMaterialProperty(); - expect(function() { - property.getType(undefined); - }).toThrowDeveloperError(); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/CompositePositionPropertySpec.js b/Specs/DataSource/CompositePositionPropertySpec.js deleted file mode 100644 index 7edcf333cd21..000000000000 --- a/Specs/DataSource/CompositePositionPropertySpec.js +++ /dev/null @@ -1,219 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/CompositePositionProperty', - 'DataSource/ConstantPositionProperty', - 'DataSource/PositionProperty', - 'Core/Cartesian3', - 'Core/JulianDate', - 'Core/ReferenceFrame', - 'Core/TimeInterval', - 'Core/TimeIntervalCollection' - ], function( - CompositePositionProperty, - ConstantPositionProperty, - PositionProperty, - Cartesian3, - JulianDate, - ReferenceFrame, - TimeInterval, - TimeIntervalCollection) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('default constructor has expected values', function() { - var property = new CompositePositionProperty(); - expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); - expect(property.getValue(new JulianDate())).toBeUndefined(); - expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); - }); - - it('constructor sets expected values', function() { - var property = new CompositePositionProperty(ReferenceFrame.INERTIAL); - expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); - }); - - it('can modify reference frame', function() { - var property = new CompositePositionProperty(); - expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); - property.referenceFrame = ReferenceFrame.INERTIAL; - expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); - }); - - it('works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(result1).not.toBe(interval1.data.getValue(interval1.start)); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop); - expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('getValue works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = new Cartesian3(); - var result1 = property.getValue(interval1.start, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('getValue works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('getValue returns in fixed frame', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var valueInertial = new Cartesian3(1, 2, 3); - var valueFixed = PositionProperty.convertToReferenceFrame(interval1.start, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); - - var result1 = property.getValue(interval1.start); - expect(result1).toEqual(valueFixed); - - var result2 = property.getValue(interval2.stop); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('getValueInReferenceFrame works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = new Cartesian3(); - var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL)); - - var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED)); - }); - - it('getValueInReferenceFrame works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6), ReferenceFrame.FIXED)); - - var property = new CompositePositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL); - expect(result1).toEqual(interval1.data.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL)); - - var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED); - expect(result2).toEqual(interval2.data.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED)); - }); - - it('equals works', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var left = new CompositePositionProperty(); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new CompositePositionProperty(); - right.intervals.addInterval(interval1); - expect(left.equals(right)).toEqual(false); - - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - - right.referenceFrame = ReferenceFrame.INTERTIAL; - expect(left.equals(right)).toEqual(false); - }); - - it('getValue throws with no time parameter', function() { - var property = new CompositePositionProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('getValueInReferenceFrame throws with no referenceFrame parameter', function() { - var property = new CompositePositionProperty(); - var time = new JulianDate(); - expect(function() { - property.getValueInReferenceFrame(time, undefined); - }).toThrowDeveloperError(); - }); - - it('raises definitionChanged event in all cases', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositePositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - }); - - it('does not raise definitionChanged for an overwritten interval', function() { - var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositePositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - - //interval2 overwrites interval1, so callCount should not increase. - interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/CompositePropertySpec.js b/Specs/DataSource/CompositePropertySpec.js deleted file mode 100644 index db876de99e84..000000000000 --- a/Specs/DataSource/CompositePropertySpec.js +++ /dev/null @@ -1,125 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/CompositeProperty', - 'DataSource/ConstantProperty', - 'Core/Cartesian3', - 'Core/JulianDate', - 'Core/TimeInterval', - 'Core/TimeIntervalCollection' - ], function( - CompositeProperty, - ConstantProperty, - Cartesian3, - JulianDate, - TimeInterval, - TimeIntervalCollection) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('default constructor has expected values', function() { - var property = new CompositeProperty(); - expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); - expect(property.getValue(new JulianDate())).toBeUndefined(); - }); - - it('works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositeProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(result1).not.toBe(interval1.data.getValue(interval1.start)); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop); - expect(result2).not.toBe(interval2.data.getValue(interval2.stop)); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositeProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = new Cartesian3(); - var result1 = property.getValue(interval1.start, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data.getValue(interval1.start)); - - var result2 = property.getValue(interval2.stop, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data.getValue(interval2.stop)); - }); - - it('equals works', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); - - var left = new CompositeProperty(); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new CompositeProperty(); - right.intervals.addInterval(interval1); - expect(left.equals(right)).toEqual(false); - - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged event in all cases', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositeProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - }); - - it('does not raise definitionChanged for an overwritten interval', function() { - var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); - var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); - - var property = new CompositeProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - - //interval2 overwrites interval1, so callCount should not increase. - interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); - }); - - it('getValue throws with no time parameter', function() { - var property = new CompositeProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/ConstantPositionPropertySpec.js b/Specs/DataSource/ConstantPositionPropertySpec.js deleted file mode 100644 index 5ddb76a4fc44..000000000000 --- a/Specs/DataSource/ConstantPositionPropertySpec.js +++ /dev/null @@ -1,130 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/ConstantPositionProperty', - 'DataSource/PositionProperty', - 'Core/Cartesian3', - 'Core/JulianDate', - 'Core/ReferenceFrame' - ], function( - ConstantPositionProperty, - PositionProperty, - Cartesian3, - JulianDate, - ReferenceFrame) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var time = new JulianDate(); - - it('Constructor sets expected defaults', function() { - var property = new ConstantPositionProperty(); - expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); - - property = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); - expect(property.referenceFrame).toBe(ReferenceFrame.INERTIAL); - }); - - it('getValue works without a result parameter', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantPositionProperty(value); - - var result = property.getValue(time); - expect(result).not.toBe(value); - expect(result).toEqual(value); - }); - - it('getValue works with a result parameter', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantPositionProperty(value); - - var expected = new Cartesian3(); - var result = property.getValue(time, expected); - expect(result).toBe(expected); - expect(expected).toEqual(value); - }); - - it('getValue returns in fixed frame', function() { - var valueInertial = new Cartesian3(1, 2, 3); - var valueFixed = PositionProperty.convertToReferenceFrame(time, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); - var property = new ConstantPositionProperty(valueInertial, ReferenceFrame.INERTIAL); - - var result = property.getValue(time); - expect(result).toEqual(valueFixed); - }); - - it('getValue works with undefined fixed value', function() { - var property = new ConstantPositionProperty(undefined); - expect(property.getValue(time)).toBeUndefined(); - }); - - it('getValue work swith undefined inertial value', function() { - var property = new ConstantPositionProperty(undefined, ReferenceFrame.INERTIAL); - expect(property.getValue(time)).toBeUndefined(); - }); - - it('getValueInReferenceFrame works without a result parameter', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantPositionProperty(value); - - var result = property.getValueInReferenceFrame(time, ReferenceFrame.INERTIAL); - expect(result).not.toBe(value); - expect(result).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL)); - }); - - it('getValueInReferenceFrame works with a result parameter', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantPositionProperty(value, ReferenceFrame.INERTIAL); - - var expected = new Cartesian3(); - var result = property.getValueInReferenceFrame(time, ReferenceFrame.FIXED, expected); - expect(result).toBe(expected); - expect(expected).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED)); - }); - - it('setValue rasies definitionChanged event', function() { - var property = new ConstantPositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - property.setValue(new Cartesian3(1, 2, 3)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - }); - - it('setValue does not raise definitionChanged event with equal data', function() { - var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0)); - spyOn(property.definitionChanged, 'raiseEvent'); - property.setValue(new Cartesian3(0, 0, 0)); - expect(property.definitionChanged.raiseEvent.callCount).toBe(0); - }); - - it('setValue raises definitionChanged when referenceFrame changes', function() { - var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0), ReferenceFrame.FIXED); - spyOn(property.definitionChanged, 'raiseEvent'); - property.setValue(new Cartesian3(0, 0, 0), ReferenceFrame.INERTIAL); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - }); - - it('equals works', function() { - var left = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); - var right = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); - - expect(left.equals(right)).toEqual(true); - - right = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.FIXED); - expect(left.equals(right)).toEqual(false); - - right = new ConstantPositionProperty(new Cartesian3(1, 2, 4), ReferenceFrame.INERTIAL); - expect(left.equals(right)).toEqual(false); - }); - - it('getValue throws without time parameter', function() { - var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('getValueInReferenceFrame throws with no referenceFrame parameter', function() { - var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); - expect(function() { - property.getValueInReferenceFrame(time, undefined); - }).toThrowDeveloperError(); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/ConstantPropertySpec.js b/Specs/DataSource/ConstantPropertySpec.js deleted file mode 100644 index ec8ea4c8d605..000000000000 --- a/Specs/DataSource/ConstantPropertySpec.js +++ /dev/null @@ -1,97 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/ConstantProperty', - 'Core/Cartesian3', - 'Core/JulianDate' - ], function( - ConstantProperty, - Cartesian3, - JulianDate) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var time = new JulianDate(); - - it('works with basic types', function() { - var expected = 5; - var property = new ConstantProperty(expected); - expect(property.getValue(time)).toBe(expected); - }); - - it('works with objects', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantProperty(value); - - var result = property.getValue(time); - expect(result).not.toBe(value); - expect(result).toEqual(value); - }); - - it('setValue rasies definitionChanged event', function() { - var property = new ConstantProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - property.setValue(5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - }); - - it('setValue does not raise definitionChanged event with equal data', function() { - var property = new ConstantProperty(new Cartesian3(0, 0, 0)); - spyOn(property.definitionChanged, 'raiseEvent'); - property.setValue(new Cartesian3(0, 0, 0)); - expect(property.definitionChanged.raiseEvent.callCount).toBe(0); - }); - - it('works with objects with result parameter', function() { - var value = new Cartesian3(1, 2, 3); - var property = new ConstantProperty(value); - - var expected = new Cartesian3(); - var result = property.getValue(time, expected); - expect(result).toBe(expected); - expect(expected).toEqual(value); - }); - - it('works with undefined value', function() { - var property = new ConstantProperty(undefined); - expect(property.getValue()).toBeUndefined(); - }); - - it('constructor throws with undefined clone function on non-basic type', function() { - expect(function() { - return new ConstantProperty({ - equals : function() { - return true; - } - }); - }).toThrowDeveloperError(); - }); - - it('constructor throws with undefined equals function on non-basic type', function() { - expect(function() { - return new ConstantProperty({ - clone : function() { - return {}; - } - }); - }).toThrowDeveloperError(); - }); - - it('equals works for object types', function() { - var left = new ConstantProperty(new Cartesian3(1, 2, 3)); - var right = new ConstantProperty(new Cartesian3(1, 2, 3)); - - expect(left.equals(right)).toEqual(true); - - right = new ConstantProperty(new Cartesian3(1, 2, 4)); - expect(left.equals(right)).toEqual(false); - }); - - it('equals works for simple types', function() { - var left = new ConstantProperty(1); - var right = new ConstantProperty(1); - - expect(left.equals(right)).toEqual(true); - - right = new ConstantProperty(2); - expect(left.equals(right)).toEqual(false); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/GridMaterialPropertySpec.js b/Specs/DataSource/GridMaterialPropertySpec.js deleted file mode 100644 index 54351e7318df..000000000000 --- a/Specs/DataSource/GridMaterialPropertySpec.js +++ /dev/null @@ -1,225 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/GridMaterialProperty', - 'DataSource/ConstantProperty', - 'DataSource/SampledProperty', - 'DataSource/TimeIntervalCollectionProperty', - 'Core/Cartesian2', - 'Core/Color', - 'Core/JulianDate', - 'Core/TimeInterval' - ], function( - GridMaterialProperty, - ConstantProperty, - SampledProperty, - TimeIntervalCollectionProperty, - Cartesian2, - Color, - JulianDate, - TimeInterval) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor provides the expected defaults', function() { - var property = new GridMaterialProperty(); - expect(property.color).toBeDefined(); - expect(property.cellAlpha).toBeDefined(); - expect(property.lineCount).toBeDefined(); - expect(property.lineThickness).toBeDefined(); - - expect(property.getType()).toEqual('Grid'); - - var result = property.getValue(); - expect(result.color).toEqual(Color.WHITE); - expect(result.cellAlpha).toEqual(0.1); - expect(result.lineCount).toEqual(new Cartesian2(8, 8)); - expect(result.lineThickness).toEqual(new Cartesian2(1.0, 1.0)); - }); - - it('works with constant values', function() { - var property = new GridMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - property.cellAlpha = new ConstantProperty(1.0); - property.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); - property.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); - - var result = property.getValue(new JulianDate()); - expect(result.color).toEqual(Color.RED); - expect(result.cellAlpha).toEqual(1); - expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); - expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); - }); - - it('works with undefined values', function() { - var property = new GridMaterialProperty(); - property.color.setValue(undefined); - property.cellAlpha.setValue(undefined); - property.lineCount.setValue(undefined); - property.lineThickness.setValue(undefined); - - var result = property.getValue(); - expect(result.hasOwnProperty('color')).toEqual(true); - expect(result.hasOwnProperty('cellAlpha')).toEqual(true); - expect(result.hasOwnProperty('lineCount')).toEqual(true); - expect(result.hasOwnProperty('lineThickness')).toEqual(true); - expect(result.color).toBeUndefined(); - expect(result.cellAlpha).toBeUndefined(); - expect(result.lineCount).toBeUndefined(); - expect(result.lineThickness).toBeUndefined(); - }); - - it('works with dynamic values', function() { - var property = new GridMaterialProperty(); - property.color = new TimeIntervalCollectionProperty(); - property.cellAlpha = new TimeIntervalCollectionProperty(); - property.lineCount = new TimeIntervalCollectionProperty(); - property.lineThickness = new TimeIntervalCollectionProperty(); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); - property.cellAlpha.intervals.addInterval(new TimeInterval(start, stop, true, true, 1.0)); - property.lineCount.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(3.4, 5.0))); - property.lineThickness.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); - - var result = property.getValue(start); - expect(result.color).toEqual(Color.BLUE); - expect(result.cellAlpha).toEqual(1); - expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); - expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); - }); - - it('works with a result parameter', function() { - var property = new GridMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - property.cellAlpha = new ConstantProperty(1.0); - property.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); - property.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); - - var result = {}; - var returnedResult = property.getValue(new JulianDate(), result); - expect(result).toBe(returnedResult); - expect(result.color).toEqual(Color.RED); - expect(result.cellAlpha).toEqual(1.0); - expect(result.lineCount).toEqual(new Cartesian2(3.4, 5.0)); - expect(result.lineThickness).toEqual(new Cartesian2(2, 3)); - }); - - it('equals works', function() { - var left = new GridMaterialProperty(); - left.color = new ConstantProperty(Color.RED); - left.cellAlpha = new ConstantProperty(1.0); - left.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); - left.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); - - var right = new GridMaterialProperty(); - right.color = new ConstantProperty(Color.RED); - right.cellAlpha = new ConstantProperty(1.0); - right.lineCount = new ConstantProperty(new Cartesian2(3.4, 5.0)); - right.lineThickness = new ConstantProperty(new Cartesian2(2, 3)); - - expect(left.equals(right)).toEqual(true); - - right.color = new ConstantProperty(Color.BLUE); - expect(left.equals(right)).toEqual(false); - - right.color = left.color; - right.cellAlpha = new ConstantProperty(0.5); - expect(left.equals(right)).toEqual(false); - - right.cellAlpha = left.cellAlpha; - right.lineCount = new ConstantProperty(new Cartesian2(4, 5.0)); - expect(left.equals(right)).toEqual(false); - - right.lineCount = left.lineCount; - right.lineThickness = new ConstantProperty(new Cartesian2(3, 2)); - expect(left.equals(right)).toEqual(false); - - right.lineThickness = left.lineThickness; - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged when a property is assigned or modified', function() { - var property = new GridMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.color = new ConstantProperty(Color.WHITE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color.setValue(Color.BLACK); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); - - property.cellAlpha = new ConstantProperty(0.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.cellAlpha.setValue(1.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.cellAlpha = property.cellAlpha; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); - - property.lineCount = new ConstantProperty(5.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.lineCount.setValue(10.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.lineCount = property.lineCount; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); - - property.lineThickness = new ConstantProperty(5.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.lineThickness.setValue(10.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.lineThickness = property.lineThickness; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - }); - - it('isConstant is only true when all properties are constant or undefined', function() { - var property = new GridMaterialProperty(); - expect(property.isConstant).toBe(true); - - property.color = undefined; - property.cellAlpha = undefined; - property.lineCount = undefined; - property.lineThickness = undefined; - expect(property.isConstant).toBe(true); - - property.color = new SampledProperty(Color); - property.color.addSample(new JulianDate(), Color.WHITE); - expect(property.isConstant).toBe(false); - - property.color = undefined; - expect(property.isConstant).toBe(true); - property.cellAlpha = new SampledProperty(Number); - property.cellAlpha.addSample(new JulianDate(), 0); - expect(property.isConstant).toBe(false); - - property.cellAlpha = undefined; - expect(property.isConstant).toBe(true); - property.lineCount = new SampledProperty(Number); - property.lineCount.addSample(new JulianDate(), 1); - expect(property.isConstant).toBe(false); - - property.lineCount = undefined; - expect(property.isConstant).toBe(true); - property.lineThickness= new SampledProperty(Number); - property.lineThickness.addSample(new JulianDate(), 1); - expect(property.isConstant).toBe(false); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/ImageMaterialPropertySpec.js b/Specs/DataSource/ImageMaterialPropertySpec.js deleted file mode 100644 index 5cfe5e31033c..000000000000 --- a/Specs/DataSource/ImageMaterialPropertySpec.js +++ /dev/null @@ -1,147 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DataSource/ImageMaterialProperty', - 'DataSource/ConstantProperty', - 'DataSource/TimeIntervalCollectionProperty', - 'Core/Cartesian2', - 'Core/JulianDate', - 'Core/TimeInterval' - ], function( - ImageMaterialProperty, - ConstantProperty, - TimeIntervalCollectionProperty, - Cartesian2, - JulianDate, - TimeInterval) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor provides the expected defaults', function() { - var property = new ImageMaterialProperty(); - expect(property.getType()).toEqual('Image'); - - var result = property.getValue(); - expect(result.image).toBeUndefined(); - expect(result.repeat).toEqual(new Cartesian2(1.0, 1.0)); - }); - - it('works with constant values', function() { - var property = new ImageMaterialProperty(); - property.image = new ConstantProperty('http://test.invalid/image.png'); - property.repeat = new ConstantProperty(new Cartesian2(2, 3)); - - var result = property.getValue(new JulianDate()); - expect(result.image).toEqual('http://test.invalid/image.png'); - expect(result.repeat).toEqual(new Cartesian2(2, 3)); - }); - - it('works with undefined values', function() { - var property = new ImageMaterialProperty(); - property.image = new ConstantProperty(); - property.repeat = new ConstantProperty(); - - var result = property.getValue(); - expect(result.hasOwnProperty('image')).toEqual(true); - expect(result.hasOwnProperty('repeat')).toEqual(true); - expect(result.image).toBeUndefined(); - expect(result.repeat).toBeUndefined(); - }); - - it('works with dynamic values', function() { - var property = new ImageMaterialProperty(); - property.image = new TimeIntervalCollectionProperty(); - property.repeat = new TimeIntervalCollectionProperty(); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.image.intervals.addInterval(new TimeInterval(start, stop, true, true, 'http://test.invalid/image.png')); - property.repeat.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); - - var result = property.getValue(start); - expect(result.image).toEqual('http://test.invalid/image.png'); - expect(result.repeat).toEqual(new Cartesian2(2, 3)); - }); - - it('works with a result parameter', function() { - var property = new ImageMaterialProperty(); - property.image = new ConstantProperty('http://test.invalid/image.png'); - property.repeat = new ConstantProperty(new Cartesian2(2, 3)); - - var result = {}; - var returnedResult = property.getValue(new JulianDate(), result); - expect(result).toBe(returnedResult); - expect(result.image).toEqual('http://test.invalid/image.png'); - expect(result.repeat).toEqual(new Cartesian2(2, 3)); - }); - - it('equals works', function() { - var left = new ImageMaterialProperty(); - left.image = new ConstantProperty('http://test.invalid/image.png'); - left.repeat = new ConstantProperty(new Cartesian2(2, 3)); - - var right = new ImageMaterialProperty(); - right.image = new ConstantProperty('http://test.invalid/image.png'); - right.repeat = new ConstantProperty(new Cartesian2(2, 3)); - - expect(left.equals(right)).toEqual(true); - - right.image = new ConstantProperty('http://test.invalid/image2.png'); - expect(left.equals(right)).toEqual(false); - - right.image = left.image; - right.repeat = new ConstantProperty(new Cartesian2(3, 2)); - expect(left.equals(right)).toEqual(false); - - right.repeat = left.repeat; - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged when a property is assigned or modified', function() { - var property = new ImageMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.image = new ConstantProperty('http://test.invalid/image.png'); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.image.setValue('http://test.invalid/image2.png'); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.image = property.image; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); - - property.repeat = new ConstantProperty(new Cartesian2(1.5, 1.5)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.repeat.setValue(new Cartesian2(1.0, 1.0)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.repeat = property.repeat; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - }); - - it('isConstant is only true when all properties are constant or undefined', function() { - var property = new ImageMaterialProperty(); - expect(property.isConstant).toBe(true); - - property.image = undefined; - property.repeat = undefined; - expect(property.isConstant).toBe(true); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.image = new TimeIntervalCollectionProperty(); - property.image.intervals.addInterval(new TimeInterval(start, stop, true, true, 'http://test.invalid/image.png')); - expect(property.isConstant).toBe(false); - - property.image = undefined; - expect(property.isConstant).toBe(true); - property.repeat = new TimeIntervalCollectionProperty(); - property.repeat.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); - expect(property.isConstant).toBe(false); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js b/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js deleted file mode 100644 index b4303427f0f2..000000000000 --- a/Specs/DataSource/PolylineOutlineMaterialPropertySpec.js +++ /dev/null @@ -1,170 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/PolylineOutlineMaterialProperty', - 'DataSource/ConstantProperty', - 'DataSource/TimeIntervalCollectionProperty', - 'Core/Color', - 'Core/JulianDate', - 'Core/TimeInterval' - ], function( - PolylineOutlineMaterialProperty, - ConstantProperty, - TimeIntervalCollectionProperty, - Color, - JulianDate, - TimeInterval) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor provides the expected defaults', function() { - var property = new PolylineOutlineMaterialProperty(); - expect(property.getType()).toEqual('PolylineOutline'); - - var result = property.getValue(); - expect(result.color).toEqual(Color.WHITE); - expect(result.outlineColor).toEqual(Color.BLACK); - expect(result.outlineWidth).toEqual(0.0); - }); - - it('works with constant values', function() { - var property = new PolylineOutlineMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - property.outlineColor = new ConstantProperty(Color.BLUE); - - var result = property.getValue(new JulianDate()); - expect(result.color).toEqual(Color.RED); - expect(result.outlineColor).toEqual(Color.BLUE); - }); - - it('works with undefined values', function() { - var property = new PolylineOutlineMaterialProperty(); - property.color.setValue(undefined); - property.outlineColor.setValue(undefined); - - var result = property.getValue(); - expect(result.hasOwnProperty('color')).toEqual(true); - expect(result.hasOwnProperty('outlineColor')).toEqual(true); - expect(result.color).toBeUndefined(); - expect(result.outlineColor).toBeUndefined(); - }); - - it('works with dynamic values', function() { - var property = new PolylineOutlineMaterialProperty(); - property.color = new TimeIntervalCollectionProperty(); - property.outlineColor = new TimeIntervalCollectionProperty(); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); - property.outlineColor.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.RED)); - - var result = property.getValue(start); - expect(result.color).toEqual(Color.BLUE); - expect(result.outlineColor).toEqual(Color.RED); - }); - - it('works with a result parameter', function() { - var property = new PolylineOutlineMaterialProperty(); - property.color = new ConstantProperty(Color.RED); - property.outlineColor = new ConstantProperty(Color.BLUE); - - var result = { - color : Color.YELLOW.clone(), - outlineColor : Color.BROWN.clone() - }; - var returnedResult = property.getValue(new JulianDate(), result); - expect(returnedResult).toBe(result); - expect(result.color).toEqual(Color.RED); - expect(result.outlineColor).toEqual(Color.BLUE); - }); - - it('equals works', function() { - var left = new PolylineOutlineMaterialProperty(); - left.color = new ConstantProperty(Color.WHITE); - left.outlineColor = new ConstantProperty(Color.BLACK); - left.outlineWidth = new ConstantProperty(5); - - var right = new PolylineOutlineMaterialProperty(); - right.color = new ConstantProperty(Color.WHITE); - right.outlineColor = new ConstantProperty(Color.BLACK); - right.outlineWidth = new ConstantProperty(5); - expect(left.equals(right)).toEqual(true); - - right.color = new ConstantProperty(Color.RED); - expect(left.equals(right)).toEqual(false); - - right.color = left.color; - right.outlineColor = new ConstantProperty(Color.BLUE); - expect(left.equals(right)).toEqual(false); - - right.outlineColor = left.outlineColor; - right.outlineWidth = new ConstantProperty(6); - expect(left.equals(right)).toEqual(false); - }); - - it('raises definitionChanged when a property is assigned or modified', function() { - var property = new PolylineOutlineMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.color = new ConstantProperty(Color.RED); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color.setValue(Color.YELLOW); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); - - property.outlineColor = new ConstantProperty(Color.BLUE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.outlineColor.setValue(Color.GREEN); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.outlineColor = property.outlineColor; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - - property.outlineWidth = new ConstantProperty(2.5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.outlineWidth.setValue(1.5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.outlineWidth = property.outlineWidth; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - }); - - it('isConstant is only true when all properties are constant or undefined', function() { - var property = new PolylineOutlineMaterialProperty(); - expect(property.isConstant).toBe(true); - - property.color = undefined; - property.outlineColor = undefined; - property.outlineWidth = undefined; - expect(property.isConstant).toBe(true); - - var start = new JulianDate(1, 0); - var stop = new JulianDate(2, 0); - property.color = new TimeIntervalCollectionProperty(); - property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.RED)); - expect(property.isConstant).toBe(false); - - property.color = undefined; - expect(property.isConstant).toBe(true); - property.outlineColor = new TimeIntervalCollectionProperty(); - property.outlineColor.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); - expect(property.isConstant).toBe(false); - - property.outlineColor = undefined; - expect(property.isConstant).toBe(true); - property.outlineWidth = new TimeIntervalCollectionProperty(); - property.outlineWidth.intervals.addInterval(new TimeInterval(start, stop, true, true, 2.0)); - expect(property.isConstant).toBe(false); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/SampledPositionPropertySpec.js b/Specs/DataSource/SampledPositionPropertySpec.js deleted file mode 100644 index 3de56a7158ee..000000000000 --- a/Specs/DataSource/SampledPositionPropertySpec.js +++ /dev/null @@ -1,263 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/SampledPositionProperty', - 'DataSource/PositionProperty', - 'Core/Cartesian3', - 'Core/defined', - 'Core/JulianDate', - 'Core/LinearApproximation', - 'Core/LagrangePolynomialApproximation', - 'Core/ReferenceFrame' - ], function( - SampledPositionProperty, - PositionProperty, - Cartesian3, - defined, - JulianDate, - LinearApproximation, - LagrangePolynomialApproximation, - ReferenceFrame) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor sets expected defaults', function() { - var property = new SampledPositionProperty(); - expect(property.referenceFrame).toEqual(ReferenceFrame.FIXED); - expect(property.interpolationDegree).toEqual(1); - expect(property.interpolationAlgorithm).toEqual(LinearApproximation); - }); - - it('constructor sets expected values', function() { - var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); - expect(property.referenceFrame).toEqual(ReferenceFrame.INERTIAL); - expect(property.interpolationDegree).toEqual(1); - expect(property.interpolationAlgorithm).toEqual(LinearApproximation); - }); - - it('getValue works without a result parameter', function() { - var time = new JulianDate(); - var value = new Cartesian3(1, 2, 3); - var property = new SampledPositionProperty(); - property.addSample(time, value); - - var result = property.getValue(time); - expect(result).not.toBe(value); - expect(result).toEqual(value); - }); - - it('getValue works with a result parameter', function() { - var time = new JulianDate(); - var value = new Cartesian3(1, 2, 3); - var property = new SampledPositionProperty(); - property.addSample(time, value); - - var expected = new Cartesian3(); - var result = property.getValue(time, expected); - expect(result).toBe(expected); - expect(expected).toEqual(value); - }); - - it('getValue returns in fixed frame', function() { - var time = new JulianDate(); - var valueInertial = new Cartesian3(1, 2, 3); - var valueFixed = PositionProperty.convertToReferenceFrame(time, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); - var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); - property.addSample(time, valueInertial); - - var result = property.getValue(time); - expect(result).toEqual(valueFixed); - }); - - it('getValueInReferenceFrame works without a result parameter', function() { - var time = new JulianDate(); - var value = new Cartesian3(1, 2, 3); - var property = new SampledPositionProperty(); - property.addSample(time, value); - - var result = property.getValueInReferenceFrame(time, ReferenceFrame.INERTIAL); - expect(result).not.toBe(value); - expect(result).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL)); - }); - - it('getValueInReferenceFrame works with a result parameter', function() { - var time = new JulianDate(); - var value = new Cartesian3(1, 2, 3); - var property = new SampledPositionProperty(ReferenceFrame.INERTIAL); - property.addSample(time, value); - - var expected = new Cartesian3(); - var result = property.getValueInReferenceFrame(time, ReferenceFrame.FIXED, expected); - expect(result).toBe(expected); - expect(expected).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED)); - }); - - it('addSamplesPackedArray works', function() { - var data = [0, 7, 8, 9, 1, 8, 9, 10, 2, 9, 10, 11]; - var epoch = new JulianDate(0, 0); - - var property = new SampledPositionProperty(); - property.addSamplesPackedArray(data, epoch); - expect(property.getValue(epoch)).toEqual(new Cartesian3(7, 8, 9)); - expect(property.getValue(new JulianDate(0, 0.5))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); - }); - - it('addSample works', function() { - var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)]; - var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; - - var property = new SampledPositionProperty(); - property.addSample(times[0], values[0]); - property.addSample(times[1], values[1]); - property.addSample(times[2], values[2]); - - expect(property.getValue(times[0])).toEqual(values[0]); - expect(property.getValue(times[1])).toEqual(values[1]); - expect(property.getValue(times[2])).toEqual(values[2]); - expect(property.getValue(new JulianDate(0.5, 0))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); - }); - - it('addSamples works', function() { - var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)]; - var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; - - var property = new SampledPositionProperty(); - property.addSamples(times, values); - expect(property.getValue(times[0])).toEqual(values[0]); - expect(property.getValue(times[1])).toEqual(values[1]); - expect(property.getValue(times[2])).toEqual(values[2]); - expect(property.getValue(new JulianDate(0.5, 0))).toEqual(new Cartesian3(7.5, 8.5, 9.5)); - }); - - it('can set interpolationAlgorithm and degree', function() { - var data = [0, 7, 8, 9, 1, 8, 9, 10, 2, 9, 10, 11]; - var epoch = new JulianDate(0, 0); - - var timesCalled = 0; - var MockInterpolation = { - type : 'Mock', - getRequiredDataPoints : function(degree) { - return 3; - }, - - interpolateOrderZero : function(x, xTable, yTable, yStride, result) { - expect(x).toEqual(1); - - expect(xTable.length).toEqual(3); - expect(xTable[0]).toBe(-2); - expect(xTable[1]).toBe(-1); - expect(xTable[2]).toBe(0); - - expect(yTable.length).toEqual(9); - expect(yTable[0]).toBe(7); - expect(yTable[1]).toBe(8); - expect(yTable[2]).toBe(9); - expect(yTable[3]).toBe(8); - expect(yTable[4]).toBe(9); - expect(yTable[5]).toBe(10); - expect(yTable[6]).toBe(9); - expect(yTable[7]).toBe(10); - expect(yTable[8]).toBe(11); - - expect(yStride).toEqual(3); - - expect(result.length).toEqual(3); - - result[0] = 2; - result[1] = 3; - result[2] = 4; - timesCalled++; - return result; - } - }; - - var property = new SampledPositionProperty(); - property.addSamplesPackedArray(data, epoch); - property.setInterpolationOptions({ - interpolationDegree : 2, - interpolationAlgorithm : MockInterpolation - }); - expect(property.getValue(epoch)).toEqual(new Cartesian3(7, 8, 9)); - expect(property.getValue(new JulianDate(0, 3))).toEqual(new Cartesian3(2, 3, 4)); - - expect(timesCalled).toEqual(1); - }); - - it('Returns undefined if trying to interpolate with less than enough samples.', function() { - var value = new Cartesian3(1, 2, 3); - var time = new JulianDate(0, 0); - - var property = new SampledPositionProperty(); - property.addSample(time, value); - - expect(property.getValue(time)).toEqual(value); - expect(property.getValue(time.addSeconds(4))).toBeUndefined(); - }); - - it('throws with no time parameter', function() { - var property = new SampledPositionProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('throws with no reference frame parameter', function() { - var property = new SampledPositionProperty(); - var time = new JulianDate(); - expect(function() { - property.getValueInReferenceFrame(time, undefined); - }).toThrowDeveloperError(); - }); - - it('equals works when interpolators differ', function() { - var left = new SampledPositionProperty(); - var right = new SampledPositionProperty(); - - expect(left.equals(right)).toEqual(true); - right.setInterpolationOptions({ - interpolationAlgorithm : LagrangePolynomialApproximation - }); - expect(left.equals(right)).toEqual(false); - }); - - it('equals works when interpolator degree differ', function() { - var left = new SampledPositionProperty(); - - left.setInterpolationOptions({ - interpolationDegree : 2, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - var right = new SampledPositionProperty(); - right.setInterpolationOptions({ - interpolationDegree : 2, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - expect(left.equals(right)).toEqual(true); - right.setInterpolationOptions({ - interpolationDegree : 3, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - expect(left.equals(right)).toEqual(false); - }); - - it('equals works when reference frames differ', function() { - var left = new SampledPositionProperty(ReferenceFrame.FIXED); - var right = new SampledPositionProperty(ReferenceFrame.INERTIAL); - expect(left.equals(right)).toEqual(false); - }); - - it('equals works when samples differ', function() { - var left = new SampledPositionProperty(); - var right = new SampledPositionProperty(); - expect(left.equals(right)).toEqual(true); - - var time = new JulianDate(); - var value = new Cartesian3(1, 2, 3); - left.addSample(time, value); - expect(left.equals(right)).toEqual(false); - - right.addSample(time, value); - expect(left.equals(right)).toEqual(true); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/SampledPropertySpec.js b/Specs/DataSource/SampledPropertySpec.js deleted file mode 100644 index bd4a54c0623c..000000000000 --- a/Specs/DataSource/SampledPropertySpec.js +++ /dev/null @@ -1,371 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/SampledProperty', - 'Core/defined', - 'Core/JulianDate', - 'Core/LinearApproximation', - 'Core/LagrangePolynomialApproximation' - ], function( - SampledProperty, - defined, - JulianDate, - LinearApproximation, - LagrangePolynomialApproximation) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('constructor sets expected defaults', function() { - var property = new SampledProperty(Number); - expect(property.interpolationDegree).toEqual(1); - expect(property.interpolationAlgorithm).toEqual(LinearApproximation); - expect(property.isConstant).toEqual(true); - }); - - it('isConstant works', function() { - var property = new SampledProperty(Number); - expect(property.isConstant).toEqual(true); - property.addSample(new JulianDate(0, 0), 1); - expect(property.isConstant).toEqual(false); - }); - - it('addSamplesPackedArray works', function() { - var data = [0, 7, 1, 8, 2, 9]; - var epoch = new JulianDate(0, 0); - - var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.addSamplesPackedArray(data, epoch); - - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - expect(property.getValue(epoch)).toEqual(7); - expect(property.getValue(new JulianDate(0, 0.5))).toEqual(7.5); - }); - - it('addSample works', function() { - var values = [7, 8, 9]; - var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; - - var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.addSample(times[0], values[0]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.addSample(times[1], values[1]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.addSample(times[2], values[2]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - expect(property.getValue(times[0])).toEqual(values[0]); - expect(property.getValue(times[1])).toEqual(values[1]); - expect(property.getValue(times[2])).toEqual(values[2]); - expect(property.getValue(new JulianDate(0.5, 0))).toEqual(7.5); - }); - - it('addSamples works', function() { - var values = [7, 8, 9]; - var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; - - var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); - property.addSamples(times, values); - - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - expect(property.getValue(times[0])).toEqual(values[0]); - expect(property.getValue(times[1])).toEqual(values[1]); - expect(property.getValue(times[2])).toEqual(values[2]); - expect(property.getValue(new JulianDate(0.5, 0))).toEqual(7.5); - }); - - it('works with PackableForInterpolation', function() { - var CustomType = function(value) { - this.x = value; - }; - - CustomType.packedLength = 1; - - CustomType.packedInterpolationLength = 2; - - CustomType.pack = function(value, array, startingIndex) { - array[startingIndex] = value.x; - }; - - CustomType.unpack = function(array, startingIndex, result) { - return array[startingIndex]; - }; - - CustomType.convertPackedArrayForInterpolation = function(packedArray, startingIndex, lastIndex, result) { - for ( var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { - var offset = i * 2; - result[offset] = packedArray[i] * 0.5; - result[offset + 1] = packedArray[i] * 0.5; - } - }; - - CustomType.unpackInterpolationResult = function(array, sourceArray, firstIndex, lastIndex, result) { - if (!defined(result)) { - result = new CustomType(); - } - result.x = array[0] + array[1]; - return result; - }; - - var values = [new CustomType(0), new CustomType(2), new CustomType(4)]; - var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; - - var property = new SampledProperty(CustomType); - property.addSample(times[0], values[0]); - property.addSample(times[1], values[1]); - property.addSample(times[2], values[2]); - - expect(property.getValue(new JulianDate(0.5, 0)).x).toEqual(1); - }); - - it('can set interpolationAlgorithm and degree', function() { - var data = [0, 7, 2, 9, 4, 11]; - var epoch = new JulianDate(0, 0); - - var timesCalled = 0; - var MockInterpolation = { - type : 'Mock', - getRequiredDataPoints : function(degree) { - return 3; - }, - - interpolateOrderZero : function(x, xTable, yTable, yStride, result) { - expect(x).toEqual(-1); - - expect(xTable.length).toEqual(3); - expect(xTable[0]).toBe(-4); - expect(xTable[1]).toBe(-2); - expect(xTable[2]).toBe(0); - - expect(yTable.length).toEqual(3); - expect(yTable[0]).toBe(7); - expect(yTable[1]).toBe(9); - expect(yTable[2]).toBe(11); - - expect(yStride).toEqual(1); - - expect(result.length).toEqual(1); - - result[0] = 2; - timesCalled++; - return result; - } - }; - - var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.addSamplesPackedArray(data, epoch); - - expect(property.getValue(epoch)).toEqual(7); - expect(property.getValue(new JulianDate(0, 1))).toEqual(8); - - property.setInterpolationOptions({ - interpolationAlgorithm : MockInterpolation, - interpolationDegree : 2 - }); - - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - expect(property.getValue(epoch)).toEqual(7); - expect(property.getValue(new JulianDate(0, 3))).toEqual(2); - - expect(timesCalled).toEqual(1); - }); - - it('Returns undefined if trying to interpolate with less than enough samples.', function() { - var value = 7; - var time = new JulianDate(0, 0); - - var property = new SampledProperty(Number); - property.addSample(time, value); - - expect(property.getValue(time)).toEqual(value); - expect(property.getValue(time.addSeconds(4))).toBeUndefined(); - }); - - it('mergeNewSamples works with huge data sets.', function() { - var times = []; - var values = []; - var epoch = new JulianDate(); - - var data = []; - var expectedTimes = []; - var expectedValues = []; - - for ( var i = 0; i < 200000; i++) { - data.push(i); - data.push(i); - expectedTimes.push(epoch.addSeconds(i)); - expectedValues.push(i); - } - - SampledProperty._mergeNewSamples(epoch, times, values, data, 1); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - it('mergeNewSamples works for sorted non-intersecting data.', function() { - var times = []; - var values = []; - var epoch = new JulianDate(); - - var newData = [0, 'a', 1, 'b', 2, 'c']; - var newData2 = [3, 'd', 4, 'e', 5, 'f']; - - var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; - var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; - - SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); - SampledProperty._mergeNewSamples(epoch, times, values, newData2, 1); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - it('mergeNewSamples works for ISO8601 dates', function() { - var times = []; - var values = []; - var epoch = JulianDate.fromIso8601('2010-01-01T12:00:00'); - - var newData = ['2010-01-01T12:00:00', 'a', '2010-01-01T12:00:01', 'b', '2010-01-01T12:00:02', 'c']; - var newData2 = ['2010-01-01T12:00:03', 'd', '2010-01-01T12:00:04', 'e', '2010-01-01T12:00:05', 'f']; - - var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; - var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; - - SampledProperty._mergeNewSamples(undefined, times, values, newData, 1); - SampledProperty._mergeNewSamples(undefined, times, values, newData2, 1); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - it('mergeNewSamples works for elements of size 2.', function() { - var times = []; - var values = []; - var epoch = new JulianDate(); - - var newData = [1, 'b', 'b', 4, 'e', 'e', 0, 'a', 'a']; - var newData2 = [2, 'c', 'c', 3, 'd', 'd']; - - var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4)]; - var expectedValues = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'e', 'e']; - - SampledProperty._mergeNewSamples(epoch, times, values, newData, 2); - SampledProperty._mergeNewSamples(epoch, times, values, newData2, 2); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - it('mergeNewSamples works for unsorted intersecting data.', function() { - var times = []; - var values = []; - var epoch = new JulianDate(); - - var newData = [1, 'b', 4, 'e', 0, 'a']; - var newData2 = [5, 'f', 2, 'c', 3, 'd']; - - var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(2), epoch.addSeconds(3), epoch.addSeconds(4), epoch.addSeconds(5)]; - var expectedValues = ['a', 'b', 'c', 'd', 'e', 'f']; - - SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); - SampledProperty._mergeNewSamples(epoch, times, values, newData2, 1); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - it('mergeNewSamples works for data with repeated values.', function() { - var times = []; - var values = []; - var epoch = new JulianDate(); - - var newData = [0, 'a', 1, 'b', 1, 'c', 0, 'd', 4, 'e', 5, 'f']; - var expectedTimes = [epoch.addSeconds(0), epoch.addSeconds(1), epoch.addSeconds(4), epoch.addSeconds(5)]; - var expectedValues = ['d', 'c', 'e', 'f']; - SampledProperty._mergeNewSamples(epoch, times, values, newData, 1); - - expect(times).toEqual(expectedTimes, JulianDate.compare); - expect(values).toEqual(expectedValues); - }); - - var interwovenData = [{ - epoch : JulianDate.fromIso8601("20130205T150405.704999999999927Z"), - values : [0.0, 1, 120.0, 2, 240.0, 3, 360.0, 4, 480.0, 6, 600.0, 8, 720.0, 10, 840.0, 12, 960.0, 14, 1080.0, 16] - }, { - epoch : JulianDate.fromIso8601("20130205T151151.60499999999956Z"), - values : [0.0, 5, 120.0, 7, 240.0, 9, 360.0, 11, 480.0, 13, 600.0, 15, 720.0, 17, 840.0, 18, 960.0, 19, 1080.0, 20] - }]; - - it('mergeNewSamples works with interwoven data', function() { - var times = []; - var values = []; - SampledProperty._mergeNewSamples(interwovenData[0].epoch, times, values, interwovenData[0].values, 1); - SampledProperty._mergeNewSamples(interwovenData[1].epoch, times, values, interwovenData[1].values, 1); - for ( var i = 0; i < values.length; i++) { - expect(values[i]).toBe(i + 1); - } - }); - - it('constructor throws without type parameter.', function() { - expect(function() { - return new SampledProperty(undefined); - }).toThrowDeveloperError(); - }); - - it('equals works when interpolators differ', function() { - var left = new SampledProperty(Number); - var right = new SampledProperty(Number); - - expect(left.equals(right)).toEqual(true); - right.setInterpolationOptions({ - interpolationAlgorithm : LagrangePolynomialApproximation - }); - expect(left.equals(right)).toEqual(false); - }); - - it('equals works when interpolator degree differ', function() { - var left = new SampledProperty(Number); - - left.setInterpolationOptions({ - interpolationDegree : 2, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - var right = new SampledProperty(Number); - right.setInterpolationOptions({ - interpolationDegree : 2, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - expect(left.equals(right)).toEqual(true); - right.setInterpolationOptions({ - interpolationDegree : 3, - interpolationAlgorithm : LagrangePolynomialApproximation - }); - - expect(left.equals(right)).toEqual(false); - }); - - it('equals works when samples differ', function() { - var left = new SampledProperty(Number); - var right = new SampledProperty(Number); - expect(left.equals(right)).toEqual(true); - - var time = new JulianDate(); - left.addSample(time, 5); - expect(left.equals(right)).toEqual(false); - - right.addSample(time, 5); - expect(left.equals(right)).toEqual(true); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js deleted file mode 100644 index 5356632e935a..000000000000 --- a/Specs/DataSource/TimeIntervalCollectionPositionPropertySpec.js +++ /dev/null @@ -1,180 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/TimeIntervalCollectionPositionProperty', - 'DataSource/PositionProperty', - 'Core/Cartesian3', - 'Core/JulianDate', - 'Core/ReferenceFrame', - 'Core/TimeInterval', - 'Core/TimeIntervalCollection' - ], function( - TimeIntervalCollectionPositionProperty, - PositionProperty, - Cartesian3, - JulianDate, - ReferenceFrame, - TimeInterval, - TimeIntervalCollection) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('default constructor has expected values', function() { - var property = new TimeIntervalCollectionPositionProperty(); - expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); - expect(property.getValue(new JulianDate())).toBeUndefined(); - expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); - }); - - it('getValue works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionPositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(result1).not.toBe(interval1.data); - expect(result1).toEqual(interval1.data); - - var result2 = property.getValue(interval2.stop); - expect(result2).not.toBe(interval2.data); - expect(result2).toEqual(interval2.data); - }); - - it('getValue works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionPositionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = new Cartesian3(); - var result1 = property.getValue(interval1.start, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data); - - var result2 = property.getValue(interval2.stop, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data); - }); - - it('getValue returns in fixed frame', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - - var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.INERTIAL); - property.intervals.addInterval(interval1); - - var valueInertial = new Cartesian3(1, 2, 3); - var valueFixed = PositionProperty.convertToReferenceFrame(interval1.start, valueInertial, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED); - - var result = property.getValue(interval1.start); - expect(result).toEqual(valueFixed); - }); - - it('getValueInReferenceFrame works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var valueInertial = PositionProperty.convertToReferenceFrame(interval1.start, interval1.data, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL); - - var expected = new Cartesian3(); - var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(valueInertial); - - var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data); - }); - - it('getValueInReferenceFrame works without a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var valueInertial = PositionProperty.convertToReferenceFrame(interval1.start, interval1.data, ReferenceFrame.FIXED, ReferenceFrame.INERTIAL); - - var result1 = property.getValueInReferenceFrame(interval1.start, ReferenceFrame.INERTIAL); - expect(result1).toEqual(valueInertial); - - var result2 = property.getValueInReferenceFrame(interval2.stop, ReferenceFrame.FIXED); - expect(result2).toEqual(interval2.data); - }); - - it('returns undefined for valid interval without data', function() { - var property = new TimeIntervalCollectionPositionProperty(); - - var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, undefined); - property.intervals.addInterval(interval); - - var result = property.getValue(interval.start); - expect(result).toBeUndefined(); - }); - - it('throws with no time parameter', function() { - var property = new TimeIntervalCollectionPositionProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('throws with no reference frame parameter', function() { - var property = new TimeIntervalCollectionPositionProperty(); - var time = new JulianDate(); - expect(function() { - property.getValueInReferenceFrame(time, undefined); - }).toThrowDeveloperError(); - }); - - it('equals works for differing referenceFrames', function() { - var left = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - var right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.INERTIAL); - expect(left.equals(right)).toEqual(false); - - right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - expect(left.equals(right)).toEqual(true); - }); - - it('equals works for differing intervals', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var left = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new TimeIntervalCollectionPositionProperty(ReferenceFrame.FIXED); - right.intervals.addInterval(interval1); - - expect(left.equals(right)).toEqual(false); - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged event', function() { - var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - - var property = new TimeIntervalCollectionPositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.removeInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - - property.intervals.addInterval(interval); - property.definitionChanged.raiseEvent.reset(); - property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - }); -}); \ No newline at end of file diff --git a/Specs/DataSource/TimeIntervalCollectionPropertySpec.js b/Specs/DataSource/TimeIntervalCollectionPropertySpec.js deleted file mode 100644 index a79b892ebd7c..000000000000 --- a/Specs/DataSource/TimeIntervalCollectionPropertySpec.js +++ /dev/null @@ -1,128 +0,0 @@ -/*global defineSuite*/ -defineSuite(['DataSource/TimeIntervalCollectionProperty', - 'Core/Cartesian3', - 'Core/JulianDate', - 'Core/TimeInterval', - 'Core/TimeIntervalCollection' - ], function( - TimeIntervalCollectionProperty, - Cartesian3, - JulianDate, - TimeInterval, - TimeIntervalCollection) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - it('default constructor has expected values', function() { - var property = new TimeIntervalCollectionProperty(); - expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); - expect(property.getValue(new JulianDate())).toBeUndefined(); - expect(property.isConstant).toBe(true); - }); - - it('works with basic types', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, 5); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, 6); - - var property = new TimeIntervalCollectionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - expect(property.getValue(interval1.start)).toBe(interval1.data); - expect(property.getValue(interval2.stop)).toBe(interval2.data); - expect(property.isConstant).toBe(false); - }); - - it('works with clonable objects', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var result1 = property.getValue(interval1.start); - expect(result1).not.toBe(interval1.data); - expect(result1).toEqual(interval1.data); - - var result2 = property.getValue(interval2.stop); - expect(result2).not.toBe(interval2.data); - expect(result2).toEqual(interval2.data); - }); - - it('works with a result parameter', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var property = new TimeIntervalCollectionProperty(); - property.intervals.addInterval(interval1); - property.intervals.addInterval(interval2); - - var expected = new Cartesian3(); - var result1 = property.getValue(interval1.start, expected); - expect(result1).toBe(expected); - expect(result1).toEqual(interval1.data); - - var result2 = property.getValue(interval2.stop, expected); - expect(result2).toBe(expected); - expect(result2).toEqual(interval2.data); - }); - - it('throws with no time parameter', function() { - var property = new TimeIntervalCollectionProperty(); - expect(function() { - property.getValue(undefined); - }).toThrowDeveloperError(); - }); - - it('equals works for differing basic type intervals', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, 5); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, 6); - - var left = new TimeIntervalCollectionProperty(); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new TimeIntervalCollectionProperty(); - right.intervals.addInterval(interval1); - - expect(left.equals(right)).toEqual(false); - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - }); - - it('equals works for differing complex type intervals', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new Cartesian3(4, 5, 6)); - - var left = new TimeIntervalCollectionProperty(); - left.intervals.addInterval(interval1); - left.intervals.addInterval(interval2); - - var right = new TimeIntervalCollectionProperty(); - right.intervals.addInterval(interval1); - - expect(left.equals(right)).toEqual(false); - right.intervals.addInterval(interval2); - expect(left.equals(right)).toEqual(true); - }); - - it('raises definitionChanged event', function() { - var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); - - var property = new TimeIntervalCollectionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); - - property.intervals.addInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); - - property.intervals.removeInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - - property.intervals.addInterval(interval); - property.definitionChanged.raiseEvent.reset(); - property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - }); -}); \ No newline at end of file diff --git a/Specs/DynamicScene/ColorMaterialPropertySpec.js b/Specs/DynamicScene/ColorMaterialPropertySpec.js index 505b08cc67c2..bf614d19f636 100644 --- a/Specs/DynamicScene/ColorMaterialPropertySpec.js +++ b/Specs/DynamicScene/ColorMaterialPropertySpec.js @@ -1,27 +1,25 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/ColorMaterialProperty', +defineSuite(['DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', 'DynamicScene/TimeIntervalCollectionProperty', 'Core/Color', 'Core/JulianDate', - 'Core/TimeInterval', - 'Specs/UndefinedProperty' + 'Core/TimeInterval' ], function( ColorMaterialProperty, ConstantProperty, TimeIntervalCollectionProperty, Color, JulianDate, - TimeInterval, - UndefinedProperty) { + TimeInterval) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('works with basic types', function() { + it('constructor provides the expected defaults', function() { var property = new ColorMaterialProperty(); expect(property.color).toBeDefined(); expect(property.getType()).toEqual('Color'); + expect(property.isConstant).toBe(true); var result = property.getValue(); expect(result.color).toEqual(Color.WHITE); @@ -37,7 +35,7 @@ defineSuite([ it('works with undefined values', function() { var property = new ColorMaterialProperty(); - property.color = new UndefinedProperty(); + property.color.setValue(undefined); var result = property.getValue(); expect(result.hasOwnProperty('color')).toEqual(true); @@ -52,6 +50,8 @@ defineSuite([ var stop = new JulianDate(2, 0); property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + expect(property.isConstant).toBe(false); + var result = property.getValue(start); expect(result.color).toEqual(Color.BLUE); }); @@ -79,4 +79,20 @@ defineSuite([ right.color = new ConstantProperty(Color.BLACK); expect(left.equals(right)).toEqual(false); }); + + it('raises definitionChanged when a color property is assigned or modified', function() { + var property = new ColorMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.WHITE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.BLACK); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/CompositeMaterialPropertySpec.js b/Specs/DynamicScene/CompositeMaterialPropertySpec.js index cd36375bf641..156b5e942a8c 100644 --- a/Specs/DynamicScene/CompositeMaterialPropertySpec.js +++ b/Specs/DynamicScene/CompositeMaterialPropertySpec.js @@ -1,17 +1,16 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/CompositeMaterialProperty', - 'DynamicScene/ConstantProperty', +defineSuite(['DynamicScene/CompositeMaterialProperty', 'DynamicScene/ColorMaterialProperty', 'DynamicScene/GridMaterialProperty', + 'Core/Color', 'Core/JulianDate', 'Core/TimeInterval', 'Core/TimeIntervalCollection' ], function( CompositeMaterialProperty, - ConstantProperty, ColorMaterialProperty, GridMaterialProperty, + Color, JulianDate, TimeInterval, TimeIntervalCollection) { @@ -79,6 +78,50 @@ defineSuite([ expect(left.equals(right)).toEqual(true); }); + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + + var property = new CompositeMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.color.setValue(Color.BLUE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ColorMaterialProperty()); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + + var property = new CompositeMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.color.setValue(Color.BLUE); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); + it('getValue throws with no time parameter', function() { var property = new CompositeMaterialProperty(); expect(function() { diff --git a/Specs/DynamicScene/CompositePositionPropertySpec.js b/Specs/DynamicScene/CompositePositionPropertySpec.js index e93edc93dd83..925392616bc9 100644 --- a/Specs/DynamicScene/CompositePositionPropertySpec.js +++ b/Specs/DynamicScene/CompositePositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/CompositePositionProperty', +defineSuite(['DynamicScene/CompositePositionProperty', 'DynamicScene/ConstantPositionProperty', 'DynamicScene/PositionProperty', 'Core/Cartesian3', @@ -173,4 +172,48 @@ defineSuite([ property.getValueInReferenceFrame(time, undefined); }).toThrowDeveloperError(); }); + + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantPositionProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositePositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/CompositePropertySpec.js b/Specs/DynamicScene/CompositePropertySpec.js index 0e6cdbbc5338..d192cec4a712 100644 --- a/Specs/DynamicScene/CompositePropertySpec.js +++ b/Specs/DynamicScene/CompositePropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/CompositeProperty', +defineSuite(['DynamicScene/CompositeProperty', 'DynamicScene/ConstantProperty', 'Core/Cartesian3', 'Core/JulianDate', @@ -73,6 +72,50 @@ defineSuite([ expect(left.equals(right)).toEqual(true); }); + it('raises definitionChanged event in all cases', function() { + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + }); + + it('does not raise definitionChanged for an overwritten interval', function() { + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ConstantProperty(new Cartesian3(1, 2, 3))); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); + + var property = new CompositeProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval1); + property.intervals.addInterval(interval2); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + + //interval2 overwrites interval1, so callCount should not increase. + interval1.data.setValue(new Cartesian3()); + expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + }); + it('getValue throws with no time parameter', function() { var property = new CompositeProperty(); expect(function() { diff --git a/Specs/DynamicScene/ConstantPositionPropertySpec.js b/Specs/DynamicScene/ConstantPositionPropertySpec.js index ea12530c5946..17987a9864a3 100644 --- a/Specs/DynamicScene/ConstantPositionPropertySpec.js +++ b/Specs/DynamicScene/ConstantPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/ConstantPositionProperty', +defineSuite(['DynamicScene/ConstantPositionProperty', 'DynamicScene/PositionProperty', 'Core/Cartesian3', 'Core/JulianDate', @@ -17,7 +16,7 @@ defineSuite([ var time = new JulianDate(); it('Constructor sets expected defaults', function() { - var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); + var property = new ConstantPositionProperty(); expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); property = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); @@ -52,6 +51,16 @@ defineSuite([ expect(result).toEqual(valueFixed); }); + it('getValue works with undefined fixed value', function() { + var property = new ConstantPositionProperty(undefined); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('getValue work swith undefined inertial value', function() { + var property = new ConstantPositionProperty(undefined, ReferenceFrame.INERTIAL); + expect(property.getValue(time)).toBeUndefined(); + }); + it('getValueInReferenceFrame works without a result parameter', function() { var value = new Cartesian3(1, 2, 3); var property = new ConstantPositionProperty(value); @@ -71,6 +80,27 @@ defineSuite([ expect(expected).toEqual(PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.INERTIAL, ReferenceFrame.FIXED)); }); + it('setValue rasies definitionChanged event', function() { + var property = new ConstantPositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(1, 2, 3)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('setValue does not raise definitionChanged event with equal data', function() { + var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0)); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0)); + expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + }); + + it('setValue raises definitionChanged when referenceFrame changes', function() { + var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0), ReferenceFrame.FIXED); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0), ReferenceFrame.INERTIAL); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + it('equals works', function() { var left = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); var right = new ConstantPositionProperty(new Cartesian3(1, 2, 3), ReferenceFrame.INERTIAL); @@ -84,12 +114,6 @@ defineSuite([ expect(left.equals(right)).toEqual(false); }); - it('constructor throws with undefined value', function() { - expect(function() { - return new ConstantPositionProperty(undefined); - }).toThrowDeveloperError(); - }); - it('getValue throws without time parameter', function() { var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); expect(function() { @@ -99,7 +123,6 @@ defineSuite([ it('getValueInReferenceFrame throws with no referenceFrame parameter', function() { var property = new ConstantPositionProperty(new Cartesian3(1, 2, 3)); - var time = new JulianDate(); expect(function() { property.getValueInReferenceFrame(time, undefined); }).toThrowDeveloperError(); diff --git a/Specs/DynamicScene/ConstantPropertySpec.js b/Specs/DynamicScene/ConstantPropertySpec.js index a24d5e23e72d..08e17ff73ffd 100644 --- a/Specs/DynamicScene/ConstantPropertySpec.js +++ b/Specs/DynamicScene/ConstantPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/ConstantProperty', +defineSuite(['DynamicScene/ConstantProperty', 'Core/Cartesian3', 'Core/JulianDate' ], function( @@ -18,7 +17,7 @@ defineSuite([ expect(property.getValue(time)).toBe(expected); }); - it('works with clonable objects', function() { + it('works with objects', function() { var value = new Cartesian3(1, 2, 3); var property = new ConstantProperty(value); @@ -27,7 +26,21 @@ defineSuite([ expect(result).toEqual(value); }); - it('works with clonable objects with result parameter', function() { + it('setValue rasies definitionChanged event', function() { + var property = new ConstantProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('setValue does not raise definitionChanged event with equal data', function() { + var property = new ConstantProperty(new Cartesian3(0, 0, 0)); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue(new Cartesian3(0, 0, 0)); + expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + }); + + it('works with objects with result parameter', function() { var value = new Cartesian3(1, 2, 3); var property = new ConstantProperty(value); @@ -37,10 +50,9 @@ defineSuite([ expect(expected).toEqual(value); }); - it('constructor throws with undefined value', function() { - expect(function() { - return new ConstantProperty(undefined); - }).toThrowDeveloperError(); + it('works with undefined value', function() { + var property = new ConstantProperty(undefined); + expect(property.getValue()).toBeUndefined(); }); it('constructor throws with undefined clone function on non-basic type', function() { diff --git a/Specs/DynamicScene/GridMaterialPropertySpec.js b/Specs/DynamicScene/GridMaterialPropertySpec.js index 6b6da656468e..7041f12442fc 100644 --- a/Specs/DynamicScene/GridMaterialPropertySpec.js +++ b/Specs/DynamicScene/GridMaterialPropertySpec.js @@ -1,26 +1,25 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/GridMaterialProperty', +defineSuite(['DynamicScene/GridMaterialProperty', 'DynamicScene/ConstantProperty', + 'DynamicScene/SampledProperty', 'DynamicScene/TimeIntervalCollectionProperty', 'Core/Cartesian2', 'Core/Color', 'Core/JulianDate', - 'Core/TimeInterval', - 'Specs/UndefinedProperty' + 'Core/TimeInterval' ], function( GridMaterialProperty, ConstantProperty, + SampledProperty, TimeIntervalCollectionProperty, Cartesian2, Color, JulianDate, - TimeInterval, - UndefinedProperty) { + TimeInterval) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('works with basic types', function() { + it('constructor provides the expected defaults', function() { var property = new GridMaterialProperty(); expect(property.color).toBeDefined(); expect(property.cellAlpha).toBeDefined(); @@ -52,10 +51,10 @@ defineSuite([ it('works with undefined values', function() { var property = new GridMaterialProperty(); - property.color = new UndefinedProperty(); - property.cellAlpha = new UndefinedProperty(); - property.lineCount = new UndefinedProperty(); - property.lineThickness = new UndefinedProperty(); + property.color.setValue(undefined); + property.cellAlpha.setValue(undefined); + property.lineCount.setValue(undefined); + property.lineThickness.setValue(undefined); var result = property.getValue(); expect(result.hasOwnProperty('color')).toEqual(true); @@ -138,4 +137,89 @@ defineSuite([ right.lineThickness = left.lineThickness; expect(left.equals(right)).toEqual(true); }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new GridMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.WHITE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.BLACK); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha = new ConstantProperty(0.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha.setValue(1.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.cellAlpha = property.cellAlpha; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount = new ConstantProperty(5.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount.setValue(10.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineCount = property.lineCount; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness = new ConstantProperty(5.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness.setValue(10.0); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.lineThickness = property.lineThickness; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new GridMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.color = undefined; + property.cellAlpha = undefined; + property.lineCount = undefined; + property.lineThickness = undefined; + expect(property.isConstant).toBe(true); + + property.color = new SampledProperty(Color); + property.color.addSample(new JulianDate(), Color.WHITE); + expect(property.isConstant).toBe(false); + + property.color = undefined; + expect(property.isConstant).toBe(true); + property.cellAlpha = new SampledProperty(Number); + property.cellAlpha.addSample(new JulianDate(), 0); + expect(property.isConstant).toBe(false); + + property.cellAlpha = undefined; + expect(property.isConstant).toBe(true); + property.lineCount = new SampledProperty(Number); + property.lineCount.addSample(new JulianDate(), 1); + expect(property.isConstant).toBe(false); + + property.lineCount = undefined; + expect(property.isConstant).toBe(true); + property.lineThickness= new SampledProperty(Number); + property.lineThickness.addSample(new JulianDate(), 1); + expect(property.isConstant).toBe(false); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/ImageMaterialPropertySpec.js b/Specs/DynamicScene/ImageMaterialPropertySpec.js index 833583dd366f..e12993d4ebea 100644 --- a/Specs/DynamicScene/ImageMaterialPropertySpec.js +++ b/Specs/DynamicScene/ImageMaterialPropertySpec.js @@ -5,24 +5,19 @@ defineSuite([ 'DynamicScene/TimeIntervalCollectionProperty', 'Core/Cartesian2', 'Core/JulianDate', - 'Core/TimeInterval', - 'Specs/UndefinedProperty' + 'Core/TimeInterval' ], function( ImageMaterialProperty, ConstantProperty, TimeIntervalCollectionProperty, Cartesian2, JulianDate, - TimeInterval, - UndefinedProperty) { + TimeInterval) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('works with basic types', function() { + it('constructor provides the expected defaults', function() { var property = new ImageMaterialProperty(); - expect(property.image).toBeUndefined(); - expect(property.repeat).toBeDefined(); - expect(property.getType()).toEqual('Image'); var result = property.getValue(); @@ -42,8 +37,8 @@ defineSuite([ it('works with undefined values', function() { var property = new ImageMaterialProperty(); - property.image = new UndefinedProperty(); - property.repeat = new UndefinedProperty(); + property.image = new ConstantProperty(); + property.repeat = new ConstantProperty(); var result = property.getValue(); expect(result.hasOwnProperty('image')).toEqual(true); @@ -100,4 +95,53 @@ defineSuite([ right.repeat = left.repeat; expect(left.equals(right)).toEqual(true); }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new ImageMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.image = new ConstantProperty('http://test.invalid/image.png'); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.image.setValue('http://test.invalid/image2.png'); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.image = property.image; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.repeat = new ConstantProperty(new Cartesian2(1.5, 1.5)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.repeat.setValue(new Cartesian2(1.0, 1.0)); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.repeat = property.repeat; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new ImageMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.image = undefined; + property.repeat = undefined; + expect(property.isConstant).toBe(true); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.image = new TimeIntervalCollectionProperty(); + property.image.intervals.addInterval(new TimeInterval(start, stop, true, true, 'http://test.invalid/image.png')); + expect(property.isConstant).toBe(false); + + property.image = undefined; + expect(property.isConstant).toBe(true); + property.repeat = new TimeIntervalCollectionProperty(); + property.repeat.intervals.addInterval(new TimeInterval(start, stop, true, true, new Cartesian2(2, 3))); + expect(property.isConstant).toBe(false); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js index cdb025b14873..de8a3d4b2b32 100644 --- a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js +++ b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js @@ -1,32 +1,28 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/PolylineOutlineMaterialProperty', +defineSuite(['DynamicScene/PolylineOutlineMaterialProperty', 'DynamicScene/ConstantProperty', 'DynamicScene/TimeIntervalCollectionProperty', 'Core/Color', 'Core/JulianDate', - 'Core/TimeInterval', - 'Specs/UndefinedProperty' + 'Core/TimeInterval' ], function( PolylineOutlineMaterialProperty, ConstantProperty, TimeIntervalCollectionProperty, Color, JulianDate, - TimeInterval, - UndefinedProperty) { + TimeInterval) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('works with basic types', function() { + it('constructor provides the expected defaults', function() { var property = new PolylineOutlineMaterialProperty(); - expect(property.color).toBeDefined(); - expect(property.outlineColor).toBeDefined(); expect(property.getType()).toEqual('PolylineOutline'); var result = property.getValue(); expect(result.color).toEqual(Color.WHITE); expect(result.outlineColor).toEqual(Color.BLACK); + expect(result.outlineWidth).toEqual(0.0); }); it('works with constant values', function() { @@ -41,8 +37,8 @@ defineSuite([ it('works with undefined values', function() { var property = new PolylineOutlineMaterialProperty(); - property.color = new UndefinedProperty(); - property.outlineColor = new UndefinedProperty(); + property.color.setValue(undefined); + property.outlineColor.setValue(undefined); var result = property.getValue(); expect(result.hasOwnProperty('color')).toEqual(true); @@ -104,4 +100,71 @@ defineSuite([ right.outlineWidth = new ConstantProperty(6); expect(left.equals(right)).toEqual(false); }); + + it('raises definitionChanged when a property is assigned or modified', function() { + var property = new PolylineOutlineMaterialProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.color = new ConstantProperty(Color.RED); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color.setValue(Color.YELLOW); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.color = property.color; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor = new ConstantProperty(Color.BLUE); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor.setValue(Color.GREEN); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineColor = property.outlineColor; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + + property.outlineWidth = new ConstantProperty(2.5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineWidth.setValue(1.5); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.outlineWidth = property.outlineWidth; + expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + }); + + it('isConstant is only true when all properties are constant or undefined', function() { + var property = new PolylineOutlineMaterialProperty(); + expect(property.isConstant).toBe(true); + + property.color = undefined; + property.outlineColor = undefined; + property.outlineWidth = undefined; + expect(property.isConstant).toBe(true); + + var start = new JulianDate(1, 0); + var stop = new JulianDate(2, 0); + property.color = new TimeIntervalCollectionProperty(); + property.color.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.RED)); + expect(property.isConstant).toBe(false); + + property.color = undefined; + expect(property.isConstant).toBe(true); + property.outlineColor = new TimeIntervalCollectionProperty(); + property.outlineColor.intervals.addInterval(new TimeInterval(start, stop, true, true, Color.BLUE)); + expect(property.isConstant).toBe(false); + + property.outlineColor = undefined; + expect(property.isConstant).toBe(true); + property.outlineWidth = new TimeIntervalCollectionProperty(); + property.outlineWidth.intervals.addInterval(new TimeInterval(start, stop, true, true, 2.0)); + expect(property.isConstant).toBe(false); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/SampledPositionPropertySpec.js b/Specs/DynamicScene/SampledPositionPropertySpec.js index e4c2c745a930..5dc5f947fbac 100644 --- a/Specs/DynamicScene/SampledPositionPropertySpec.js +++ b/Specs/DynamicScene/SampledPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/SampledPositionProperty', +defineSuite(['DynamicScene/SampledPositionProperty', 'DynamicScene/PositionProperty', 'Core/Cartesian3', 'Core/defined', @@ -172,8 +171,10 @@ defineSuite([ var property = new SampledPositionProperty(); property.addSamplesPackedArray(data, epoch); - property.interpolationDegree = 2; - property.interpolationAlgorithm = MockInterpolation; + property.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : MockInterpolation + }); expect(property.getValue(epoch)).toEqual(new Cartesian3(7, 8, 9)); expect(property.getValue(new JulianDate(0, 3))).toEqual(new Cartesian3(2, 3, 4)); @@ -208,27 +209,35 @@ defineSuite([ it('equals works when interpolators differ', function() { var left = new SampledPositionProperty(); - left.interpolationAlgorithm = LinearApproximation; - var right = new SampledPositionProperty(); - right.interpolationAlgorithm = LinearApproximation; expect(left.equals(right)).toEqual(true); - right.interpolationAlgorithm = LagrangePolynomialApproximation; + right.setInterpolationOptions({ + interpolationAlgorithm : LagrangePolynomialApproximation + }); expect(left.equals(right)).toEqual(false); }); it('equals works when interpolator degree differ', function() { var left = new SampledPositionProperty(); - left.interpolationAlgorithm = LagrangePolynomialApproximation; - left.interpolationDegree = 2; + + left.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); var right = new SampledPositionProperty(); - right.interpolationAlgorithm = LagrangePolynomialApproximation; - right.interpolationDegree = 2; + right.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); expect(left.equals(right)).toEqual(true); - right.interpolationDegree = 3; + right.setInterpolationOptions({ + interpolationDegree : 3, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + expect(left.equals(right)).toEqual(false); }); diff --git a/Specs/DynamicScene/SampledPropertySpec.js b/Specs/DynamicScene/SampledPropertySpec.js index 5f8310631ff2..aa9630c207d0 100644 --- a/Specs/DynamicScene/SampledPropertySpec.js +++ b/Specs/DynamicScene/SampledPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/SampledProperty', +defineSuite(['DynamicScene/SampledProperty', 'Core/defined', 'Core/JulianDate', 'Core/LinearApproximation', @@ -18,6 +17,14 @@ defineSuite([ var property = new SampledProperty(Number); expect(property.interpolationDegree).toEqual(1); expect(property.interpolationAlgorithm).toEqual(LinearApproximation); + expect(property.isConstant).toEqual(true); + }); + + it('isConstant works', function() { + var property = new SampledProperty(Number); + expect(property.isConstant).toEqual(true); + property.addSample(new JulianDate(0, 0), 1); + expect(property.isConstant).toEqual(false); }); it('addSamplesPackedArray works', function() { @@ -25,7 +32,11 @@ defineSuite([ var epoch = new JulianDate(0, 0); var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + property.addSamplesPackedArray(data, epoch); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); expect(property.getValue(epoch)).toEqual(7); expect(property.getValue(new JulianDate(0, 0.5))).toEqual(7.5); }); @@ -35,9 +46,19 @@ defineSuite([ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + property.addSample(times[0], values[0]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + property.addSample(times[1], values[1]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + property.addSample(times[2], values[2]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); expect(property.getValue(times[0])).toEqual(values[0]); expect(property.getValue(times[1])).toEqual(values[1]); @@ -50,7 +71,10 @@ defineSuite([ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); property.addSamples(times, values); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); expect(property.getValue(times[0])).toEqual(values[0]); expect(property.getValue(times[1])).toEqual(values[1]); expect(property.getValue(times[2])).toEqual(values[2]); @@ -136,12 +160,19 @@ defineSuite([ }; var property = new SampledProperty(Number); + spyOn(property.definitionChanged, 'raiseEvent'); + property.addSamplesPackedArray(data, epoch); + expect(property.getValue(epoch)).toEqual(7); expect(property.getValue(new JulianDate(0, 1))).toEqual(8); - property.interpolationDegree = 2; - property.interpolationAlgorithm = MockInterpolation; + property.setInterpolationOptions({ + interpolationAlgorithm : MockInterpolation, + interpolationDegree : 2 + }); + + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); expect(property.getValue(epoch)).toEqual(7); expect(property.getValue(new JulianDate(0, 3))).toEqual(2); @@ -293,27 +324,35 @@ defineSuite([ it('equals works when interpolators differ', function() { var left = new SampledProperty(Number); - left.interpolationAlgorithm = LinearApproximation; - var right = new SampledProperty(Number); - right.interpolationAlgorithm = LinearApproximation; expect(left.equals(right)).toEqual(true); - right.interpolationAlgorithm = LagrangePolynomialApproximation; + right.setInterpolationOptions({ + interpolationAlgorithm : LagrangePolynomialApproximation + }); expect(left.equals(right)).toEqual(false); }); it('equals works when interpolator degree differ', function() { var left = new SampledProperty(Number); - left.interpolationAlgorithm = LagrangePolynomialApproximation; - left.interpolationDegree = 2; + + left.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); var right = new SampledProperty(Number); - right.interpolationAlgorithm = LagrangePolynomialApproximation; - right.interpolationDegree = 2; + right.setInterpolationOptions({ + interpolationDegree : 2, + interpolationAlgorithm : LagrangePolynomialApproximation + }); expect(left.equals(right)).toEqual(true); - right.interpolationDegree = 3; + right.setInterpolationOptions({ + interpolationDegree : 3, + interpolationAlgorithm : LagrangePolynomialApproximation + }); + expect(left.equals(right)).toEqual(false); }); diff --git a/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js b/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js index ff3a5a7b3588..0ae994904073 100644 --- a/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js +++ b/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/TimeIntervalCollectionPositionProperty', +defineSuite(['DynamicScene/TimeIntervalCollectionPositionProperty', 'DynamicScene/PositionProperty', 'Core/Cartesian3', 'Core/JulianDate', @@ -159,4 +158,23 @@ defineSuite([ right.intervals.addInterval(interval2); expect(left.equals(right)).toEqual(true); }); + + it('raises definitionChanged event', function() { + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + + var property = new TimeIntervalCollectionPositionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + + property.intervals.addInterval(interval); + property.definitionChanged.raiseEvent.reset(); + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js b/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js index 29b0ced2f664..51f677b43d05 100644 --- a/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js +++ b/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js @@ -1,6 +1,5 @@ /*global defineSuite*/ -defineSuite([ - 'DynamicScene/TimeIntervalCollectionProperty', +defineSuite(['DynamicScene/TimeIntervalCollectionProperty', 'Core/Cartesian3', 'Core/JulianDate', 'Core/TimeInterval', @@ -18,6 +17,7 @@ defineSuite([ var property = new TimeIntervalCollectionProperty(); expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); expect(property.getValue(new JulianDate())).toBeUndefined(); + expect(property.isConstant).toBe(true); }); it('works with basic types', function() { @@ -30,6 +30,7 @@ defineSuite([ expect(property.getValue(interval1.start)).toBe(interval1.data); expect(property.getValue(interval2.stop)).toBe(interval2.data); + expect(property.isConstant).toBe(false); }); it('works with clonable objects', function() { @@ -105,4 +106,23 @@ defineSuite([ right.intervals.addInterval(interval2); expect(left.equals(right)).toEqual(true); }); + + it('raises definitionChanged event', function() { + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); + + var property = new TimeIntervalCollectionProperty(); + spyOn(property.definitionChanged, 'raiseEvent'); + + property.intervals.addInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + property.definitionChanged.raiseEvent.reset(); + + property.intervals.removeInterval(interval); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + + property.intervals.addInterval(interval); + property.definitionChanged.raiseEvent.reset(); + property.intervals.clear(); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); }); \ No newline at end of file From dba917e6284afc9bbd4e25a606f6e6080818fd04 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 28 Jan 2014 08:38:49 -0500 Subject: [PATCH 07/81] Get rid of DynamicDirectionsProperty It's no longer needed because it can be represented by standard properties. The code processing the CZML now lives in CzmlDataSource. --- Source/DynamicScene/CzmlDataSource.js | 26 ++++- .../DynamicScene/DynamicDirectionsProperty.js | 103 ------------------ .../DynamicDirectionsPropertySpec.js | 76 ------------- 3 files changed, 20 insertions(+), 185 deletions(-) delete mode 100644 Source/DynamicScene/DynamicDirectionsProperty.js delete mode 100644 Specs/DynamicScene/DynamicDirectionsPropertySpec.js diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index ccddab2cae15..d3cf13116585 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -40,7 +40,6 @@ define([ './PolylineOutlineMaterialProperty', './DynamicCone', './DynamicLabel', - './DynamicDirectionsProperty', './DynamicEllipse', './DynamicEllipsoid', './GridMaterialProperty', @@ -101,7 +100,6 @@ define([ PolylineOutlineMaterialProperty, DynamicCone, DynamicLabel, - DynamicDirectionsProperty, DynamicEllipse, DynamicEllipsoid, GridMaterialProperty, @@ -1094,12 +1092,28 @@ define([ processPacketData(Number, pyramid, 'intersectionWidth', pyramidData.intersectionWidth, interval, sourceUri); processMaterialPacketData(pyramid, 'material', pyramidData.material, interval, sourceUri); + //The directions property is a special case value that can be an array of unitSpherical or unit Cartesians. + //We pre-process this into Spherical instances and then process it like any other array. if (defined(pyramidData.directions)) { - var directions = pyramid.directions; - if (!defined(directions)) { - pyramid.directions = directions = new DynamicDirectionsProperty(); + var i; + var len; + var values = []; + var tmp = pyramidData.directions.unitSpherical; + if (defined(tmp)) { + for (i = 0, len = tmp.length; i < len; i += 2) { + values.push(new Spherical(tmp[i], tmp[i + 1])); + } + pyramidData.directions.array = values; + } + + tmp = pyramidData.directions.unitCartesian; + if (defined(tmp)) { + for (i = 0, len = tmp.length; i < len; i += 3) { + values.push(Spherical.fromCartesian3(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2]))); + } + pyramidData.directions.array = values; } - directions.processCzmlIntervals(pyramidData.directions, interval); + processPacketData(Array, pyramid, 'directions', pyramidData.directions, interval, sourceUri); } } diff --git a/Source/DynamicScene/DynamicDirectionsProperty.js b/Source/DynamicScene/DynamicDirectionsProperty.js deleted file mode 100644 index 6ef7b2654e13..000000000000 --- a/Source/DynamicScene/DynamicDirectionsProperty.js +++ /dev/null @@ -1,103 +0,0 @@ -/*global define*/ -define([ - '../Core/defined', - '../Core/TimeInterval', - '../Core/TimeIntervalCollection', - '../Core/Cartesian3', - '../Core/Spherical', - '../Core/Iso8601' - ], function( - defined, - TimeInterval, - TimeIntervalCollection, - Cartesian3, - Spherical, - Iso8601) { - "use strict"; - - function ValueHolder(czmlInterval) { - var i; - var len; - var values = []; - var tmp = czmlInterval.unitSpherical; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 2) { - values.push(new Spherical(tmp[i], tmp[i + 1])); - } - this.spherical = values; - } - - tmp = czmlInterval.unitCartesian; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 3) { - values.push(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2], true)); - } - this.cartesian = values; - } - } - - ValueHolder.prototype.getValue = function() { - var sphericals = this.spherical; - if (!defined(sphericals)) { - sphericals = []; - this.spherical = sphericals; - var cartesians = this.cartesian; - for ( var i = 0, len = cartesians.length; i < len; i++) { - sphericals.push(Spherical.fromCartesian3(cartesians[i])); - } - } - return sphericals; - }; - - /** - * @private - */ - var DynamicDirectionsProperty = function() { - this._propertyIntervals = new TimeIntervalCollection(); - }; - - DynamicDirectionsProperty.prototype.processCzmlIntervals = function(czmlIntervals, constrainedInterval, dynamicObjectCollection) { - if (Array.isArray(czmlIntervals)) { - for ( var i = 0, len = czmlIntervals.length; i < len; i++) { - addCzmlInterval(this, czmlIntervals[i], constrainedInterval, dynamicObjectCollection); - } - } else { - addCzmlInterval(this, czmlIntervals, constrainedInterval, dynamicObjectCollection); - } - }; - - DynamicDirectionsProperty.prototype.getValue = function(time) { - var interval = this._propertyIntervals.findIntervalContainingDate(time); - if (!defined(interval)) { - return undefined; - } - return interval.data.getValue(); - }; - - function addCzmlInterval(dynamicDirectionsProperty, czmlInterval, constrainedInterval, dynamicObjectCollection) { - var iso8601Interval = czmlInterval.interval; - if (!defined(iso8601Interval)) { - iso8601Interval = Iso8601.MAXIMUM_INTERVAL.clone(); - } else { - iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); - } - - if (defined(constrainedInterval)) { - iso8601Interval = iso8601Interval.intersect(constrainedInterval); - } - - //See if we already have data at that interval. - var thisIntervals = dynamicDirectionsProperty._propertyIntervals; - var existingInterval = thisIntervals.findInterval(iso8601Interval.start, iso8601Interval.stop); - - //If not, create it. - if (!defined(existingInterval)) { - existingInterval = iso8601Interval; - thisIntervals.addInterval(existingInterval); - } - - existingInterval.data = new ValueHolder(czmlInterval); - } - - return DynamicDirectionsProperty; -}); diff --git a/Specs/DynamicScene/DynamicDirectionsPropertySpec.js b/Specs/DynamicScene/DynamicDirectionsPropertySpec.js deleted file mode 100644 index 5c8ac4d5a862..000000000000 --- a/Specs/DynamicScene/DynamicDirectionsPropertySpec.js +++ /dev/null @@ -1,76 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/DynamicDirectionsProperty', - 'Core/JulianDate', - 'Core/Cartesian3', - 'Core/Spherical' - ], function( - DynamicDirectionsProperty, - JulianDate, - Cartesian3, - Spherical) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var sphericals; - var cartesians; - var sphericalInterval; - var cartesianInterval; - - beforeAll(function() { - cartesians = [new Cartesian3(1, 0, 0), new Cartesian3(0, 1, 0), new Cartesian3(0, 0, 1)]; - sphericals = [Spherical.fromCartesian3(cartesians[0]), Spherical.fromCartesian3(cartesians[1]), Spherical.fromCartesian3(cartesians[2])]; - - sphericalInterval = { - unitSpherical : [sphericals[0].clock, sphericals[0].cone, sphericals[1].clock, sphericals[1].cone, sphericals[2].clock, sphericals[2].cone] - }; - - cartesianInterval = { - unitCartesian : [cartesians[0].x, cartesians[0].y, cartesians[0].z, cartesians[1].x, cartesians[1].y, cartesians[1].z, cartesians[2].x, cartesians[2].y, cartesians[2].z] - }; - }); - - it('getValue returns undefined if no data exists', function() { - var property = new DynamicDirectionsProperty(); - expect(property.getValue(new JulianDate())).toBeUndefined(); - }); - - it('getValue throw if no time supplied', function() { - var property = new DynamicDirectionsProperty(); - expect(function() { - property.getValue(); - }).toThrow(); - }); - - it('getValue works for cartesian data', function() { - var property = new DynamicDirectionsProperty(); - property.processCzmlIntervals(cartesianInterval); - var result = property.getValue(new JulianDate()); - expect(result.length).toEqual(cartesians.length); - expect(result[0]).toEqual(sphericals[0]); - expect(result[1]).toEqual(sphericals[1]); - expect(result[2]).toEqual(sphericals[2]); - }); - - it('getValue works for spherical data', function() { - var property = new DynamicDirectionsProperty(); - property.processCzmlIntervals(sphericalInterval); - var result = property.getValue(new JulianDate()); - expect(result.length).toEqual(sphericals.length); - expect(result[0]).toEqual(sphericals[0]); - expect(result[1]).toEqual(sphericals[1]); - expect(result[2]).toEqual(sphericals[2]); - }); - - it('getValue returns undefined if no data exists', function() { - var property = new DynamicDirectionsProperty(); - expect(property.getValue(new JulianDate())).toBeUndefined(); - }); - - it('getValue throws if no time supplied', function() { - var property = new DynamicDirectionsProperty(); - expect(function() { - property.getValue(); - }).toThrow(); - }); -}); From f7f2124b982c85fe9f4208950f9560d923eaf8f0 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 28 Jan 2014 13:20:01 -0500 Subject: [PATCH 08/81] Ongoing property work 1. Get rid of `DynamicVertexPositionsProperty` and role the CZML processing aspect of it into CzmlDataSource. 2. Add `PropertyArray` and `PositionPropertyArray`, which allow for time-dynamic array properties. 3. Temporarily add some code to ReferenceFrameProperty to support positions, this may be removed in favor of a separate ReferencePositionProperty. --- Source/DynamicScene/CzmlDataSource.js | 58 +++++- .../DynamicVertexPositionsProperty.js | 131 ------------ Source/DynamicScene/PositionPropertyArray.js | 189 ++++++++++++++++++ Source/DynamicScene/Property.js | 13 ++ Source/DynamicScene/PropertyArray.js | 149 ++++++++++++++ Source/DynamicScene/ReferenceProperty.js | 47 ++++- Specs/DynamicScene/DynamicConeSpec.js | 2 - Specs/DynamicScene/DynamicEllipsoidSpec.js | 2 - Specs/DynamicScene/DynamicPolygonSpec.js | 2 - Specs/DynamicScene/DynamicPyramidSpec.js | 2 - .../DynamicVertexPositionsPropertySpec.js | 151 -------------- .../DynamicScene/PositionPropertyArraySepc.js | 107 ++++++++++ Specs/DynamicScene/PropertyArraySepc.js | 97 +++++++++ 13 files changed, 652 insertions(+), 298 deletions(-) delete mode 100644 Source/DynamicScene/DynamicVertexPositionsProperty.js create mode 100644 Source/DynamicScene/PositionPropertyArray.js create mode 100644 Source/DynamicScene/PropertyArray.js delete mode 100644 Specs/DynamicScene/DynamicVertexPositionsPropertySpec.js create mode 100644 Specs/DynamicScene/PositionPropertyArraySepc.js create mode 100644 Specs/DynamicScene/PropertyArraySepc.js diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index d3cf13116585..7b8c670c83b4 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -52,7 +52,8 @@ define([ './DynamicPolygon', './DynamicPyramid', './DynamicVector', - './DynamicVertexPositionsProperty', + './PositionPropertyArray', + './ReferenceProperty', './SampledPositionProperty', './SampledProperty', './TimeIntervalCollectionPositionProperty', @@ -112,7 +113,8 @@ define([ DynamicPolygon, DynamicPyramid, DynamicVector, - DynamicVertexPositionsProperty, + PositionPropertyArray, + ReferenceProperty, SampledPositionProperty, SampledProperty, TimeIntervalCollectionPositionProperty, @@ -751,11 +753,55 @@ define([ return; } - var vertexPositions = dynamicObject.vertexPositions; - if (!defined(vertexPositions)) { - dynamicObject.vertexPositions = vertexPositions = new DynamicVertexPositionsProperty(); + var i; + var len; + var references = vertexPositionsData.references; + if (defined(references)) { + var properties = []; + for (i = 0, len = references.length; i < len; i++) { + properties.push(ReferenceProperty.fromString(dynamicObjectCollection, references[i])); + } + + var iso8601Interval = vertexPositionsData.interval; + if (defined(iso8601Interval)) { + iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); + if (!(dynamicObject.vertexPositions instanceof CompositePositionProperty)) { + dynamicObject.vertexPositions = new CompositePositionProperty(); + iso8601Interval.data = new PositionPropertyArray(properties); + dynamicObject.vertexPositions.intervals.addInterval(iso8601Interval); + } + } else { + dynamicObject.vertexPositions = new PositionPropertyArray(properties); + } + } else { + var values = []; + var tmp = vertexPositionsData.cartesian; + if (defined(tmp)) { + for (i = 0, len = tmp.length; i < len; i += 3) { + values.push(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2])); + } + vertexPositionsData.array = values; + } else { + tmp = vertexPositionsData.cartographicRadians; + if (defined(tmp)) { + for (i = 0, len = tmp.length; i < len; i += 3) { + values.push(Ellipsoid.WGS84.cartographicToCartesian(new Cartographic(tmp[i], tmp[i + 1], tmp[i + 2]))); + } + vertexPositionsData.array = values; + } else { + tmp = vertexPositionsData.cartographicDegrees; + if (defined(tmp)) { + for (i = 0, len = tmp.length; i < len; i += 3) { + values.push(Ellipsoid.WGS84.cartographicToCartesian(Cartographic.fromDegrees(tmp[i], tmp[i + 1], tmp[i + 2]))); + } + vertexPositionsData.array = values; + } + } + } + if (defined(vertexPositionsData.array)) { + processPacketData(Array, dynamicObject, 'vertexPositions', vertexPositionsData, undefined, sourceUri); + } } - vertexPositions.processCzmlIntervals(vertexPositionsData, undefined, dynamicObjectCollection); } function processAvailability(dynamicObject, packet, dynamicObjectCollection, sourceUri) { diff --git a/Source/DynamicScene/DynamicVertexPositionsProperty.js b/Source/DynamicScene/DynamicVertexPositionsProperty.js deleted file mode 100644 index aa00b6be88ee..000000000000 --- a/Source/DynamicScene/DynamicVertexPositionsProperty.js +++ /dev/null @@ -1,131 +0,0 @@ -/*global define*/ -define([ - '../Core/defined', - '../Core/TimeInterval', - '../Core/TimeIntervalCollection', - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/Iso8601', - '../Core/Ellipsoid', - './ReferenceProperty' - ], function( - defined, - TimeInterval, - TimeIntervalCollection, - Cartesian3, - Cartographic, - Iso8601, - Ellipsoid, - ReferenceProperty) { - "use strict"; - - var wgs84 = Ellipsoid.WGS84; - - function ValueHolder(czmlInterval) { - var i, len, values = [], tmp; - - tmp = czmlInterval.cartesian; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 3) { - values.push(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2])); - } - this.cartesian = values; - } else { - tmp = czmlInterval.cartographicRadians; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 3) { - values.push(new Cartographic(tmp[i], tmp[i + 1], tmp[i + 2])); - } - this.cartographic = values; - } else { - tmp = czmlInterval.cartographicDegrees; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 3) { - values.push(Cartographic.fromDegrees(tmp[i], tmp[i + 1], tmp[i + 2])); - } - this.cartographic = values; - } - } - } - } - - ValueHolder.prototype.getValue = function() { - if (!defined(this.cartesian)) { - this.cartesian = wgs84.cartographicArrayToCartesianArray(this.cartographic); - } - return this.cartesian; - }; - - /** - * @private - */ - var DynamicVertexPositionsProperty = function() { - this._propertyIntervals = new TimeIntervalCollection(); - }; - - DynamicVertexPositionsProperty.prototype.processCzmlIntervals = function(czmlIntervals, constrainedInterval, dynamicObjectCollection) { - if (Array.isArray(czmlIntervals)) { - for ( var i = 0, len = czmlIntervals.length; i < len; i++) { - this._addCzmlInterval(czmlIntervals[i], constrainedInterval, dynamicObjectCollection); - } - } else { - this._addCzmlInterval(czmlIntervals, constrainedInterval, dynamicObjectCollection); - } - }; - - DynamicVertexPositionsProperty.prototype.getValue = function(time) { - var interval = this._propertyIntervals.findIntervalContainingDate(time); - if (!defined(interval)) { - return undefined; - } - var interval_data = interval.data; - if (Array.isArray(interval_data)) { - var result = []; - for ( var i = 0, len = interval_data.length; i < len; i++) { - var value = interval_data[i].getValue(time); - if (defined(value)) { - result.push(value); - } - } - return result; - } - - return interval_data.getValue(); - }; - - DynamicVertexPositionsProperty.prototype._addCzmlInterval = function(czmlInterval, constrainedInterval, dynamicObjectCollection) { - var iso8601Interval = czmlInterval.interval; - if (!defined(iso8601Interval)) { - iso8601Interval = Iso8601.MAXIMUM_INTERVAL.clone(); - } else { - iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); - } - - if (defined(constrainedInterval)) { - iso8601Interval = iso8601Interval.intersect(constrainedInterval); - } - - //See if we already have data at that interval. - var thisIntervals = this._propertyIntervals; - var existingInterval = thisIntervals.findInterval(iso8601Interval.start, iso8601Interval.stop); - - //If not, create it. - if (!defined(existingInterval)) { - existingInterval = iso8601Interval; - thisIntervals.addInterval(existingInterval); - } - - var references = czmlInterval.references; - if (!defined(references)) { - existingInterval.data = new ValueHolder(czmlInterval); - } else { - var properties = []; - for ( var i = 0, len = references.length; i < len; i++) { - properties.push(ReferenceProperty.fromString(dynamicObjectCollection, references[i])); - } - existingInterval.data = properties; - } - }; - - return DynamicVertexPositionsProperty; -}); diff --git a/Source/DynamicScene/PositionPropertyArray.js b/Source/DynamicScene/PositionPropertyArray.js new file mode 100644 index 000000000000..6eec4bed8a13 --- /dev/null +++ b/Source/DynamicScene/PositionPropertyArray.js @@ -0,0 +1,189 @@ +/*global define*/ +define(['../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Enumeration', + '../Core/Event', + '../Core/EventHelper', + '../Core/ReferenceFrame', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Enumeration, + Event, + EventHelper, + ReferenceFrame, + Property) { + "use strict"; + + /** + * A {@link PositionProperty} whose value is an array whose items are the computed value + * of other PositionProperty instances. + * + * @alias PositionProperty + * @constructor + * + * @param {Array} [value] An array of Property instances. + */ + var PositionPropertyArray = function(value, referenceFrame) { + this._value = undefined; + this._length = 0; + this._definitionChanged = new Event(); + this._eventHelper = new EventHelper(); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + this.setValue(value); + }; + + defineProperties(PositionPropertyArray.prototype, { + /** + * Gets a value indicating if this property is constant. This property + * is considered constant if all property items in the array are constant. + * @memberof PositionPropertyArray.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + var length = this._length; + var value = this._value; + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property) && !property.isConstant) { + return false; + } + } + return true; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value or one of the properties in the array also changes. + * @memberof PositionPropertyArray.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof PositionPropertyArray.prototype + * @Type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + } + }); + + /** + * Gets the value of the property. + * @memberof PositionPropertyArray + * + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Array} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Array} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PositionPropertyArray.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @memberof PositionPropertyArray + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * + * @exception {DeveloperError} time is required. + * @exception {DeveloperError} referenceFrame is required. + */ + PositionPropertyArray.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + //>>includeEnd('debug'); + + if (!defined(this._value)) { + return undefined; + } + + var length = this._length; + if (!defined(result)) { + result = new Array(length); + } + for (var i = 0; i < length; i++) { + var property = this._value[i]; + if (defined(property)) { + result[i] = property.getValueInReferenceFrame(time, referenceFrame, result[i]); + } else { + result[i] = undefined; + } + } + result.length = length; + return result; + }; + + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof PositionPropertyArray + * + * @param {Array} value An array of Property instances. + */ + PositionPropertyArray.prototype.setValue = function(value) { + var eventHelper = this._eventHelper; + eventHelper.removeAll(); + + if (defined(value)) { + this._value = value.slice(); + var length = value.length; + this._length = length; + + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property)) { + eventHelper.add(property.definitionChanged, PositionPropertyArray.prototype._raiseDefinitionChanged, this); + } + } + } else { + this._value = undefined; + this._length = 0; + } + this._definitionChanged.raiseEvent(this); + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof PositionPropertyArray + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + PositionPropertyArray.prototype.equals = function(other) { + return this === other || // + (other instanceof PositionPropertyArray && // + this._referenceFrame === other._referenceFrame && + (this._length === other._length && Property.arrayEquals(this._value, other._value))); + }; + + PositionPropertyArray.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + + return PositionPropertyArray; +}); diff --git a/Source/DynamicScene/Property.js b/Source/DynamicScene/Property.js index dcde7be20682..eda605d4769d 100644 --- a/Source/DynamicScene/Property.js +++ b/Source/DynamicScene/Property.js @@ -79,5 +79,18 @@ define(['../Core/defined', return left === right || (defined(left) && left.equals(right)); }; + /** + * @private + */ + Property.arrayEquals = function(left, right) { + var length = left.length; + for (var i = 0; i < length; i++) { + if (!Property.equals(left[i], right[i])) { + return false; + } + } + return true; + }; + return Property; }); \ No newline at end of file diff --git a/Source/DynamicScene/PropertyArray.js b/Source/DynamicScene/PropertyArray.js new file mode 100644 index 000000000000..ec22152aae3a --- /dev/null +++ b/Source/DynamicScene/PropertyArray.js @@ -0,0 +1,149 @@ +/*global define*/ +define(['../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Enumeration', + '../Core/Event', + '../Core/EventHelper', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Enumeration, + Event, + EventHelper, + Property) { + "use strict"; + + /** + * A {@link Property} whose value is an array whose items are the computed value + * of other property instances. + * + * @alias PropertyArray + * @constructor + * + * @param {Array} [value] An array of Property instances. + */ + var PropertyArray = function(value) { + this._value = undefined; + this._length = 0; + this._definitionChanged = new Event(); + this._eventHelper = new EventHelper(); + this.setValue(value); + }; + + defineProperties(PropertyArray.prototype, { + /** + * Gets a value indicating if this property is constant. This property + * is considered constant if all property items in the array are constant. + * @memberof PropertyArray.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + var length = this._length; + var value = this._value; + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property) && !property.isConstant) { + return false; + } + } + return true; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value or one of the properties in the array also changes. + * @memberof PropertyArray.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + } + }); + + /** + * Gets the value of the property. + * @memberof PropertyArray + * + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Array} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Array} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PropertyArray.prototype.getValue = function(time, result) { + if (!defined(this._value)) { + return undefined; + } + + var length = this._length; + if (!defined(result)) { + result = new Array(length); + } + for (var i = 0; i < length; i++) { + var property = this._value[i]; + if (defined(property)) { + result[i] = property.getValue(time, result[i]); + } else { + result[i] = undefined; + } + } + result.length = length; + return result; + }; + + /** + * Sets the value of the property. + * If the value is an object, the object must provide clone and equals functions. + * @memberof PropertyArray + * + * @param {Array} value An array of Property instances. + */ + PropertyArray.prototype.setValue = function(value) { + var eventHelper = this._eventHelper; + eventHelper.removeAll(); + + if (defined(value)) { + this._value = value.slice(); + var length = value.length; + this._length = length; + + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property)) { + eventHelper.add(property.definitionChanged, PropertyArray.prototype._raiseDefinitionChanged, this); + } + } + } else { + this._value = undefined; + this._length = 0; + } + this._definitionChanged.raiseEvent(this); + }; + + /** + * Compares this property to the provided property and returns + * true if they are equal, false otherwise. + * @memberof PropertyArray + * + * @param {Property} [other] The other property. + * @returns {Boolean} true if left and right are equal, false otherwise. + */ + PropertyArray.prototype.equals = function(other) { + return this === other || // + (other instanceof PropertyArray && // + (this._length === other._length && Property.arrayEquals(this._value, other._value))); + }; + + PropertyArray.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + + return PropertyArray; +}); diff --git a/Source/DynamicScene/ReferenceProperty.js b/Source/DynamicScene/ReferenceProperty.js index a13903d9f260..ddd009d4a4f7 100644 --- a/Source/DynamicScene/ReferenceProperty.js +++ b/Source/DynamicScene/ReferenceProperty.js @@ -2,11 +2,15 @@ define([ '../Core/defaultValue', '../Core/defined', - '../Core/DeveloperError' + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event' ], function( defaultValue, defined, - DeveloperError) { + defineProperties, + DeveloperError, + Event) { "use strict"; function resolve(referenceProperty) { @@ -55,8 +59,36 @@ define([ this._targetObjectId = targetObjectId; this._targetObject = undefined; this._targetPropertyName = targetPropertyName; + this._definitionChanged = new Event(); }; + defineProperties(ReferenceProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * This property always returns true. + * @memberof ConstantProperty.prototype + * @type {Boolean} + */ + isConstant : { + get : function() { + var targetProperty = resolve(this); + return !defined(targetProperty) || targetProperty.isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof ConstantProperty.prototype + * @type {Event} + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + } + }); + /** * Creates a new reference property given the dynamic object collection that will * be used to resolve it and a string indicating the target object id and property, @@ -114,6 +146,17 @@ define([ return defined(targetProperty) && this._targetObject.isAvailable(time) ? targetProperty.getValue(time, result) : undefined; }; + ReferenceProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + //>>includeEnd('debug'); + + var targetProperty = resolve(this); + return defined(targetProperty) && this._targetObject.isAvailable(time) ? targetProperty.getValueInReferenceFrame(time, referenceFrame, result) : undefined; + }; + /** * Compares this property to the provided property and returns * true if they are equal, false otherwise. diff --git a/Specs/DynamicScene/DynamicConeSpec.js b/Specs/DynamicScene/DynamicConeSpec.js index 2804e0bea475..0190f117b970 100644 --- a/Specs/DynamicScene/DynamicConeSpec.js +++ b/Specs/DynamicScene/DynamicConeSpec.js @@ -3,13 +3,11 @@ defineSuite([ 'DynamicScene/DynamicCone', 'DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', - 'DynamicScene/DynamicVertexPositionsProperty', 'Core/Color' ], function( DynamicCone, ColorMaterialProperty, ConstantProperty, - DynamicVertexPositionsProperty, Color) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ diff --git a/Specs/DynamicScene/DynamicEllipsoidSpec.js b/Specs/DynamicScene/DynamicEllipsoidSpec.js index 187b5368a242..a1a6bb582dcd 100644 --- a/Specs/DynamicScene/DynamicEllipsoidSpec.js +++ b/Specs/DynamicScene/DynamicEllipsoidSpec.js @@ -3,14 +3,12 @@ defineSuite([ 'DynamicScene/DynamicEllipsoid', 'DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', - 'DynamicScene/DynamicVertexPositionsProperty', 'Core/Cartesian3', 'Core/Color' ], function( DynamicEllipsoid, ColorMaterialProperty, ConstantProperty, - DynamicVertexPositionsProperty, Cartesian3, Color) { "use strict"; diff --git a/Specs/DynamicScene/DynamicPolygonSpec.js b/Specs/DynamicScene/DynamicPolygonSpec.js index 8118be9fe392..5d1135fc0b1a 100644 --- a/Specs/DynamicScene/DynamicPolygonSpec.js +++ b/Specs/DynamicScene/DynamicPolygonSpec.js @@ -3,13 +3,11 @@ defineSuite([ 'DynamicScene/DynamicPolygon', 'DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', - 'DynamicScene/DynamicVertexPositionsProperty', 'Core/Color' ], function( DynamicPolygon, ColorMaterialProperty, ConstantProperty, - DynamicVertexPositionsProperty, Color) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ diff --git a/Specs/DynamicScene/DynamicPyramidSpec.js b/Specs/DynamicScene/DynamicPyramidSpec.js index db13c145981b..58594f9f0448 100644 --- a/Specs/DynamicScene/DynamicPyramidSpec.js +++ b/Specs/DynamicScene/DynamicPyramidSpec.js @@ -3,13 +3,11 @@ defineSuite([ 'DynamicScene/DynamicPyramid', 'DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', - 'DynamicScene/DynamicVertexPositionsProperty', 'Core/Color' ], function( DynamicPyramid, ColorMaterialProperty, ConstantProperty, - DynamicVertexPositionsProperty, Color) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ diff --git a/Specs/DynamicScene/DynamicVertexPositionsPropertySpec.js b/Specs/DynamicScene/DynamicVertexPositionsPropertySpec.js deleted file mode 100644 index 3322599322f9..000000000000 --- a/Specs/DynamicScene/DynamicVertexPositionsPropertySpec.js +++ /dev/null @@ -1,151 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/DynamicVertexPositionsProperty', - 'DynamicScene/DynamicObjectCollection', - 'DynamicScene/CzmlDataSource', - 'Core/Cartographic', - 'Core/JulianDate', - 'Core/Math', - 'Core/Ellipsoid' - ], function( - DynamicVertexPositionsProperty, - DynamicObjectCollection, - CzmlDataSource, - Cartographic, - JulianDate, - CesiumMath, - Ellipsoid) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var cartographicRadiansInterval = { - cartographicRadians : [1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9] - }; - - var cartographicDegreesInterval = { - cartographicDegrees : [10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9] - }; - - var cartesianInterval = { - cartesian : [10000, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009] - }; - - var testObjects = [{ - id : 'test1', - position : { - cartesian : [100000, 100001, 100003] - } - }, { - id : 'test2', - position : { - cartesian : [100004, 100005, 100006] - } - }, { - id : 'test3', - position : { - interval : '2012-04-18T15:59:00Z/2012-04-18T15:59:00Z', - cartesian : [100007, 100008, 100009] - } - }]; - - var referenceInterval = { - references : ['test1.position', 'test2.position', 'test3.position'] - }; - - it('getValue returns undefined if no data exists', function() { - var property = new DynamicVertexPositionsProperty(); - expect(property.getValue(new JulianDate())).toBeUndefined(); - }); - - it('getValue throw if no time supplied', function() { - var property = new DynamicVertexPositionsProperty(); - expect(function() { - property.getValue(); - }).toThrow(); - }); - - it('getValue works for cartesian data', function() { - var property = new DynamicVertexPositionsProperty(); - property.processCzmlIntervals(cartesianInterval); - var result = property.getValue(new JulianDate()); - expect(result.length).toEqual(3); - expect(result[0].x).toEqual(cartesianInterval.cartesian[0]); - expect(result[0].y).toEqual(cartesianInterval.cartesian[1]); - expect(result[0].z).toEqual(cartesianInterval.cartesian[2]); - - expect(result[1].x).toEqual(cartesianInterval.cartesian[3]); - expect(result[1].y).toEqual(cartesianInterval.cartesian[4]); - expect(result[1].z).toEqual(cartesianInterval.cartesian[5]); - - expect(result[2].x).toEqual(cartesianInterval.cartesian[6]); - expect(result[2].y).toEqual(cartesianInterval.cartesian[7]); - expect(result[2].z).toEqual(cartesianInterval.cartesian[8]); - }); - - it('getValue works for cartographic degrees data', function() { - var property = new DynamicVertexPositionsProperty(); - property.processCzmlIntervals(cartographicDegreesInterval); - var result = property.getValue(new JulianDate()); - - var expected = Ellipsoid.WGS84.cartographicArrayToCartesianArray([new Cartographic(CesiumMath.toRadians(10.1), CesiumMath.toRadians(10.2), 10.3), new Cartographic(CesiumMath.toRadians(10.4), CesiumMath.toRadians(10.5), 10.6), new Cartographic(CesiumMath.toRadians(10.7), CesiumMath.toRadians(10.8), 10.9)]); - - expect(result.length).toEqual(3); - expect(result[0].x).toEqual(expected[0].x); - expect(result[0].y).toEqual(expected[0].y); - expect(result[0].z).toEqual(expected[0].z); - - expect(result[1].x).toEqual(expected[1].x); - expect(result[1].y).toEqual(expected[1].y); - expect(result[1].z).toEqual(expected[1].z); - - expect(result[2].x).toEqual(expected[2].x); - expect(result[2].y).toEqual(expected[2].y); - expect(result[2].z).toEqual(expected[2].z); - }); - - it('getValue works for cartographic radians data', function() { - var property = new DynamicVertexPositionsProperty(); - property.processCzmlIntervals(cartographicRadiansInterval); - var result = property.getValue(new JulianDate()); - - var expected = Ellipsoid.WGS84.cartographicArrayToCartesianArray([new Cartographic(1.1, 1.2, 1.3), new Cartographic(1.4, 1.5, 1.6), new Cartographic(1.7, 1.8, 1.9)]); - - expect(result.length).toEqual(3); - expect(result[0].x).toEqual(expected[0].x); - expect(result[0].y).toEqual(expected[0].y); - expect(result[0].z).toEqual(expected[0].z); - - expect(result[1].x).toEqual(expected[1].x); - expect(result[1].y).toEqual(expected[1].y); - expect(result[1].z).toEqual(expected[1].z); - - expect(result[2].x).toEqual(expected[2].x); - expect(result[2].y).toEqual(expected[2].y); - expect(result[2].z).toEqual(expected[2].z); - }); - - it('getValue works for reference data', function() { - var source = new CzmlDataSource(); - var objects = source.getDynamicObjectCollection(); - source.load(testObjects); - var test1 = objects.getById('test1'); - var test2 = objects.getById('test2'); - var test3 = objects.getById('test3'); - - var property = new DynamicVertexPositionsProperty(); - property.processCzmlIntervals(referenceInterval, undefined, objects); - - var time = JulianDate.fromIso8601('2011-04-18T15:59:00Z'); - var result = property.getValue(time); - expect(result.length).toEqual(2); - expect(result[0]).toEqual(test1.position.getValue(time)); - expect(result[1]).toEqual(test2.position.getValue(time)); - - time = JulianDate.fromIso8601('2012-04-18T15:59:00Z'); - result = property.getValue(time); - expect(result.length).toEqual(3); - expect(result[0]).toEqual(test1.position.getValue(time)); - expect(result[1]).toEqual(test2.position.getValue(time)); - expect(result[2]).toEqual(test3.position.getValue(time)); - }); -}); diff --git a/Specs/DynamicScene/PositionPropertyArraySepc.js b/Specs/DynamicScene/PositionPropertyArraySepc.js new file mode 100644 index 000000000000..f10d3ac2973c --- /dev/null +++ b/Specs/DynamicScene/PositionPropertyArraySepc.js @@ -0,0 +1,107 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/PositionPropertyArray', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/SampledPositionProperty', + 'Core/Cartesian3', + 'Core/JulianDate', + 'Core/ReferenceFrame' + ], function( + PositionPropertyArray, + ConstantPositionProperty, + SampledPositionProperty, + Cartesian3, + JulianDate, + ReferenceFrame) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + it('default constructor sets expected values', function() { + var property = new PositionPropertyArray(); + expect(property.isConstant).toBe(true); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('constructor sets expected values', function() { + var expected = [Cartesian3.UNIT_X, Cartesian3.UNIT_Z]; + var value = [new ConstantPositionProperty(Cartesian3.UNIT_X), new ConstantPositionProperty(Cartesian3.UNIT_Z)]; + var property = new PositionPropertyArray(value); + expect(property.getValue(time)).toEqual(expected); + }); + + it('setValue rasies definitionChanged event', function() { + var property = new PositionPropertyArray(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue([]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('changing array member raises definitionChanged event', function() { + var property = new PositionPropertyArray(); + var item = new ConstantPositionProperty(Cartesian3.UNIT_X); + property.setValue([item]); + spyOn(property.definitionChanged, 'raiseEvent'); + item.setValue(Cartesian3.UNIT_Z); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('works with result parameter', function() { + var expected = [Cartesian3.UNIT_X, Cartesian3.UNIT_Z]; + var expectedResult = []; + var value = [new ConstantPositionProperty(Cartesian3.UNIT_X), new ConstantPositionProperty(Cartesian3.UNIT_Z)]; + var property = new PositionPropertyArray(value); + var result = property.getValue(time, expectedResult); + expect(result).toEqual(expected); + expect(result).toBe(expectedResult); + }); + + it('works with reference frame parameter', function() { + var value = [new ConstantPositionProperty(Cartesian3.UNIT_X, ReferenceFrame.INERTIAL), new ConstantPositionProperty(Cartesian3.UNIT_Z, ReferenceFrame.FIXED)]; + var expected = [value[0].getValueInReferenceFrame(time, ReferenceFrame.INERTIAL), value[1].getValueInReferenceFrame(time, ReferenceFrame.INERTIAL)]; + var property = new PositionPropertyArray(value); + var result = property.getValueInReferenceFrame(time, ReferenceFrame.INERTIAL); + expect(result).toEqual(expected); + }); + + it('works with undefined value', function() { + var property = new PositionPropertyArray(); + property.setValue(undefined); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('works with undefined propertyvalue', function() { + var property = new PositionPropertyArray(); + property.setValue([new ConstantPositionProperty()]); + expect(property.getValue(time)).toEqual([undefined]); + }); + + it('works with empty array', function() { + var property = new PositionPropertyArray(); + property.setValue([]); + expect(property.getValue(time)).toEqual([]); + }); + + it('equals works', function() { + var left = new PositionPropertyArray([new ConstantPositionProperty(Cartesian3.UNIT_X)]); + var right = new PositionPropertyArray([new ConstantPositionProperty(Cartesian3.UNIT_X)]); + + expect(left.equals(right)).toEqual(true); + + right = new PositionPropertyArray([new ConstantPositionProperty(Cartesian3.UNIT_Z)]); + expect(left.equals(right)).toEqual(false); + }); + + it('isConstant is true only if all members are constant', function() { + var property = new PositionPropertyArray(); + + property.setValue([new ConstantPositionProperty(Cartesian3.UNIT_X)]); + expect(property.isConstant).toBe(true); + + var sampledProperty = new SampledPositionProperty(); + sampledProperty.addSample(time, Cartesian3.UNIT_X); + property.setValue([new ConstantPositionProperty(Cartesian3.UNIT_Z), sampledProperty]); + + expect(property.isConstant).toBe(false); + }); +}); \ No newline at end of file diff --git a/Specs/DynamicScene/PropertyArraySepc.js b/Specs/DynamicScene/PropertyArraySepc.js new file mode 100644 index 000000000000..4864a87d0753 --- /dev/null +++ b/Specs/DynamicScene/PropertyArraySepc.js @@ -0,0 +1,97 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/PropertyArray', + 'DynamicScene/ConstantProperty', + 'DynamicScene/SampledProperty', + 'Core/Cartesian3', + 'Core/JulianDate' + ], function( + PropertyArray, + ConstantProperty, + SampledProperty, + Cartesian3, + JulianDate) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + it('default constructor sets expected values', function() { + var property = new PropertyArray(); + expect(property.isConstant).toBe(true); + expect(property.getValue(time)).toBeUndefined(); + }); + + it('constructor sets expected values', function() { + var expected = [1, 2]; + var value = [new ConstantProperty(1), new ConstantProperty(2)]; + var property = new PropertyArray(value); + expect(property.getValue(time)).toEqual(expected); + }); + + it('setValue rasies definitionChanged event', function() { + var property = new PropertyArray(); + spyOn(property.definitionChanged, 'raiseEvent'); + property.setValue([]); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('changing array member raises definitionChanged event', function() { + var property = new PropertyArray(); + var item = new ConstantProperty(1); + property.setValue([item]); + spyOn(property.definitionChanged, 'raiseEvent'); + item.setValue(2); + expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + }); + + it('works with result parameter', function() { + var expected = [1, 2]; + var expectedResult = []; + var value = [new ConstantProperty(1), new ConstantProperty(2)]; + var property = new PropertyArray(value); + var result = property.getValue(time, expectedResult); + expect(result).toEqual(expected); + expect(result).toBe(expectedResult); + }); + + it('works with undefined value', function() { + var property = new PropertyArray(); + property.setValue(undefined); + expect(property.getValue()).toBeUndefined(); + }); + + it('works with undefined propertyvalue', function() { + var property = new PropertyArray(); + property.setValue([new ConstantProperty()]); + expect(property.getValue()).toEqual([undefined]); + }); + + it('works with empty array', function() { + var property = new PropertyArray(); + property.setValue([]); + expect(property.getValue()).toEqual([]); + }); + + it('equals works', function() { + var left = new PropertyArray([new ConstantProperty(1)]); + var right = new PropertyArray([new ConstantProperty(1)]); + + expect(left.equals(right)).toEqual(true); + + right = new PropertyArray([new ConstantProperty(2)]); + expect(left.equals(right)).toEqual(false); + }); + + it('isConstant is true only if all members are constant', function() { + var property = new PropertyArray(); + + property.setValue([new ConstantProperty(2)]); + expect(property.isConstant).toBe(true); + + var sampledProperty = new SampledProperty(Number); + sampledProperty.addSample(time, 1); + property.setValue([new ConstantProperty(2), sampledProperty]); + + expect(property.isConstant).toBe(false); + }); +}); \ No newline at end of file From f81a5524a783cee4f3fdfab0a0472b316f3913e4 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 29 Jan 2014 09:34:14 -0500 Subject: [PATCH 09/81] Ongoing DynamicScene refactor 1. Add additional properties to DynamicEllipse, DynamicEllipsoid, and DynamicPolygon which will be used with new geometry code. 2. Tweaks to GeoJsonDataSource developers and minor CzmlDataSource cleanup. --- Source/DynamicScene/CzmlDataSource.js | 75 ++++++++++----- Source/DynamicScene/DynamicEllipse.js | 111 +++++++++++++++++++++-- Source/DynamicScene/DynamicEllipsoid.js | 39 +++++++- Source/DynamicScene/DynamicPolygon.js | 83 ++++++++++++++++- Source/DynamicScene/GeoJsonDataSource.js | 2 +- Specs/DynamicScene/CzmlDataSourceSpec.js | 8 ++ Specs/DynamicScene/DynamicPolygonSpec.js | 28 ++++++ 7 files changed, 313 insertions(+), 33 deletions(-) diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 7b8c670c83b4..f377331617ad 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -356,6 +356,12 @@ define([ var propertyCreated = false; var property = object[propertyName]; + var epoch; + var packetEpoch = packetData.epoch; + if (defined(packetEpoch)) { + epoch = JulianDate.fromIso8601(packetEpoch); + } + //Without an interval, any sampled value is infinite, meaning it completely //replaces any non-sampled property that may exist. if (isSampled && !hasInterval) { @@ -364,11 +370,6 @@ define([ object[propertyName] = property; propertyCreated = true; } - var epoch; - var packetEpoch = packetData.epoch; - if (defined(packetEpoch)) { - epoch = JulianDate.fromIso8601(packetEpoch); - } property.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, property); return propertyCreated; @@ -456,7 +457,7 @@ define([ interval.data = new SampledProperty(type); intervals.addInterval(interval); } - interval.data.addSamplesPackedArray(unwrappedInterval, JulianDate.fromIso8601(packetData.epoch)); + interval.data.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, interval.data); return propertyCreated; } @@ -503,6 +504,12 @@ define([ var propertyCreated = false; var property = object[propertyName]; + var epoch; + var packetEpoch = packetData.epoch; + if (defined(packetEpoch)) { + epoch = JulianDate.fromIso8601(packetEpoch); + } + //Without an interval, any sampled value is infinite, meaning it completely //replaces any non-sampled property that may exist. if (isSampled && !hasInterval) { @@ -511,11 +518,6 @@ define([ object[propertyName] = property; propertyCreated = true; } - var epoch; - var packetEpoch = packetData.epoch; - if (defined(packetEpoch)) { - epoch = JulianDate.fromIso8601(packetEpoch); - } property.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, property); return propertyCreated; @@ -597,7 +599,7 @@ define([ interval.data = new SampledPositionProperty(referenceFrame); intervals.addInterval(interval); } - interval.data.addSamplesPackedArray(unwrappedInterval, JulianDate.fromIso8601(packetData.epoch)); + interval.data.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, interval.data); return propertyCreated; } @@ -654,21 +656,17 @@ define([ combinedInterval = constrainedInterval; } - combinedInterval = defaultValue(combinedInterval, Iso8601.MAXIMUM_INTERVAL); - - var propertyCreated = false; var property = object[propertyName]; - if (!defined(property)) { + var existingMaterial; + var existingInterval; + + if (defined(combinedInterval)) { + if (!(property instanceof CompositeMaterialProperty)) { property = new CompositeMaterialProperty(); object[propertyName] = property; - propertyCreated = true; - } - //See if we already have data at that interval. var thisIntervals = property.intervals; - var existingInterval = thisIntervals.findInterval(combinedInterval.start, combinedInterval.stop); - var existingMaterial; - + existingInterval = thisIntervals.findInterval(combinedInterval.start, combinedInterval.stop); if (defined(existingInterval)) { //We have an interval, but we need to make sure the //new data is the same type of material as the old data. @@ -678,6 +676,10 @@ define([ existingInterval = combinedInterval.clone(); thisIntervals.addInterval(existingInterval); } + } + } else { + existingMaterial = property; + } var materialData; if (defined(packetData.solidColor)) { @@ -703,9 +705,12 @@ define([ processPacketData(Image, existingMaterial, 'image', materialData.image, undefined, sourceUri); existingMaterial.repeat = combineIntoCartesian2(existingMaterial.repeat, materialData.horizontalRepeat, materialData.verticalRepeat); } - existingInterval.data = existingMaterial; - return propertyCreated; + if (defined(existingInterval)) { + existingInterval.data = existingMaterial; + } else { + object[propertyName] = existingMaterial; + } } function processMaterialPacketData(object, propertyName, packetData, interval, sourceUri) { @@ -939,9 +944,19 @@ define([ dynamicObject.ellipse = ellipse = new DynamicEllipse(); } + processPacketData(Boolean, ellipse, 'show', ellipseData.show, interval, sourceUri); processPacketData(Number, ellipse, 'rotation', ellipseData.rotation, interval, sourceUri); processPacketData(Number, ellipse, 'semiMajorAxis', ellipseData.semiMajorAxis, interval, sourceUri); processPacketData(Number, ellipse, 'semiMinorAxis', ellipseData.semiMinorAxis, interval, sourceUri); + processPacketData(Number, ellipse, 'height', ellipseData.height, interval, sourceUri); + processPacketData(Number, ellipse, 'extrudedHeight', ellipseData.extrudedHeight, interval, sourceUri); + processPacketData(Number, ellipse, 'granularity', ellipseData.granularity, interval, sourceUri); + processPacketData(Number, ellipse, 'stRotation', ellipseData.stRotation, interval, sourceUri); + processMaterialPacketData(ellipse, 'material', ellipseData.material, interval, sourceUri); + processPacketData(Boolean, ellipse, 'fill', ellipseData.fill, interval, sourceUri); + processPacketData(Boolean, ellipse, 'outline', ellipseData.outline, interval, sourceUri); + processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri); + processPacketData(Number, ellipse, 'outlineWidth', ellipseData.outlineWidth, interval, sourceUri); } function processEllipsoid(dynamicObject, packet, dynamicObjectCollection, sourceUri) { @@ -963,6 +978,10 @@ define([ processPacketData(Boolean, ellipsoid, 'show', ellipsoidData.show, interval, sourceUri); processPacketData(Cartesian3, ellipsoid, 'radii', ellipsoidData.radii, interval, sourceUri); processMaterialPacketData(ellipsoid, 'material', ellipsoidData.material, interval, sourceUri); + processPacketData(Boolean, ellipsoid, 'fill', ellipsoidData.fill, interval, sourceUri); + processPacketData(Boolean, ellipsoid, 'outline', ellipsoidData.outline, interval, sourceUri); + processPacketData(Color, ellipsoid, 'outlineColor', ellipsoidData.outlineColor, interval, sourceUri); + processPacketData(Number, ellipsoid, 'outlineWidth', ellipsoidData.outlineWidth, interval, sourceUri); } function processLabel(dynamicObject, packet, dynamicObjectCollection, sourceUri) { @@ -1062,6 +1081,14 @@ define([ processPacketData(Boolean, polygon, 'show', polygonData.show, interval, sourceUri); processMaterialPacketData(polygon, 'material', polygonData.material, interval, sourceUri); + processPacketData(Number, polygon, 'height', polygonData.height, interval, sourceUri); + processPacketData(Number, polygon, 'extrudedHeight', polygonData.extrudedHeight, interval, sourceUri); + processPacketData(Number, polygon, 'granularity', polygonData.granularity, interval, sourceUri); + processPacketData(Number, polygon, 'stRotation', polygonData.stRotation, interval, sourceUri); + processPacketData(Boolean, polygon, 'fill', polygonData.fill, interval, sourceUri); + processPacketData(Boolean, polygon, 'outline', polygonData.outline, interval, sourceUri); + processPacketData(Color, polygon, 'outlineColor', polygonData.outlineColor, interval, sourceUri); + processPacketData(Number, polygon, 'outlineWidth', polygonData.outlineWidth, interval, sourceUri); } function processPolyline(dynamicObject, packet, dynamicObjectCollection, sourceUri) { diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index 4250ea0a93dc..af0eb3a4ef1b 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -30,12 +30,15 @@ define(['../Core/Cartesian3', this._semiMajorAxis = undefined; this._semiMinorAxis = undefined; this._rotation = undefined; - this._lastPosition = undefined; - this._lastSemiMajorAxis = undefined; - this._lastSemiMinorAxis = undefined; - this._lastRotation = undefined; - this._cachedVertexPositions = undefined; + this._show = undefined; + this._material = undefined; + this._height = undefined; + this._extrudedHeight = undefined; + this._granularity = undefined; + this._stRotation = undefined; this._propertyChanged = new Event(); + this._outline = undefined; + this._outlineColor = undefined; }; defineProperties(DynamicEllipse.prototype, { @@ -69,7 +72,82 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - rotation : createDynamicPropertyDescriptor('rotation', '_rotation') + rotation : createDynamicPropertyDescriptor('rotation', '_rotation'), + + /** + * Gets or sets the boolean {@link Property} specifying the polygon's visibility. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + show : createDynamicPropertyDescriptor('show', '_show'), + + /** + * Gets or sets the {@link MaterialProperty} specifying the appearance of the polygon. + * @memberof DynamicEllipse.prototype + * @type {MaterialProperty} + */ + material : createDynamicPropertyDescriptor('material', '_material'), + + /** + * Gets or sets the Number {@link Property} specifying the height of the polygon. + * If undefined, the polygon will be on the surface. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + height : createDynamicPropertyDescriptor('height', '_height'), + + /** + * Gets or sets the Number {@link Property} specifying the extruded height of the polygon. + * Setting this property creates a polygon shaped volume starting at height and ending + * at the extruded height. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight', '_extrudedHeight'), + + /** + * Gets or sets the Number {@link Property} specifying the sampling distance, in radians, + * between each latitude and longitude point. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + granularity : createDynamicPropertyDescriptor('granularity', '_granularity'), + + /** + * Gets or sets the Number {@link Property} specifying the rotation of the texture coordinates, + * in radians. A positive rotation is counter-clockwise. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + stRotation : createDynamicPropertyDescriptor('stRotation', '_stRotation'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the ellipse should be filled. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + fill : createDynamicPropertyDescriptor('fill', '_fill'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the ellipse should be outlined. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + outline : createDynamicPropertyDescriptor('outline', '_outline'), + + /** + * Gets or sets the Number {@link Property} specifying whether the width of the outline. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + + /** + * Gets or sets the Color {@link Property} specifying whether the color of the outline. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') }); /** @@ -86,6 +164,16 @@ define(['../Core/Cartesian3', result.rotation = this.rotation; result.semiMajorAxis = this.semiMajorAxis; result.semiMinorAxis = this.semiMinorAxis; + result.show = this.show; + result.material = this.material; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.stRotation = this.stRotation; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; return result; }; @@ -107,8 +195,19 @@ define(['../Core/Cartesian3', this.rotation = defaultValue(this.rotation, source.rotation); this.semiMajorAxis = defaultValue(this.semiMajorAxis, source.semiMajorAxis); this.semiMinorAxis = defaultValue(this.semiMinorAxis, source.semiMinorAxis); + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.stRotation = defaultValue(this.stRotation, source.stRotation); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; + /** * Gets an array of vertex positions for the ellipse at the provided time. * diff --git a/Source/DynamicScene/DynamicEllipsoid.js b/Source/DynamicScene/DynamicEllipsoid.js index 58bb3b6b1732..e982f03639a9 100644 --- a/Source/DynamicScene/DynamicEllipsoid.js +++ b/Source/DynamicScene/DynamicEllipsoid.js @@ -58,7 +58,36 @@ define(['../Core/defaultValue', * @memberof DynamicEllipsoid.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material') + material : createDynamicPropertyDescriptor('material', '_material'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the ellipsoid should be filled. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + fill : createDynamicPropertyDescriptor('fill', '_fill'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the ellipsoid should be outlined. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + outline : createDynamicPropertyDescriptor('outline', '_outline'), + + /** + * Gets or sets the Number {@link Property} specifying whether the width of the outline. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + + /** + * Gets or sets the Color {@link Property} specifying whether the color of the outline. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') + }); /** @@ -75,6 +104,10 @@ define(['../Core/defaultValue', result.show = this.show; result.radii = this.radii; result.material = this.material; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; return result; }; @@ -96,6 +129,10 @@ define(['../Core/defaultValue', this.show = defaultValue(this.show, source.show); this.radii = defaultValue(this.radii, source.radii); this.material = defaultValue(this.material, source.material); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; return DynamicEllipsoid; diff --git a/Source/DynamicScene/DynamicPolygon.js b/Source/DynamicScene/DynamicPolygon.js index 5d69412f0715..adc828a98a7a 100644 --- a/Source/DynamicScene/DynamicPolygon.js +++ b/Source/DynamicScene/DynamicPolygon.js @@ -23,6 +23,10 @@ define(['../Core/defaultValue', var DynamicPolygon = function() { this._show = undefined; this._material = undefined; + this._height = undefined; + this._extrudedHeight = undefined; + this._granularity = undefined; + this._stRotation = undefined; this._propertyChanged = new Event(); }; @@ -50,7 +54,68 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material') + material : createDynamicPropertyDescriptor('material', '_material'), + + /** + * Gets or sets the Number {@link Property} specifying the height of the polygon. + * If undefined, the polygon will be on the surface. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + height : createDynamicPropertyDescriptor('height', '_height'), + + /** + * Gets or sets the Number {@link Property} specifying the extruded height of the polygon. + * Setting this property creates a polygon shaped volume starting at height and ending + * at the extruded height. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight', '_extrudedHeight'), + + /** + * Gets or sets the Number {@link Property} specifying the sampling distance, in radians, + * between each latitude and longitude point. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + granularity : createDynamicPropertyDescriptor('granularity', '_granularity'), + + /** + * Gets or sets the Number {@link Property} specifying the rotation of the texture coordinates, + * in radians. A positive rotation is counter-clockwise. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + stRotation : createDynamicPropertyDescriptor('stRotation', '_stRotation'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the polygon should be filled. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + fill : createDynamicPropertyDescriptor('fill', '_fill'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the polygon should be outlined. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + outline : createDynamicPropertyDescriptor('outline', '_outline'), + + /** + * Gets or sets the Number {@link Property} specifying whether the width of the outline. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + + /** + * Gets or sets the Color {@link Property} specifying whether the color of the outline. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') }); /** @@ -66,6 +131,14 @@ define(['../Core/defaultValue', } result.show = this.show; result.material = this.material; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.stRotation = this.stRotation; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; return result; }; @@ -86,6 +159,14 @@ define(['../Core/defaultValue', this.show = defaultValue(this.show, source.show); this.material = defaultValue(this.material, source.material); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.stRotation = defaultValue(this.stRotation, source.stRotation); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; return DynamicPolygon; diff --git a/Source/DynamicScene/GeoJsonDataSource.js b/Source/DynamicScene/GeoJsonDataSource.js index 45688c25ce04..477ee0a7383c 100644 --- a/Source/DynamicScene/GeoJsonDataSource.js +++ b/Source/DynamicScene/GeoJsonDataSource.js @@ -244,7 +244,7 @@ define([ defaultPolygon.polygon = polygon; material = new ColorMaterialProperty(); - material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.1)); + material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.25)); polygon.material = material; this._changed = new Event(); diff --git a/Specs/DynamicScene/CzmlDataSourceSpec.js b/Specs/DynamicScene/CzmlDataSourceSpec.js index a5c3e897544d..1343638faa7e 100644 --- a/Specs/DynamicScene/CzmlDataSourceSpec.js +++ b/Specs/DynamicScene/CzmlDataSourceSpec.js @@ -1294,6 +1294,10 @@ defineSuite([ } } }, + height : 1, + extrudedHeight : 2, + granularity : 3, + stRotation : 4, show : true } }; @@ -1305,6 +1309,10 @@ defineSuite([ expect(dynamicObject.polygon).toBeDefined(); expect(dynamicObject.polygon.material.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polygon.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(true); + expect(dynamicObject.polygon.height.getValue(Iso8601.MINIMUM_VALUE)).toEqual(1); + expect(dynamicObject.polygon.extrudedHeight.getValue(Iso8601.MINIMUM_VALUE)).toEqual(2); + expect(dynamicObject.polygon.granularity.getValue(Iso8601.MINIMUM_VALUE)).toEqual(3); + expect(dynamicObject.polygon.stRotation.getValue(Iso8601.MINIMUM_VALUE)).toEqual(4); }); it('CZML adds data for constrained polygon.', function() { diff --git a/Specs/DynamicScene/DynamicPolygonSpec.js b/Specs/DynamicScene/DynamicPolygonSpec.js index 5d1135fc0b1a..017f78ef86e4 100644 --- a/Specs/DynamicScene/DynamicPolygonSpec.js +++ b/Specs/DynamicScene/DynamicPolygonSpec.js @@ -16,12 +16,20 @@ defineSuite([ var source = new DynamicPolygon(); source.material = new ColorMaterialProperty(); source.show = new ConstantProperty(true); + source.height = new ConstantProperty(1); + source.extrudedHeight = new ConstantProperty(2); + source.granularity = new ConstantProperty(3); + source.stRotation = new ConstantProperty(4); var target = new DynamicPolygon(); target.merge(source); expect(target.material).toBe(source.material); expect(target.show).toBe(source.show); + expect(target.height).toBe(source.height); + expect(target.extrudedHeight).toBe(source.extrudedHeight); + expect(target.granularity).toBe(source.granularity); + expect(target.stRotation).toBe(source.stRotation); }); it('merge does not assign assigned properties', function() { @@ -31,25 +39,45 @@ defineSuite([ var material = new ColorMaterialProperty(); var show = new ConstantProperty(true); + var height = new ConstantProperty(1); + var extrudedHeight = new ConstantProperty(2); + var granularity = new ConstantProperty(3); + var stRotation = new ConstantProperty(4); var target = new DynamicPolygon(); target.material = material; target.show = show; + target.height = height; + target.extrudedHeight = extrudedHeight; + target.granularity = granularity; + target.stRotation = stRotation; target.merge(source); expect(target.material).toBe(material); expect(target.show).toBe(show); + expect(target.height).toBe(height); + expect(target.extrudedHeight).toBe(extrudedHeight); + expect(target.granularity).toBe(granularity); + expect(target.stRotation).toBe(stRotation); }); it('clone works', function() { var source = new DynamicPolygon(); source.material = new ColorMaterialProperty(); source.show = new ConstantProperty(true); + source.height = new ConstantProperty(1); + source.extrudedHeight = new ConstantProperty(2); + source.granularity = new ConstantProperty(3); + source.stRotation = new ConstantProperty(4); var result = source.clone(); expect(result.material).toBe(source.material); expect(result.show).toBe(source.show); + expect(result.height).toBe(source.height); + expect(result.extrudedHeight).toBe(source.extrudedHeight); + expect(result.granularity).toBe(source.granularity); + expect(result.stRotation).toBe(source.stRotation); }); it('merge throws if source undefined', function() { From 0aff771c2f04d843b8f8e441f785f5b138ecf1bd Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 29 Jan 2014 10:27:10 -0500 Subject: [PATCH 10/81] Fix custom property used for CZML processing. --- Source/DynamicScene/CzmlDataSource.js | 117 ++++++++++++++++++++------ 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index f377331617ad..bf67cd590a74 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -1,6 +1,5 @@ /*global define*/ -define([ - '../Core/Cartesian2', +define(['../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartographic', '../Core/Color', @@ -9,6 +8,7 @@ define([ '../Core/createGuid', '../Core/defaultValue', '../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError', '../Core/Ellipsoid', '../Core/Event', @@ -70,6 +70,7 @@ define([ createGuid, defaultValue, defined, + defineProperties, DeveloperError, Ellipsoid, Event, @@ -123,6 +124,92 @@ define([ when) { "use strict"; + //This class is a workaround for CZML represented as two properties which get turned into a single Cartesian2 property once loaded. + var Cartesian2WrapperProperty = function() { + this._definitionChanged = new Event(); + this._x = undefined; + this._xSubscription = undefined; + this._y = undefined; + this._ySubscription = undefined; + + this.x = new ConstantProperty(0); + this.y = new ConstantProperty(0.1); + }; + + defineProperties(Cartesian2WrapperProperty.prototype, { + isConstant : { + get : function() { + return this._x.isConstant && this._y.isConstant; + } + }, + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + x : { + get : function() { + return this._x; + }, + set : function(value) { + if (this._x !== value) { + if (this._xSubscription) { + this._xSubscription(); + this._xSubscription = undefined; + } + this._x = value; + if (defined(value)) { + this._xSubscription = value.definitionChanged.addEventListener(Cartesian2WrapperProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + }, + y : { + get : function() { + return this._y; + }, + set : function(value) { + if (this._y !== value) { + if (this._ySubscription) { + this._ySubscription(); + this._ySubscription = undefined; + } + this._y = value; + if (defined(value)) { + this._ySubscription = value.definitionChanged.addEventListener(Cartesian2WrapperProperty.prototype._raiseDefinitionChanged, this); + } + this._raiseDefinitionChanged(this); + } + } + } + }); + + Cartesian2WrapperProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = new Cartesian2(); + } + result.x = this._x.getValue(time); + result.y = this._y.getValue(time); + return result; + }; + + Cartesian2WrapperProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + + function combineIntoCartesian2(object, packetDataX, packetDataY) { + if (!defined(packetDataX) && !defined(packetDataY)) { + return object; + } + if (!(object instanceof Cartesian2WrapperProperty)) { + object = new Cartesian2WrapperProperty(); + } + processPacketData(Number, object, 'x', packetDataX); + processPacketData(Number, object, 'y', packetDataY); + return object; + } + var scratchCartesian = new Cartesian3(); var scratchSpherical = new Spherical(); var scratchCartographic = new Cartographic(); @@ -618,32 +705,6 @@ define([ } } - var Cartesian2WrapperProperty = function() { - this._x = new ConstantProperty(0); - this._y = new ConstantProperty(0); - }; - - Cartesian2WrapperProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = new Cartesian2(); - } - result.x = this._x.getValue(time); - result.y = this._y.getValue(time); - return result; - }; - - function combineIntoCartesian2(object, packetDataX, packetDataY) { - if (!defined(packetDataX) && !defined(packetDataY)) { - return object; - } - if (!(object instanceof Cartesian2WrapperProperty)) { - object = new Cartesian2WrapperProperty(); - } - processPacketData(Number, object, '_x', packetDataX); - processPacketData(Number, object, '_y', packetDataY); - return object; - } - function processMaterialProperty(object, propertyName, packetData, constrainedInterval, sourceUri) { var combinedInterval; var packetInterval = packetData.interval; From 14c53f8296e13b278188cc79d4316887bf48c2a4 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 29 Jan 2014 17:33:21 -0500 Subject: [PATCH 11/81] Temporarily remove DynamicEllipse visualization. It will be re-implemented using Geometry & Appearances. --- Source/DynamicScene/DynamicEllipse.js | 55 ---------------- .../DynamicScene/DynamicPolygonVisualizer.js | 18 ++--- .../DynamicScene/DynamicPolylineVisualizer.js | 12 +--- .../DynamicPolygonVisualizerSpec.js | 59 ----------------- .../DynamicPolylineVisualizerSpec.js | 66 ------------------- 5 files changed, 6 insertions(+), 204 deletions(-) diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index af0eb3a4ef1b..06bd6f312537 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -207,60 +207,5 @@ define(['../Core/Cartesian3', this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; - - /** - * Gets an array of vertex positions for the ellipse at the provided time. - * - * @param {JulianDate} time The desired time. - * @param {Ellipsoid} ellipsoid The ellipsoid on which the ellipse will be on. - * @param {Cartesian3} position The position of the ellipsoid. - * @returns An array of vertex positions. - */ - DynamicEllipse.prototype.getValue = function(time, position) { - var semiMajorAxisProperty = this._semiMajorAxis; - var semiMinorAxisProperty = this._semiMinorAxis; - - if (!defined(position) || // - !defined(semiMajorAxisProperty) || // - !defined(semiMinorAxisProperty)) { - return undefined; - } - - var semiMajorAxis = semiMajorAxisProperty.getValue(time); - var semiMinorAxis = semiMinorAxisProperty.getValue(time); - - var rotation = 0.0; - var rotationProperty = this._rotation; - if (defined(rotationProperty)) { - rotation = rotationProperty.getValue(time); - } - - if (!defined(semiMajorAxis) || // - !defined(semiMinorAxis) || // - semiMajorAxis === 0.0 || // - semiMinorAxis === 0.0) { - return undefined; - } - - var lastPosition = this._lastPosition; - var lastSemiMajorAxis = this._lastSemiMajorAxis; - var lastSemiMinorAxis = this._lastSemiMinorAxis; - var lastRotation = this._lastRotation; - if (rotation !== lastRotation || // - lastSemiMajorAxis !== semiMajorAxis || // - lastSemiMinorAxis !== semiMinorAxis || // - !Cartesian3.equals(lastPosition, position)) { - - //CZML_TODO The surface reference should come from CZML and not be hard-coded to Ellipsoid.WGS84. - this._cachedVertexPositions = Shapes.computeEllipseBoundary(Ellipsoid.WGS84, position, semiMajorAxis, semiMinorAxis, rotation); - this._lastPosition = Cartesian3.clone(position, this._lastPosition); - this._lastRotation = rotation; - this._lastSemiMajorAxis = semiMajorAxis; - this._lastSemiMinorAxis = semiMinorAxis; - } - - return this._cachedVertexPositions; - }; - return DynamicEllipse; }); diff --git a/Source/DynamicScene/DynamicPolygonVisualizer.js b/Source/DynamicScene/DynamicPolygonVisualizer.js index 8365092862b8..b07ac790ed21 100644 --- a/Source/DynamicScene/DynamicPolygonVisualizer.js +++ b/Source/DynamicScene/DynamicPolygonVisualizer.js @@ -187,15 +187,11 @@ define([ var polygon; var showProperty = dynamicPolygon._show; - var ellipseProperty = dynamicObject._ellipse; var positionProperty = dynamicObject._position; var vertexPositionsProperty = dynamicObject._vertexPositions; var polygonVisualizerIndex = dynamicObject._polygonVisualizerIndex; var show = dynamicObject.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); - var hasVertexPostions = defined(vertexPositionsProperty); - if (!show || // - (!hasVertexPostions && // - (!defined(ellipseProperty) || !defined(positionProperty)))) { + if (!show || !defined(vertexPositionsProperty)) { //Remove the existing primitive if we have one if (defined(polygonVisualizerIndex)) { polygon = dynamicPolygonVisualizer._polygonCollection[polygonVisualizerIndex]; @@ -230,16 +226,10 @@ define([ polygon.show = true; - var vertexPositions; - if (hasVertexPostions) { - vertexPositions = vertexPositionsProperty.getValue(time); - } else { - vertexPositions = ellipseProperty.getValue(time, positionProperty.getValue(time, cachedPosition)); - } - + var vertexPositions = vertexPositionsProperty.getValue(time); if (polygon._visualizerPositions !== vertexPositions && // - defined(vertexPositions) && // - vertexPositions.length > 3) { + defined(vertexPositions) && // + vertexPositions.length > 3) { polygon.setPositions(vertexPositions); polygon._visualizerPositions = vertexPositions; } diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index 4e54f47b85de..ace322b6cb66 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -186,16 +186,13 @@ define([ var polyline; var showProperty = dynamicPolyline._show; - var ellipseProperty = dynamicObject._ellipse; var positionProperty = dynamicObject._position; var vertexPositionsProperty = dynamicObject._vertexPositions; var polylineVisualizerIndex = dynamicObject._polylineVisualizerIndex; var show = dynamicObject.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); var context = dynamicPolylineVisualizer._scene.getContext(); - if (!show || // - (!defined(vertexPositionsProperty) && // - (!defined(ellipseProperty) || !defined(positionProperty)))) { + if (!show || !defined(vertexPositionsProperty)) { //Remove the existing primitive if we have one if (defined(polylineVisualizerIndex)) { polyline = dynamicPolylineVisualizer._polylineCollection.get(polylineVisualizerIndex); @@ -232,12 +229,7 @@ define([ polyline.setShow(true); - var vertexPositions; - if (defined(ellipseProperty)) { - vertexPositions = ellipseProperty.getValue(time, positionProperty.getValue(time, cachedPosition)); - } else { - vertexPositions = vertexPositionsProperty.getValue(time); - } + var vertexPositions = vertexPositionsProperty.getValue(time); if (defined(vertexPositions) && polyline._visualizerPositions !== vertexPositions) { polyline.setPositions(vertexPositions); diff --git a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js b/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js index b4c60b7ef344..532bf80ef0b4 100644 --- a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js @@ -98,65 +98,6 @@ defineSuite([ expect(scene.getPrimitives().getLength()).toEqual(0); }); - it('object with ellipse and no position does not create a polygon.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.ellipse = new DynamicEllipse(); - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('object with ellipse and position properties and no ellipse properties does not create positions.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.ellipse = new DynamicEllipse(); - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(1); - var primitive = scene.getPrimitives().get(0); - expect(primitive.getPositions()).toBeUndefined(); - }); - - it('DynamicPolygon with ellipse and position creates a primitive and updates it.', function() { - var time = new JulianDate(); - - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(0); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - polygon.material = new ColorMaterialProperty(); - - var ellipse = testObject.ellipse = new DynamicEllipse(); - ellipse.rotation = new ConstantProperty(0); - ellipse.semiMajorAxis = new ConstantProperty(1000); - ellipse.semiMinorAxis = new ConstantProperty(1000); - visualizer.update(new JulianDate()); - - expect(scene.getPrimitives().getLength()).toEqual(1); - - var primitive = scene.getPrimitives().get(0); - - visualizer.update(time); - expect(primitive.show).toEqual(testObject.polygon.show.getValue(time)); - expect(primitive.material.uniforms).toEqual(testObject.polygon.material.getValue(time)); - expect(primitive.getPositions().length > 0); - - }); - it('A DynamicPolygon causes a primtive to be created and updated.', function() { var time = new JulianDate(); diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index 6b572c610731..f9e3f4e062ad 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -106,72 +106,6 @@ defineSuite([ expect(polylineCollection.getLength()).toEqual(0); }); - it('object with ellipse and no position does not create a polyline.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.ellipse = new DynamicEllipse(); - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(0); - }); - - it('object with ellipse and position properties and no ellipse properties does not create positions.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.ellipse = new DynamicEllipse(); - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - var primitive = polylineCollection.get(0); - expect(primitive.getPositions().length).toEqual(0); - }); - - it('DynamicPolyline with ellipse and position creates a primitive and updates it.', function() { - var time = new JulianDate(); - - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(1); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - - var ellipse = testObject.ellipse = new DynamicEllipse(); - ellipse.rotation = new ConstantProperty(0); - ellipse.semiMajorAxis = new ConstantProperty(1000); - ellipse.semiMinorAxis = new ConstantProperty(1000); - visualizer.update(new JulianDate()); - - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(1); - var primitive = polylineCollection.get(0); - expect(primitive.getPositions().length).toBeGreaterThan(0); - - - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - polylineCollection = scene.getPrimitives().get(0); - primitive = polylineCollection.get(0); - expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); - expect(primitive.getPositions().length > 0); - - }); - it('A DynamicPolyline causes a primtive to be created and updated.', function() { var time = new JulianDate(); From 56c6e5d1bf3f9babafde12a6d0b7b82c219579be Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 30 Jan 2014 14:58:42 -0500 Subject: [PATCH 12/81] Everything old is new again Start of a new approach to taking advantange of Geometry & Appearances in DynamicScene. This manually ports some code from the abandoned dynamicScene-geometry branch and modifies it slightly for a new, cleaner approach. This is just the first baby stem to the process and lots of things don't work yet. --- Source/Core/Map.js | 42 +++ Source/DynamicScene/DataSourceDisplay.js | 39 ++- Source/DynamicScene/EllipseGeometryUpdater.js | 252 +++++++++++++++++ Source/DynamicScene/GeometryBatchType.js | 13 + Source/DynamicScene/GeometryVisualizer.js | 257 ++++++++++++++++++ .../DynamicScene/StaticGeometryColorBatch.js | 205 ++++++++++++++ .../EllipseGeometryUpdaterSpec.js | 130 +++++++++ 7 files changed, 927 insertions(+), 11 deletions(-) create mode 100644 Source/Core/Map.js create mode 100644 Source/DynamicScene/EllipseGeometryUpdater.js create mode 100644 Source/DynamicScene/GeometryBatchType.js create mode 100644 Source/DynamicScene/GeometryVisualizer.js create mode 100644 Source/DynamicScene/StaticGeometryColorBatch.js create mode 100644 Specs/DynamicScene/EllipseGeometryUpdaterSpec.js diff --git a/Source/Core/Map.js b/Source/Core/Map.js new file mode 100644 index 000000000000..41b54ecc261e --- /dev/null +++ b/Source/Core/Map.js @@ -0,0 +1,42 @@ +/*global define*/ +define(['./defined', + './DeveloperError' + ], function( + defined, DeveloperError) { + "use strict"; + + var Map = function() { + this._array = []; + this._hash = {}; + }; + + Map.prototype.set = function(key, value) { + this._hash[key] = value; + this._array.push(value); + }; + + Map.prototype.get = function(key) { + return this._hash[key]; + }; + + Map.prototype.getValues = function() { + return this._array; + }; + + Map.prototype.remove = function(key) { + var hasValue = defined(this._hash[key]); + if (hasValue) { + var array = this._array; + array.splice(array.indexOf(this._hash[key]), 1); + this._hash[key] = undefined; + } + return hasValue; + }; + + Map.prototype.removeAll = function() { + this._hash = {}; + this._array.length = 0; + }; + + return Map; +}); diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 36f576ae8ee3..d1296205bcb5 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -6,6 +6,7 @@ define([ '../Core/DeveloperError', '../Core/EventHelper', './DynamicBillboardVisualizer', + './EllipseGeometryUpdater', './DynamicEllipsoidVisualizer', './DynamicConeVisualizerUsingCustomSensor', './DynamicLabelVisualizer', @@ -15,6 +16,7 @@ define([ './DynamicPolylineVisualizer', './DynamicPyramidVisualizer', './DynamicVectorVisualizer', + './GeometryVisualizer', './VisualizerCollection' ], function( defaultValue, @@ -23,6 +25,7 @@ define([ DeveloperError, EventHelper, DynamicBillboardVisualizer, + EllipseGeometryUpdater, DynamicEllipsoidVisualizer, DynamicConeVisualizerUsingCustomSensor, DynamicLabelVisualizer, @@ -32,19 +35,33 @@ define([ DynamicPolylineVisualizer, DynamicPyramidVisualizer, DynamicVectorVisualizer, + GeometryVisualizer, VisualizerCollection) { "use strict"; - var defaultVisualizerTypes = [DynamicBillboardVisualizer, - DynamicEllipsoidVisualizer, - DynamicConeVisualizerUsingCustomSensor, - DynamicLabelVisualizer, - DynamicPointVisualizer, - DynamicPolygonVisualizer, - DynamicPolylineVisualizer, - DynamicPyramidVisualizer, - DynamicPathVisualizer, - DynamicVectorVisualizer]; + var defaultVisualizerTypes = [function(scene) { + return new DynamicBillboardVisualizer(scene); + }, function(scene) { + return new GeometryVisualizer(EllipseGeometryUpdater, scene); + }, function(scene) { + return new DynamicEllipsoidVisualizer(scene); + }, function(scene) { + return new DynamicConeVisualizerUsingCustomSensor(scene); + }, function(scene) { + return new DynamicLabelVisualizer(scene); + }, function(scene) { + return new DynamicPointVisualizer(scene); + }, function(scene) { + return new DynamicPolygonVisualizer(scene); + }, function(scene) { + return new DynamicPolylineVisualizer(scene); + }, function(scene) { + return new DynamicVectorVisualizer(scene); + }, function(scene) { + return new DynamicPyramidVisualizer(scene); + }, function(scene) { + return new DynamicPathVisualizer(scene); + }]; /** * Visualizes a collection of {@link DataSource} instances. @@ -188,7 +205,7 @@ define([ var visualizers = new Array(length); var scene = this._scene; for ( var i = 0; i < length; i++) { - visualizers[i] = new visualizerTypes[i](scene); + visualizers[i] = visualizerTypes[i](scene); } var vCollection = new VisualizerCollection(visualizers, dataSource.getDynamicObjectCollection()); diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js new file mode 100644 index 000000000000..147fdf1bdb4c --- /dev/null +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -0,0 +1,252 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ShowGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/GeometryInstance', + '../Core/EllipseGeometry', + '../Core/Iso8601', + '../DynamicScene/ConstantProperty', + '../DynamicScene/ConstantPositionProperty', + '../DynamicScene/ColorMaterialProperty', + '../DynamicScene/GeometryBatchType', + '../Scene/Primitive', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Material', + './MaterialProperty' + ], function( + Color, + ColorGeometryInstanceAttribute, + defineProperties, + DeveloperError, + Event, + ShowGeometryInstanceAttribute, + defaultValue, + defined, + GeometryInstance, + EllipseGeometry, + Iso8601, + ConstantProperty, + ConstantPositionProperty, + ColorMaterialProperty, + GeometryBatchType, + Primitive, + MaterialAppearance, + PerInstanceColorAppearance, + Material, + MaterialProperty) { + "use strict"; + + var GeometryOptions = function(dynamicObject) { + this.id = dynamicObject; + this.vertexFormat = undefined; + this.center = undefined; + this.semiMajorAxis = undefined; + this.semiMinorAxis = undefined; + this.rotation = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + this.stRotation = undefined; + this.numberOfVerticalLines = undefined; + }; + + var EllipseGeometryUpdater = function(dynamicObject) { + if (!defined(dynamicObject)) { + throw new DeveloperError('dynamicObject is required'); + } + + this._dynamicObject = dynamicObject; + this._id = dynamicObject.id; + this._dynamicObjectSubscription = dynamicObject.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); + this._ellipseSubscription = undefined; + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged = new Event(); + this._geometryInstance = undefined; + this._options = new GeometryOptions(dynamicObject); + this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); + }; + + EllipseGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; + + EllipseGeometryUpdater.MaterialAppearanceType = MaterialAppearance; + + EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { + var attributes; + if (!defined(this._geometryInstance)) { + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), + color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) + }; + } + + this._geometryInstance = new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseGeometry(this._options), + attributes : attributes + }); + } else { + attributes = this._geometryInstance.attributes; + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), + color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) + }; + } + } + + return this._geometryInstance; + }; + + defineProperties(EllipseGeometryUpdater.prototype, { + id : { + get : function() { + return this._id; + } + }, + geometryType : { + get : function() { + return this._geometryType; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } + }, + show : { + get : function() { + return this._show; + } + }, + material : { + get : function() { + return this._material; + } + } + }); + + function setGeometryType(that, geometryType) { + that._geometryType = geometryType; + that._geometryInstance = undefined; + that._geometryChanged.raiseEvent(); + } + + EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { + if (propertyName === 'ellipse') { + if (defined(oldValue)) { + this._ellipseSubscription(); + } + + this._ellipse = newValue; + + if (defined(newValue)) { + this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); + } + + this._onEllipsePropertyChanged(); + } else if (propertyName === 'position') { + this._update(); + } + }; + + EllipseGeometryUpdater.prototype._onEllipsePropertyChanged = function(ellipse, propertyName, newValue, oldValue) { + this._update(); + }; + + EllipseGeometryUpdater.prototype._update = function() { + var ellipse = this._dynamicObject.ellipse; + + if (!defined(ellipse)) { + setGeometryType(this, GeometryBatchType.NONE); + return; + } + + var createInstance = false; + var dynamicOptions = {}; + var options = this._options; + + var fill = ellipse.fill; + if (defined(fill)) { + if (fill.isConstant) { + if (!fill.getValue(Iso8601.MINIMUM_VALUE)) { + setGeometryType(this, GeometryBatchType.NONE); + return; + } + } else { + dynamicOptions.fill = fill; + } + } + + var show = ellipse.show; + if (defined(show)) { + if (show.isConstant) { + if (!show.getValue(Iso8601.MINIMUM_VALUE)) { + setGeometryType(this, GeometryBatchType.NONE); + return; + } + } else { + dynamicOptions.show = fill; + } + } + + var material = ellipse.material; + var isColorMaterial = !defined(material) || material instanceof ColorMaterialProperty; + + this._material = material; + this._show = show; + + var position = this._dynamicObject.position; + var semiMajorAxis = ellipse.semiMajorAxis; + var semiMinorAxis = ellipse.semiMinorAxis; + + if (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis)) { + setGeometryType(this, GeometryBatchType.NONE); + return; + } + + var rotation = ellipse.rotation; + var height = ellipse.height; + var extrudedHeight = ellipse.extrudedHeight; + var granularity = ellipse.granularity; + var stRotation = ellipse.stRotation; + + if (!position.isConstant || // + !semiMajorAxis.isConstant || // + !semiMinorAxis.isConstant || // + defined(rotation) && !rotation.isConstant || // + defined(height) && !height.isConstant || // + defined(extrudedHeight) && !extrudedHeight.isConstant || // + defined(granularity) && !granularity.isConstant || // + defined(stRotation) && !stRotation.isConstant) { + setGeometryType(this, GeometryBatchType.DYNAMIC); + } else { + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.VERTEX_FORMAT; + options.center = position.getValue(Iso8601.MINIMUM_VALUE, options.center); + options.semiMajorAxis = semiMajorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMajorAxis); + options.semiMinorAxis = semiMinorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMinorAxis); + options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE, options.rotation) : undefined; + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE, options.height) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE, options.extrudedHeight) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE, options.granularity) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE, options.stRotation) : undefined; + setGeometryType(this, isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL); + } + }; + + return EllipseGeometryUpdater; +}); \ No newline at end of file diff --git a/Source/DynamicScene/GeometryBatchType.js b/Source/DynamicScene/GeometryBatchType.js new file mode 100644 index 000000000000..b7ea8cfbf9d1 --- /dev/null +++ b/Source/DynamicScene/GeometryBatchType.js @@ -0,0 +1,13 @@ +/*global define*/ +define(['../Core/Enumeration'], function(Enumeration) { + "use strict"; + + var GeometryBatchType = { + COLOR : new Enumeration(0, 'COLOR'), + MATERIAL : new Enumeration(1, 'MATERIAL'), + DYNAMIC : new Enumeration(2, 'DYNAMIC'), + NONE : new Enumeration(3, 'NONE') + }; + + return GeometryBatchType; +}); diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js new file mode 100644 index 000000000000..24e8b1af0e80 --- /dev/null +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -0,0 +1,257 @@ +/*global define*/ +define(['../Core/defined', + '../Core/DeveloperError', + '../Core/destroyObject', + '../Core/Map', + '../Scene/PerInstanceColorAppearance', + '../Scene/PolylineColorAppearance', + '../Scene/MaterialAppearance', + '../Scene/PolylineMaterialAppearance', + //'./DynamicGeometryBatch', + './DynamicObjectCollection', + './GeometryBatchType', + './StaticGeometryColorBatch'//, + //'./StaticGeometryPerMaterialBatch', + //'./StaticOutlineGeometryBatch' + ], function( + defined, + DeveloperError, + destroyObject, + Map, + PerInstanceColorAppearance, + PolylineColorAppearance, + MaterialAppearance, + PolylineMaterialAppearance, + //DynamicGeometryBatch, + DynamicObjectCollection, + GeometryBatchType, + StaticGeometryColorBatch) {//, + //StaticGeometryPerMaterialBatch, + //StaticOutlineGeometryBatch) { + "use strict"; + + var emptyArray = []; + + /** + * A DynamicObject visualizer which maps the DynamicPolygon instance + * in DynamicObject.polygon to a Polygon primitive. + * @alias GeometryVisualizer + * @constructor + * + * @param {Scene} scene The scene the primitives will be rendered in. + * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. + * + * @exception {DeveloperError} scene is required. + * + * @see DynamicPolygon + * @see Scene + * @see DynamicObject + * @see DynamicObjectCollection + * @see CompositeDynamicObjectCollection + * @see VisualizerCollection + * @see DynamicBillboardVisualizer + * @see DynamicConeVisualizer + * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicLabelVisualizer + * @see DynamicPointVisualizer + * @see DynamicPolylineVisualizer + * @see DynamicPyramidVisualizer + */ + var GeometryVisualizer = function(type, scene, dynamicObjectCollection) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + + this._type = type; + + var primitives = scene.getPrimitives(); + this._scene = scene; + this._primitives = primitives; + this._dynamicObjectCollection = undefined; + this._addedObjects = new DynamicObjectCollection(); + this._removedObjects = new DynamicObjectCollection(); + + //this._outlineBatch = new StaticOutlineGeometryBatch(primitives); + + this._batches = []; + this._batches[GeometryBatchType.COLOR.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType); + //this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); + //this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); + + this._updaters = new Map(); + this.setDynamicObjectCollection(dynamicObjectCollection); + }; + + /** + * Returns the scene being used by this visualizer. + * + * @returns {Scene} The scene being used by this visualizer. + */ + GeometryVisualizer.prototype.getScene = function() { + return this._scene; + }; + + /** + * Gets the DynamicObjectCollection being visualized. + * + * @returns {DynamicObjectCollection} The DynamicObjectCollection being visualized. + */ + GeometryVisualizer.prototype.getDynamicObjectCollection = function() { + return this._dynamicObjectCollection; + }; + + /** + * Sets the DynamicObjectCollection to visualize. + * + * @param dynamicObjectCollection The DynamicObjectCollection to visualizer. + */ + GeometryVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { + var oldCollection = this._dynamicObjectCollection; + if (oldCollection !== dynamicObjectCollection) { + if (defined(oldCollection)) { + oldCollection.collectionChanged.removeEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); + this.removeAllPrimitives(); + } + this._dynamicObjectCollection = dynamicObjectCollection; + if (defined(dynamicObjectCollection)) { + dynamicObjectCollection.collectionChanged.addEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); + //Add all existing items to the collection. + this._onCollectionChanged(dynamicObjectCollection, dynamicObjectCollection.getObjects(), emptyArray); + } + } + }; + + /** + * Updates all of the primitives created by this visualizer to match their + * DynamicObject counterpart at the given time. + * + * @param {JulianDate} time The time to update to. + * + * @exception {DeveloperError} time is required. + */ + GeometryVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is requied.'); + } + + var addedObjects = this._addedObjects; + var added = addedObjects.getObjects(); + var removedObjects = this._removedObjects; + var removed = removedObjects.getObjects(); + + var i; + var g; + var dynamicObject; + var id; + var updater; + var batch; + var batches = this._batches; + for (i = removed.length - 1; i > -1; i--) { + dynamicObject = removed[i]; + id = dynamicObject.id; + updater = this._updaters.get(id); + batch = batches[updater.geometryType.value]; + if (defined(batch)) { + batch.remove(updater); + } + + updater.destroy(); + this._updaters.remove(id); + } + + for (i = added.length - 1; i > -1; i--) { + dynamicObject = added[i]; + id = dynamicObject.id; + updater = new this._type(dynamicObject); + this._updaters.set(id, updater); + batch = batches[updater.geometryType.value]; + if (defined(batch)) { + batch.add(time, updater); + } + } + + addedObjects.removeAll(); + removedObjects.removeAll(); + + for (g = 0; g < batches.length; g++) { + batches[g].update(time); + } + }; + + /** + * Removes all primitives from the scene. + */ + GeometryVisualizer.prototype.removeAllPrimitives = function() { + this._addedObjects.removeAll(); + this._removedObjects.removeAll(); + + var batches = this._batches; + var batchesLength = batches.length; + for (var g = 0; g < batchesLength; g++) { + batches[g].removeAllPrimitives(); + } + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @memberof GeometryVisualizer + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see GeometryVisualizer#destroy + */ + GeometryVisualizer.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @memberof GeometryVisualizer + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see GeometryVisualizer#isDestroyed + * + * @example + * visualizer = visualizer && visualizer.destroy(); + */ + GeometryVisualizer.prototype.destroy = function() { + this.removeAllPrimitives(); + return destroyObject(this); + }; + + GeometryVisualizer.prototype._onCollectionChanged = function(dynamicObjectCollection, added, removed) { + var addedObjects = this._addedObjects; + var removedObjects = this._removedObjects; + + var i; + var dynamicObject; + for (i = removed.length - 1; i > -1; i--) { + dynamicObject = removed[i]; + if (!addedObjects.remove(dynamicObject)) { + removedObjects.add(dynamicObject); + } + } + + for (i = added.length - 1; i > -1; i--) { + dynamicObject = added[i]; + if (!removedObjects.remove(dynamicObject)) { + addedObjects.add(dynamicObject); + } + } + }; + + return GeometryVisualizer; +}); diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js new file mode 100644 index 000000000000..7fe0fb72f6d9 --- /dev/null +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -0,0 +1,205 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', + '../Core/Map', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/Primitive' + ], function( + Color, + ColorGeometryInstanceAttribute, + defined, + Map, + ShowGeometryInstanceAttribute, + Primitive) { + "use strict"; + + var AttributeCache = function() { + this.attributes = undefined; + this.showProperty = undefined; + this.colorProperty = undefined; + this.colorValue = Color.clone(Color.WHITE); + }; + + var Batch = function(primitives, translucent, appearanceType) { + this.translucent = translucent; + this.appearanceType = appearanceType; + this.primitives = primitives; + this.createPrimitive = false; + this.primitive = undefined; + this.geometry = new Map(); + this.updaters = new Map(); + this.attributes = new Map(); + this.itemsToRemove = []; + }; + + Batch.prototype.add = function(updater, instance) { + var id = updater.id; + this.createPrimitive = true; + this.geometry.set(id, instance); + this.updaters.set(id, updater); + }; + + Batch.prototype.remove = function(updater) { + var id = updater.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + this.updaters.remove(id); + }; + + Batch.prototype.update = function(time) { + var removedCount = 0; + var primitive = this.primitive; + var primitives = this.primitives; + var geometry = this.geometry.getValues(); + if (this.createPrimitive) { + this.attributes.removeAll(); + if (defined(primitive)) { + primitives.remove(primitive); + } + if (geometry.length > 0) { + primitive = new Primitive({ + asynchronous : false, + geometryInstances : geometry, + appearance : new this.appearanceType({ + translucent : this.translucent, + closed : true + }) + }); + + primitives.add(primitive); + } + this.primitive = primitive; + this.createPrimitive = false; + } else { + var updaters = this.updaters.getValues(); + var length = geometry.length; + for (var i = 0; i < length; i++) { + var instance = geometry[i]; + var updater = updaters[i]; + + //TODO PERFORMANCE We currently iterate over all geometry instances. + //We only need to iterate over attributes with time-dynamic values. + var cache = this.attributes.get(instance.id.id); + var attributes; + var colorProperty; + var showProperty; + if (!defined(cache)) { + cache = new AttributeCache(); + attributes = primitive.getGeometryInstanceAttributes(instance.id); + cache.attributes = attributes; + + colorProperty = defined(updater.material) ? updater.material.color : undefined; + if (defined(colorProperty) && colorProperty.isConstant) { + attributes.color = ColorGeometryInstanceAttribute.toValue(colorProperty.getValue(time), attributes.color); + } else { + cache.colorProperty = colorProperty; + } + + showProperty = updater.show; + if (defined(showProperty) && showProperty.isConstant) { + attributes.show = ShowGeometryInstanceAttribute.toValue(showProperty.getValue(time), attributes.show); + } else { + cache.showProperty = showProperty; + } + + this.attributes.set(instance.id.id, cache); + } + + attributes = cache.attributes; + colorProperty = cache.colorProperty; + if (defined(colorProperty)) { + var colorValue = colorProperty.getValue(time, cache.colorValue); + if (defined(colorValue)) { + attributes.color = ColorGeometryInstanceAttribute.toValue(colorValue, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; + } + } + } + showProperty = updater.showProperty; + if (defined(showProperty)) { + var showValue = showProperty.getValue(time); + if (defined(showValue)) { + attributes.show = ShowGeometryInstanceAttribute.toValue(showValue, attributes.show); + } + } + } + } + this.itemsToRemove.length = removedCount; + }; + + Batch.prototype.removeAllPrimitives = function() { + var primitive = this.primitive; + if (defined(primitive)) { + this.primitives.remove(primitive); + this.primitive = undefined; + this.geometry.removeAll(); + this.updaters.removeAll(); + } + }; + + var StaticGeometryColorBatch = function(primitives, appearanceType) { + this._solidBatch = new Batch(primitives, false, appearanceType); + this._translucentBatch = new Batch(primitives, true, appearanceType); + }; + + StaticGeometryColorBatch.prototype.add = function(time, updater) { + var instance = updater.createGeometryInstance(time); + if (!defined(instance.attributes.color) || instance.attributes.color.value[3] === 255) { + this._solidBatch.add(updater, instance); + } else { + this._translucentBatch.add(updater, instance); + } + }; + + StaticGeometryColorBatch.prototype.remove = function(updater) { + if (!this._solidBatch.remove(updater)) { + this._translucentBatch.remove(updater); + } + }; + + StaticGeometryColorBatch.prototype.update = function(time) { + var i; + var updater; + + //Perform initial update + this._solidBatch.update(time); + this._translucentBatch.update(time); + + //If any items swapped between solid/translucent, we need to + //move them between batches + var itemsToRemove = this._solidBatch.itemsToRemove; + var solidsToMoveLength = itemsToRemove.length; + if (solidsToMoveLength > 0) { + for (i = 0; i < solidsToMoveLength; i++) { + updater = itemsToRemove[i]; + this._solidBatch.remove(updater); + this._translucentBatch.add(updater, updater.createGeometryInstance(time)); + } + } + + itemsToRemove = this._translucentBatch.itemsToRemove; + var translucentToMoveLength = itemsToRemove.length; + var removedTranslucentLength = itemsToRemove.length; + if (translucentToMoveLength > 0) { + for (i = 0; i < translucentToMoveLength; i++) { + updater = itemsToRemove[i]; + this._translucentBatch.remove(updater); + this._solidBatch.add(updater, updater.createGeometryInstance(time)); + } + } + + //If we moved anything around, we need to re-build the primitive + if (translucentToMoveLength > 0 || removedTranslucentLength > 0) { + this._solidBatch.update(time); + this._translucentBatch.update(time); + } + }; + + StaticGeometryColorBatch.prototype.removeAllPrimitives = function() { + this._solidBatch.removeAllPrimitives(); + this._translucentBatch.removeAllPrimitives(); + }; + + return StaticGeometryColorBatch; +}); diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js new file mode 100644 index 000000000000..8c0a16697ba0 --- /dev/null +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -0,0 +1,130 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/EllipseGeometryUpdater', + 'DynamicScene/DynamicObject', + 'DynamicScene/DynamicEllipse', + 'Core/Cartesian3', + 'Core/Color', + 'Core/JulianDate', + 'DynamicScene/ConstantProperty', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/GeometryBatchType', + 'DynamicScene/GridMaterialProperty', + 'DynamicScene/SampledProperty', + 'DynamicScene/SampledPositionProperty' + ], function( + EllipseGeometryUpdater, + DynamicObject, + DynamicEllipse, + Cartesian3, + Color, + JulianDate, + ConstantProperty, + ConstantPositionProperty, + GeometryBatchType, + GridMaterialProperty, + SampledProperty, + SampledPositionProperty) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('GeometryBatchType is always set correctly', function() { + //Undefined position && ellipse + var dynamicObject = new DynamicObject(); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.NONE); + + //Undefined ellipse + dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.NONE); + + //Undefined ellipse.semiMajorAxis && ellipse.semiMinorAxis + var ellipse = new DynamicEllipse(); + dynamicObject.ellipse = ellipse; + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.NONE); + + //Undefined ellipse.semiMinorAxis + ellipse.semiMajorAxis = new ConstantProperty(1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.NONE); + + //Undefined ellipse.semiMajorAxis + ellipse.semiMajorAxis = undefined; + ellipse.semiMinorAxis = new ConstantProperty(2); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.NONE); + + //Default color + ellipse.semiMajorAxis = new ConstantProperty(1); + ellipse.semiMinorAxis = new ConstantProperty(2); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.COLOR); + + //Non-color material + ellipse.material = new GridMaterialProperty(); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.MATERIAL); + + //Dynamic position + dynamicObject.position = new SampledPositionProperty(); + dynamicObject.position.addSample(new JulianDate(), new Cartesian3()); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic semiMinorAxis + dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); + ellipse.semiMinorAxis = new SampledProperty(Number); + ellipse.semiMinorAxis.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic semiMajorAxis + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.semiMajorAxis = new SampledProperty(Number); + ellipse.semiMajorAxis.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic rotation + ellipse.semiMajorAxis = new ConstantProperty(1); + ellipse.rotation = new SampledProperty(Number); + ellipse.rotation.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic height + ellipse.rotation = new ConstantProperty(1); + ellipse.height = new SampledProperty(Number); + ellipse.height.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic extrudedHeight + ellipse.height = new ConstantProperty(1); + ellipse.extrudedHeight = new SampledProperty(Number); + ellipse.extrudedHeight.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic granularity + ellipse.extrudedHeight = new ConstantProperty(1); + ellipse.granularity = new SampledProperty(Number); + ellipse.granularity.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + + //Dynamic stRotation + ellipse.granularity = new ConstantProperty(1); + ellipse.stRotation = new SampledProperty(Number); + ellipse.stRotation.addSample(new JulianDate(), 1); + updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + }); + + it('Throws if DynamicObject supplied', function() { + expect(function() { + return new EllipseGeometryUpdater(); + }).toThrow(); + }); +}); \ No newline at end of file From 3ff84899a586529959c780a422c51b61acdac7d5 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 30 Jan 2014 17:43:53 -0500 Subject: [PATCH 13/81] Ellipse outline support I also removed `outlineWidth` from various geometry options since it doesn't work on ANGLE devices and has batching limitations. Still needs a lot of cleanup. --- Source/DynamicScene/CzmlDataSource.js | 3 - Source/DynamicScene/DynamicEllipse.js | 9 - Source/DynamicScene/DynamicEllipsoid.js | 9 - Source/DynamicScene/DynamicPolygon.js | 9 - Source/DynamicScene/EllipseGeometryUpdater.js | 215 +++++++++++------- Source/DynamicScene/GeometryVisualizer.js | 16 +- .../StaticOutlineGeometryBatch.js | 212 +++++++++++++++++ 7 files changed, 350 insertions(+), 123 deletions(-) create mode 100644 Source/DynamicScene/StaticOutlineGeometryBatch.js diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 2502d29c1c3e..a7da9ae88158 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -1024,7 +1024,6 @@ define(['../Core/Cartesian2', processPacketData(Boolean, ellipse, 'fill', ellipseData.fill, interval, sourceUri); processPacketData(Boolean, ellipse, 'outline', ellipseData.outline, interval, sourceUri); processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri); - processPacketData(Number, ellipse, 'outlineWidth', ellipseData.outlineWidth, interval, sourceUri); } function processEllipsoid(dynamicObject, packet, dynamicObjectCollection, sourceUri) { @@ -1049,7 +1048,6 @@ define(['../Core/Cartesian2', processPacketData(Boolean, ellipsoid, 'fill', ellipsoidData.fill, interval, sourceUri); processPacketData(Boolean, ellipsoid, 'outline', ellipsoidData.outline, interval, sourceUri); processPacketData(Color, ellipsoid, 'outlineColor', ellipsoidData.outlineColor, interval, sourceUri); - processPacketData(Number, ellipsoid, 'outlineWidth', ellipsoidData.outlineWidth, interval, sourceUri); } function processLabel(dynamicObject, packet, dynamicObjectCollection, sourceUri) { @@ -1156,7 +1154,6 @@ define(['../Core/Cartesian2', processPacketData(Boolean, polygon, 'fill', polygonData.fill, interval, sourceUri); processPacketData(Boolean, polygon, 'outline', polygonData.outline, interval, sourceUri); processPacketData(Color, polygon, 'outlineColor', polygonData.outlineColor, interval, sourceUri); - processPacketData(Number, polygon, 'outlineWidth', polygonData.outlineWidth, interval, sourceUri); } function processPolyline(dynamicObject, packet, dynamicObjectCollection, sourceUri) { diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index 06bd6f312537..0fac459fddb5 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -135,13 +135,6 @@ define(['../Core/Cartesian3', */ outline : createDynamicPropertyDescriptor('outline', '_outline'), - /** - * Gets or sets the Number {@link Property} specifying whether the width of the outline. - * @memberof DynamicEllipse.prototype - * @type {Property} - */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), - /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicEllipse.prototype @@ -173,7 +166,6 @@ define(['../Core/Cartesian3', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; return result; }; @@ -204,7 +196,6 @@ define(['../Core/Cartesian3', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; return DynamicEllipse; diff --git a/Source/DynamicScene/DynamicEllipsoid.js b/Source/DynamicScene/DynamicEllipsoid.js index e982f03639a9..6b68b2c3c095 100644 --- a/Source/DynamicScene/DynamicEllipsoid.js +++ b/Source/DynamicScene/DynamicEllipsoid.js @@ -74,13 +74,6 @@ define(['../Core/defaultValue', */ outline : createDynamicPropertyDescriptor('outline', '_outline'), - /** - * Gets or sets the Number {@link Property} specifying whether the width of the outline. - * @memberof DynamicEllipsoid.prototype - * @type {Property} - */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), - /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicEllipsoid.prototype @@ -107,7 +100,6 @@ define(['../Core/defaultValue', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; return result; }; @@ -132,7 +124,6 @@ define(['../Core/defaultValue', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; return DynamicEllipsoid; diff --git a/Source/DynamicScene/DynamicPolygon.js b/Source/DynamicScene/DynamicPolygon.js index adc828a98a7a..195dd7bf4bc7 100644 --- a/Source/DynamicScene/DynamicPolygon.js +++ b/Source/DynamicScene/DynamicPolygon.js @@ -103,13 +103,6 @@ define(['../Core/defaultValue', */ outline : createDynamicPropertyDescriptor('outline', '_outline'), - /** - * Gets or sets the Number {@link Property} specifying whether the width of the outline. - * @memberof DynamicPolygon.prototype - * @type {Property} - */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), - /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicPolygon.prototype @@ -138,7 +131,6 @@ define(['../Core/defaultValue', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; return result; }; @@ -166,7 +158,6 @@ define(['../Core/defaultValue', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); }; return DynamicPolygon; diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 147fdf1bdb4c..5c78ed1f98cf 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -1,45 +1,35 @@ /*global define*/ define(['../Core/Color', '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', + '../Core/EllipseGeometry', + '../Core/EllipseOutlineGeometry', '../Core/Event', - '../Core/ShowGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', '../Core/GeometryInstance', - '../Core/EllipseGeometry', '../Core/Iso8601', - '../DynamicScene/ConstantProperty', - '../DynamicScene/ConstantPositionProperty', + '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/GeometryBatchType', - '../Scene/Primitive', '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Material', - './MaterialProperty' + '../Scene/PerInstanceColorAppearance' ], function( Color, ColorGeometryInstanceAttribute, + defined, defineProperties, DeveloperError, + EllipseGeometry, + EllipseOutlineGeometry, Event, - ShowGeometryInstanceAttribute, - defaultValue, - defined, GeometryInstance, - EllipseGeometry, Iso8601, - ConstantProperty, - ConstantPositionProperty, + ShowGeometryInstanceAttribute, ColorMaterialProperty, GeometryBatchType, - Primitive, MaterialAppearance, - PerInstanceColorAppearance, - Material, - MaterialProperty) { + PerInstanceColorAppearance) { "use strict"; var GeometryOptions = function(dynamicObject) { @@ -67,8 +57,11 @@ define(['../Core/Color', this._ellipseSubscription = undefined; this._geometryType = GeometryBatchType.NONE; this._geometryChanged = new Event(); - this._geometryInstance = undefined; this._options = new GeometryOptions(dynamicObject); + this._hasOutline = false; + this._showOutline = undefined; + this._outlineColor = undefined; + this._outlineGeometryChanged = new Event(); this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); }; @@ -78,38 +71,42 @@ define(['../Core/Color', EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { var attributes; - if (!defined(this._geometryInstance)) { - if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), - color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) - }; - } - - this._geometryInstance = new GeometryInstance({ - id : this._dynamicObject, - geometry : new EllipseGeometry(this._options), - attributes : attributes - }); - } else { - attributes = this._geometryInstance.attributes; - if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), - color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) - }; - } + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), + color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) + }; } - return this._geometryInstance; + return new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseGeometry(this._options), + attributes : attributes + }); + }; + + EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + var attributes; + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._showOutline) ? this._showOutline.getValue(time) : true), + color : ColorGeometryInstanceAttribute.fromColor(defined(this._outlineColor) ? this._outlineColor.getValue(time) : Color.BLACK) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(defined(this._showOutline) ? this._showOutline.getValue(time) : true) + }; + } + + return new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseOutlineGeometry(this._options), + attributes : attributes + }); }; defineProperties(EllipseGeometryUpdater.prototype, { @@ -137,15 +134,29 @@ define(['../Core/Color', get : function() { return this._material; } + }, + hasOutline : { + get : function() { + return this._hasOutline; + } + }, + showOutline : { + get : function() { + return this._showOutline; + } + }, + outlineColor : { + get : function() { + return this._outlineColor; + } + }, + outlineGeometryChanged : { + get : function() { + return this._outlineGeometryChanged; + } } }); - function setGeometryType(that, geometryType) { - that._geometryType = geometryType; - that._geometryInstance = undefined; - that._geometryChanged.raiseEvent(); - } - EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { if (propertyName === 'ellipse') { if (defined(oldValue)) { @@ -170,55 +181,69 @@ define(['../Core/Color', EllipseGeometryUpdater.prototype._update = function() { var ellipse = this._dynamicObject.ellipse; + var oldGeometryType = this._geometryType; if (!defined(ellipse)) { - setGeometryType(this, GeometryBatchType.NONE); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(); + if(this._hasOutline){ + this._hasOutline = false; + this._outlineGeometryChanged.raiseEvent(); + } return; } - var createInstance = false; - var dynamicOptions = {}; - var options = this._options; - + var fillOff = false; var fill = ellipse.fill; - if (defined(fill)) { - if (fill.isConstant) { - if (!fill.getValue(Iso8601.MINIMUM_VALUE)) { - setGeometryType(this, GeometryBatchType.NONE); - return; - } - } else { - dynamicOptions.fill = fill; + if (defined(fill) && fill.isConstant && !fill.getValue(Iso8601.MINIMUM_VALUE)) { + if (this._geometryType !== GeometryBatchType.NONE) { + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(); } + fillOff = true; } - var show = ellipse.show; - if (defined(show)) { - if (show.isConstant) { - if (!show.getValue(Iso8601.MINIMUM_VALUE)) { - setGeometryType(this, GeometryBatchType.NONE); - return; - } - } else { - dynamicOptions.show = fill; + var outlineOff = false; + var outline = ellipse.outline; + if (defined(outline) && outline.isConstant && !outline.getValue(Iso8601.MINIMUM_VALUE) && this._hasOutline) { + if (this._hasOutline) { + this._hasOutline = false; + this._outlineGeometryChanged.raiseEvent(); + outlineOff = true; } } - var material = ellipse.material; - var isColorMaterial = !defined(material) || material instanceof ColorMaterialProperty; - - this._material = material; - this._show = show; + if (fillOff && outlineOff) { + return; + } var position = this._dynamicObject.position; var semiMajorAxis = ellipse.semiMajorAxis; var semiMinorAxis = ellipse.semiMinorAxis; - if (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis)) { - setGeometryType(this, GeometryBatchType.NONE); + var show = ellipse.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { + if (this._geometryType !== GeometryBatchType.NONE) { + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(); + } + if (this._hasOutline) { + this._hasOutline = false; + this._outlineGeometryChanged.raiseEvent(); + } return; } + + var material = ellipse.material; + var isColorMaterial = !defined(material) || material instanceof ColorMaterialProperty; + + this._material = material; + this._show = show; + this._outlineColor = ellipse.outlineColor; + this._showOutline = ellipse.outline; + var rotation = ellipse.rotation; var height = ellipse.height; var extrudedHeight = ellipse.extrudedHeight; @@ -233,8 +258,14 @@ define(['../Core/Color', defined(extrudedHeight) && !extrudedHeight.isConstant || // defined(granularity) && !granularity.isConstant || // defined(stRotation) && !stRotation.isConstant) { - setGeometryType(this, GeometryBatchType.DYNAMIC); + this._geometryType = GeometryBatchType.DYNAMIC; + this._geometryChanged.raiseEvent(); + if (this._hasOutline) { + this._hasOutline = false; + this._outlineGeometryChanged.raiseEvent(); + } } else { + var options = this._options; options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.VERTEX_FORMAT; options.center = position.getValue(Iso8601.MINIMUM_VALUE, options.center); options.semiMajorAxis = semiMajorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMajorAxis); @@ -244,7 +275,15 @@ define(['../Core/Color', options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE, options.extrudedHeight) : undefined; options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE, options.granularity) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE, options.stRotation) : undefined; - setGeometryType(this, isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL); + + if (!fillOff) { + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryChanged.raiseEvent(); + } + if (!outlineOff) { + this._hasOutline = true; + this._outlineGeometryChanged.raiseEvent(); + } } }; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 24e8b1af0e80..c525cb3ac6e6 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -10,9 +10,9 @@ define(['../Core/defined', //'./DynamicGeometryBatch', './DynamicObjectCollection', './GeometryBatchType', - './StaticGeometryColorBatch'//, + './StaticGeometryColorBatch', //'./StaticGeometryPerMaterialBatch', - //'./StaticOutlineGeometryBatch' + './StaticOutlineGeometryBatch' ], function( defined, DeveloperError, @@ -25,9 +25,9 @@ define(['../Core/defined', //DynamicGeometryBatch, DynamicObjectCollection, GeometryBatchType, - StaticGeometryColorBatch) {//, + StaticGeometryColorBatch, //StaticGeometryPerMaterialBatch, - //StaticOutlineGeometryBatch) { + StaticOutlineGeometryBatch) { "use strict"; var emptyArray = []; @@ -71,7 +71,7 @@ define(['../Core/defined', this._addedObjects = new DynamicObjectCollection(); this._removedObjects = new DynamicObjectCollection(); - //this._outlineBatch = new StaticOutlineGeometryBatch(primitives); + this._outlineBatch = new StaticOutlineGeometryBatch(primitives); this._batches = []; this._batches[GeometryBatchType.COLOR.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType); @@ -155,6 +155,8 @@ define(['../Core/defined', batch.remove(updater); } + this._outlineBatch.remove(updater); + updater.destroy(); this._updaters.remove(id); } @@ -168,6 +170,9 @@ define(['../Core/defined', if (defined(batch)) { batch.add(time, updater); } + if (updater.hasOutline) { + this._outlineBatch.add(time, updater); + } } addedObjects.removeAll(); @@ -176,6 +181,7 @@ define(['../Core/defined', for (g = 0; g < batches.length; g++) { batches[g].update(time); } + this._outlineBatch.update(time); }; /** diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js new file mode 100644 index 000000000000..0d0dae52f78d --- /dev/null +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -0,0 +1,212 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', + '../Core/Map', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive' + ], function( + Color, + ColorGeometryInstanceAttribute, + defined, + Map, + ShowGeometryInstanceAttribute, + PerInstanceColorAppearance, + Primitive) { + "use strict"; + + var AttributeCache = function() { + this.attributes = undefined; + this.showProperty = undefined; + this.colorProperty = undefined; + this.colorValue = Color.clone(Color.WHITE); + }; + + var Batch = function(primitives, translucent, appearanceType) { + this.translucent = translucent; + this.appearanceType = appearanceType; + this.primitives = primitives; + this.createPrimitive = false; + this.primitive = undefined; + this.geometry = new Map(); + this.updaters = new Map(); + this.attributes = new Map(); + this.itemsToRemove = []; + }; + + Batch.prototype.add = function(updater, instance) { + var id = updater.id; + this.createPrimitive = true; + this.geometry.set(id, instance); + this.updaters.set(id, updater); + }; + + Batch.prototype.remove = function(updater) { + var id = updater.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + this.updaters.remove(id); + }; + + Batch.prototype.update = function(time) { + var removedCount = 0; + var primitive = this.primitive; + var primitives = this.primitives; + var geometry = this.geometry.getValues(); + if (this.createPrimitive) { + this.attributes.removeAll(); + if (defined(primitive)) { + primitives.remove(primitive); + } + if (geometry.length > 0) { + primitive = new Primitive({ + asynchronous : false, + geometryInstances : geometry, + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : this.translucent, + renderState : { + depthTest : { + enabled : true + } + } + }) + }); + + primitives.add(primitive); + } + this.primitive = primitive; + this.createPrimitive = false; + } else { + var updaters = this.updaters.getValues(); + var length = geometry.length; + for (var i = 0; i < length; i++) { + var instance = geometry[i]; + var updater = updaters[i]; + + //TODO PERFORMANCE We currently iterate over all geometry instances. + //We only need to iterate over attributes with time-dynamic values. + var cache = this.attributes.get(instance.id.id); + var attributes; + var colorProperty; + var showProperty; + if (!defined(cache)) { + cache = new AttributeCache(); + attributes = primitive.getGeometryInstanceAttributes(instance.id); + cache.attributes = attributes; + + colorProperty = updater.outlineColor; + if (defined(colorProperty) && colorProperty.isConstant) { + attributes.color = ColorGeometryInstanceAttribute.toValue(colorProperty.getValue(time), attributes.color); + } else { + cache.colorProperty = colorProperty; + } + + showProperty = updater.show; + if (defined(showProperty) && showProperty.isConstant) { + attributes.show = ShowGeometryInstanceAttribute.toValue(showProperty.getValue(time), attributes.show); + } else { + cache.showProperty = showProperty; + } + + this.attributes.set(instance.id.id, cache); + } + + attributes = cache.attributes; + colorProperty = cache.colorProperty; + if (defined(colorProperty)) { + var colorValue = colorProperty.getValue(time, cache.colorValue); + if (defined(colorValue)) { + attributes.color = ColorGeometryInstanceAttribute.toValue(colorValue, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; + } + } + } + showProperty = updater.showProperty; + if (defined(showProperty)) { + var showValue = showProperty.getValue(time); + if (defined(showValue)) { + attributes.show = ShowGeometryInstanceAttribute.toValue(showValue, attributes.show); + } + } + } + } + this.itemsToRemove.length = removedCount; + }; + + Batch.prototype.removeAllPrimitives = function() { + var primitive = this.primitive; + if (defined(primitive)) { + this.primitives.remove(primitive); + this.primitive = undefined; + this.geometry.removeAll(); + this.updaters.removeAll(); + } + }; + + var StaticOutlineGeometryBatch = function(primitives, appearanceType) { + this._solidBatch = new Batch(primitives, false, appearanceType); + this._translucentBatch = new Batch(primitives, true, appearanceType); + }; + + StaticOutlineGeometryBatch.prototype.add = function(time, updater) { + var instance = updater.createOutlineGeometryInstance(time); + if (!defined(instance.attributes.color) || instance.attributes.color.value[3] === 255) { + this._solidBatch.add(updater, instance); + } else { + this._translucentBatch.add(updater, instance); + } + }; + + StaticOutlineGeometryBatch.prototype.remove = function(updater) { + if (!this._solidBatch.remove(updater)) { + this._translucentBatch.remove(updater); + } + }; + + StaticOutlineGeometryBatch.prototype.update = function(time) { + var i; + var updater; + + //Perform initial update + this._solidBatch.update(time); + this._translucentBatch.update(time); + + //If any items swapped between solid/translucent, we need to + //move them between batches + var itemsToRemove = this._solidBatch.itemsToRemove; + var solidsToMoveLength = itemsToRemove.length; + if (solidsToMoveLength > 0) { + for (i = 0; i < solidsToMoveLength; i++) { + updater = itemsToRemove[i]; + this._solidBatch.remove(updater); + this._translucentBatch.add(updater, updater.createOutlineGeometryInstance(time)); + } + } + + itemsToRemove = this._translucentBatch.itemsToRemove; + var translucentToMoveLength = itemsToRemove.length; + var removedTranslucentLength = itemsToRemove.length; + if (translucentToMoveLength > 0) { + for (i = 0; i < translucentToMoveLength; i++) { + updater = itemsToRemove[i]; + this._translucentBatch.remove(updater); + this._solidBatch.add(updater, updater.createOutlineGeometryInstance(time)); + } + } + + //If we moved anything around, we need to re-build the primitive + if (translucentToMoveLength > 0 || removedTranslucentLength > 0) { + this._solidBatch.update(time); + this._translucentBatch.update(time); + } + }; + + StaticOutlineGeometryBatch.prototype.removeAllPrimitives = function() { + this._solidBatch.removeAllPrimitives(); + this._translucentBatch.removeAllPrimitives(); + }; + + return StaticOutlineGeometryBatch; +}); From cfc5f442b21e14fd1585ae418d3b3e176600f81f Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 31 Jan 2014 15:17:24 -0500 Subject: [PATCH 14/81] Ongoing geometry work 1. Rename a bunch of variables to make the code easier to follow 2. Avoids iterating over all attributes every frame by keeping a separate map of time-dynamic updaters. --- Source/DynamicScene/ColorMaterialProperty.js | 4 +- Source/DynamicScene/EllipseGeometryUpdater.js | 208 +++++++++--------- Source/DynamicScene/GeometryVisualizer.js | 4 +- .../DynamicScene/StaticGeometryColorBatch.js | 78 ++----- .../StaticOutlineGeometryBatch.js | 78 ++----- 5 files changed, 151 insertions(+), 221 deletions(-) diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index adca27bc069f..1f385cd6f972 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -19,9 +19,9 @@ define(['../Core/Color', * @alias ColorMaterialProperty * @constructor */ - var ColorMaterialProperty = function() { + var ColorMaterialProperty = function(color) { this._definitionChanged = new Event(); - this._color = undefined; + this._color = color; this._colorSubscription = undefined; this.color = new ConstantProperty(Color.WHITE); }; diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 5c78ed1f98cf..c24b0d3e1314 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -1,6 +1,7 @@ /*global define*/ define(['../Core/Color', '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', @@ -11,12 +12,14 @@ define(['../Core/Color', '../Core/Iso8601', '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', + '../DynamicScene/ConstantProperty', '../DynamicScene/GeometryBatchType', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance' ], function( Color, ColorGeometryInstanceAttribute, + defaultValue, defined, defineProperties, DeveloperError, @@ -27,11 +30,18 @@ define(['../Core/Color', Iso8601, ShowGeometryInstanceAttribute, ColorMaterialProperty, + ConstantProperty, GeometryBatchType, MaterialAppearance, PerInstanceColorAppearance) { "use strict"; + var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ColorMaterialProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var GeometryOptions = function(dynamicObject) { this.id = dynamicObject; this.vertexFormat = undefined; @@ -51,17 +61,20 @@ define(['../Core/Color', throw new DeveloperError('dynamicObject is required'); } - this._dynamicObject = dynamicObject; this._id = dynamicObject.id; + this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._ellipseSubscription = undefined; this._geometryType = GeometryBatchType.NONE; this._geometryChanged = new Event(); - this._options = new GeometryOptions(dynamicObject); - this._hasOutline = false; - this._showOutline = undefined; - this._outlineColor = undefined; + this._showProperty = undefined; + this._materialProperty = undefined; + this._isOutlined = false; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; this._outlineGeometryChanged = new Event(); + this._options = new GeometryOptions(dynamicObject); + this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); }; @@ -69,46 +82,6 @@ define(['../Core/Color', EllipseGeometryUpdater.MaterialAppearanceType = MaterialAppearance; - EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { - var attributes; - if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true), - color : ColorGeometryInstanceAttribute.fromColor(defined(this._material) && defined(this._material.color) ? this._material.color.getValue(time) : Color.WHTE) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._show) ? this._show.getValue(time) : true) - }; - } - - return new GeometryInstance({ - id : this._dynamicObject, - geometry : new EllipseGeometry(this._options), - attributes : attributes - }); - }; - - EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - var attributes; - if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._showOutline) ? this._showOutline.getValue(time) : true), - color : ColorGeometryInstanceAttribute.fromColor(defined(this._outlineColor) ? this._outlineColor.getValue(time) : Color.BLACK) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(defined(this._showOutline) ? this._showOutline.getValue(time) : true) - }; - } - - return new GeometryInstance({ - id : this._dynamicObject, - geometry : new EllipseOutlineGeometry(this._options), - attributes : attributes - }); - }; - defineProperties(EllipseGeometryUpdater.prototype, { id : { get : function() { @@ -125,29 +98,29 @@ define(['../Core/Color', return this._geometryChanged; } }, - show : { + showProperty : { get : function() { - return this._show; + return this._showProperty; } }, - material : { + materialProperty : { get : function() { - return this._material; + return this._materialProperty; } }, - hasOutline : { + isOutlined : { get : function() { - return this._hasOutline; + return this._isOutlined; } }, - showOutline : { + showOutlineProperty : { get : function() { - return this._showOutline; + return this._showOutlineProperty; } }, - outlineColor : { + outlineColorProperty : { get : function() { - return this._outlineColor; + return this._outlineColorProperty; } }, outlineGeometryChanged : { @@ -157,6 +130,46 @@ define(['../Core/Color', } }); + EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { + var attributes; + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(this._showProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(defined(this._materialProperty.color) ? this._materialProperty.color.getValue(time) : Color.WHTE) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(this._showProperty.getValue(time)) + }; + } + + return new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseGeometry(this._options), + attributes : attributes + }); + }; + + EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + var attributes; + if (this._geometryType === GeometryBatchType.COLOR) { + attributes = { + show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(this._outlineColorProperty.getValue(time)) + }; + } else if (this._geometryType === GeometryBatchType.MATERIAL) { + attributes = { + show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)) + }; + } + + return new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseOutlineGeometry(this._options), + attributes : attributes + }); + }; + EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { if (propertyName === 'ellipse') { if (defined(oldValue)) { @@ -166,54 +179,41 @@ define(['../Core/Color', this._ellipse = newValue; if (defined(newValue)) { - this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); + this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._update, this); } - this._onEllipsePropertyChanged(); + this._update(); } else if (propertyName === 'position') { this._update(); } }; - EllipseGeometryUpdater.prototype._onEllipsePropertyChanged = function(ellipse, propertyName, newValue, oldValue) { - this._update(); - }; - EllipseGeometryUpdater.prototype._update = function() { var ellipse = this._dynamicObject.ellipse; var oldGeometryType = this._geometryType; if (!defined(ellipse)) { - this._geometryType = GeometryBatchType.NONE; - this._geometryChanged.raiseEvent(); - if(this._hasOutline){ - this._hasOutline = false; - this._outlineGeometryChanged.raiseEvent(); - } - return; - } - - var fillOff = false; - var fill = ellipse.fill; - if (defined(fill) && fill.isConstant && !fill.getValue(Iso8601.MINIMUM_VALUE)) { if (this._geometryType !== GeometryBatchType.NONE) { this._geometryType = GeometryBatchType.NONE; - this._geometryChanged.raiseEvent(); + this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); + } + if(this._isOutlined){ + this._isOutlined = false; + this._outlineGeometryChanged.raiseEvent(this._isOutlined); } - fillOff = true; + return; } - var outlineOff = false; - var outline = ellipse.outline; - if (defined(outline) && outline.isConstant && !outline.getValue(Iso8601.MINIMUM_VALUE) && this._hasOutline) { - if (this._hasOutline) { - this._hasOutline = false; - this._outlineGeometryChanged.raiseEvent(); - outlineOff = true; - } + var fillProperty = ellipse.fill; + var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = ellipse.outline; + var isOutlined = defined(outlineProperty); + if (isOutlined && outlineProperty.isConstant) { + isOutlined = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - if (fillOff && outlineOff) { + if (!isFilled && !isOutlined) { return; } @@ -226,23 +226,21 @@ define(['../Core/Color', (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { if (this._geometryType !== GeometryBatchType.NONE) { this._geometryType = GeometryBatchType.NONE; - this._geometryChanged.raiseEvent(); + this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } - if (this._hasOutline) { - this._hasOutline = false; - this._outlineGeometryChanged.raiseEvent(); + if (this._isOutlined) { + this._isOutlined = false; + this._outlineGeometryChanged.raiseEvent(this._isOutlined); } return; } - - var material = ellipse.material; - var isColorMaterial = !defined(material) || material instanceof ColorMaterialProperty; - - this._material = material; - this._show = show; - this._outlineColor = ellipse.outlineColor; - this._showOutline = ellipse.outline; + var material = defaultValue(ellipse.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); + this._outlineColorProperty = defaultValue(ellipse.outlineColor, defaultOutlineColor); var rotation = ellipse.rotation; var height = ellipse.height; @@ -258,11 +256,9 @@ define(['../Core/Color', defined(extrudedHeight) && !extrudedHeight.isConstant || // defined(granularity) && !granularity.isConstant || // defined(stRotation) && !stRotation.isConstant) { - this._geometryType = GeometryBatchType.DYNAMIC; - this._geometryChanged.raiseEvent(); - if (this._hasOutline) { - this._hasOutline = false; - this._outlineGeometryChanged.raiseEvent(); + if (this._geometryType !== GeometryBatchType.DYNAMIC) { + this._geometryType = GeometryBatchType.DYNAMIC; + this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } } else { var options = this._options; @@ -276,13 +272,13 @@ define(['../Core/Color', options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE, options.granularity) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE, options.stRotation) : undefined; - if (!fillOff) { + if (isFilled) { this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; - this._geometryChanged.raiseEvent(); + this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } - if (!outlineOff) { - this._hasOutline = true; - this._outlineGeometryChanged.raiseEvent(); + if (isOutlined) { + this._isOutlined = true; + this._outlineGeometryChanged.raiseEvent(this._isOutlined); } } }; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index c525cb3ac6e6..b3c802730387 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -166,11 +166,13 @@ define(['../Core/defined', id = dynamicObject.id; updater = new this._type(dynamicObject); this._updaters.set(id, updater); + batch = batches[updater.geometryType.value]; if (defined(batch)) { batch.add(time, updater); } - if (updater.hasOutline) { + + if (updater.isOutlined) { this._outlineBatch.add(time, updater); } } diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 7fe0fb72f6d9..8c32219b24f4 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -14,13 +14,6 @@ define(['../Core/Color', Primitive) { "use strict"; - var AttributeCache = function() { - this.attributes = undefined; - this.showProperty = undefined; - this.colorProperty = undefined; - this.colorValue = Color.clone(Color.WHITE); - }; - var Batch = function(primitives, translucent, appearanceType) { this.translucent = translucent; this.appearanceType = appearanceType; @@ -29,6 +22,7 @@ define(['../Core/Color', this.primitive = undefined; this.geometry = new Map(); this.updaters = new Map(); + this.updatersWithAttributes = new Map(); this.attributes = new Map(); this.itemsToRemove = []; }; @@ -38,24 +32,29 @@ define(['../Core/Color', this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); + if (!updater.showProperty.isConstant || !updater.materialProperty.isConstant) { + this.updatersWithAttributes.set(id, updater); + } }; Batch.prototype.remove = function(updater) { var id = updater.id; this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; this.updaters.remove(id); + this.updatersWithAttributes.remove(id); }; + var colorScratch = new Color(); Batch.prototype.update = function(time) { var removedCount = 0; var primitive = this.primitive; var primitives = this.primitives; - var geometry = this.geometry.getValues(); if (this.createPrimitive) { this.attributes.removeAll(); if (defined(primitive)) { primitives.remove(primitive); } + var geometry = this.geometry.getValues(); if (geometry.length > 0) { primitive = new Primitive({ asynchronous : false, @@ -71,58 +70,25 @@ define(['../Core/Color', this.primitive = primitive; this.createPrimitive = false; } else { - var updaters = this.updaters.getValues(); - var length = geometry.length; + var updatersWithAttributes = this.updatersWithAttributes.getValues(); + var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { - var instance = geometry[i]; - var updater = updaters[i]; - - //TODO PERFORMANCE We currently iterate over all geometry instances. - //We only need to iterate over attributes with time-dynamic values. - var cache = this.attributes.get(instance.id.id); - var attributes; - var colorProperty; - var showProperty; - if (!defined(cache)) { - cache = new AttributeCache(); + var updater = updatersWithAttributes[i]; + var instance = this.geometry.get(updater.id); + + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { attributes = primitive.getGeometryInstanceAttributes(instance.id); - cache.attributes = attributes; - - colorProperty = defined(updater.material) ? updater.material.color : undefined; - if (defined(colorProperty) && colorProperty.isConstant) { - attributes.color = ColorGeometryInstanceAttribute.toValue(colorProperty.getValue(time), attributes.color); - } else { - cache.colorProperty = colorProperty; - } - - showProperty = updater.show; - if (defined(showProperty) && showProperty.isConstant) { - attributes.show = ShowGeometryInstanceAttribute.toValue(showProperty.getValue(time), attributes.show); - } else { - cache.showProperty = showProperty; - } - - this.attributes.set(instance.id.id, cache); + this.attributes.set(instance.id.id, attributes); } - attributes = cache.attributes; - colorProperty = cache.colorProperty; - if (defined(colorProperty)) { - var colorValue = colorProperty.getValue(time, cache.colorValue); - if (defined(colorValue)) { - attributes.color = ColorGeometryInstanceAttribute.toValue(colorValue, attributes.color); - if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { - this.itemsToRemove[removedCount++] = updater; - } - } - } - showProperty = updater.showProperty; - if (defined(showProperty)) { - var showValue = showProperty.getValue(time); - if (defined(showValue)) { - attributes.show = ShowGeometryInstanceAttribute.toValue(showValue, attributes.show); - } + var colorProperty = updater.materialProperty.color; + colorProperty.getValue(time, colorScratch); + attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; } + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.showProperty.getValue(time), attributes.show); } } this.itemsToRemove.length = removedCount; @@ -145,7 +111,7 @@ define(['../Core/Color', StaticGeometryColorBatch.prototype.add = function(time, updater) { var instance = updater.createGeometryInstance(time); - if (!defined(instance.attributes.color) || instance.attributes.color.value[3] === 255) { + if (instance.attributes.color.value[3] === 255) { this._solidBatch.add(updater, instance); } else { this._translucentBatch.add(updater, instance); diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 0d0dae52f78d..09369e2ab0d4 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -16,13 +16,6 @@ define(['../Core/Color', Primitive) { "use strict"; - var AttributeCache = function() { - this.attributes = undefined; - this.showProperty = undefined; - this.colorProperty = undefined; - this.colorValue = Color.clone(Color.WHITE); - }; - var Batch = function(primitives, translucent, appearanceType) { this.translucent = translucent; this.appearanceType = appearanceType; @@ -31,6 +24,7 @@ define(['../Core/Color', this.primitive = undefined; this.geometry = new Map(); this.updaters = new Map(); + this.updatersWithAttributes = new Map(); this.attributes = new Map(); this.itemsToRemove = []; }; @@ -40,24 +34,29 @@ define(['../Core/Color', this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); + if (!updater.showOutlineProperty.isConstant || !updater.materialProperty.isConstant) { + this.updatersWithAttributes.set(id, updater); + } }; Batch.prototype.remove = function(updater) { var id = updater.id; this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; this.updaters.remove(id); + this.updatersWithAttributes.remove(id); }; + var colorScratch = new Color(); Batch.prototype.update = function(time) { var removedCount = 0; var primitive = this.primitive; var primitives = this.primitives; - var geometry = this.geometry.getValues(); if (this.createPrimitive) { this.attributes.removeAll(); if (defined(primitive)) { primitives.remove(primitive); } + var geometry = this.geometry.getValues(); if (geometry.length > 0) { primitive = new Primitive({ asynchronous : false, @@ -78,58 +77,25 @@ define(['../Core/Color', this.primitive = primitive; this.createPrimitive = false; } else { - var updaters = this.updaters.getValues(); - var length = geometry.length; + var updatersWithAttributes = this.updatersWithAttributes.getValues(); + var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { - var instance = geometry[i]; - var updater = updaters[i]; - - //TODO PERFORMANCE We currently iterate over all geometry instances. - //We only need to iterate over attributes with time-dynamic values. - var cache = this.attributes.get(instance.id.id); - var attributes; - var colorProperty; - var showProperty; - if (!defined(cache)) { - cache = new AttributeCache(); + var updater = updatersWithAttributes[i]; + var instance = this.geometry.get(updater.id); + + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { attributes = primitive.getGeometryInstanceAttributes(instance.id); - cache.attributes = attributes; - - colorProperty = updater.outlineColor; - if (defined(colorProperty) && colorProperty.isConstant) { - attributes.color = ColorGeometryInstanceAttribute.toValue(colorProperty.getValue(time), attributes.color); - } else { - cache.colorProperty = colorProperty; - } - - showProperty = updater.show; - if (defined(showProperty) && showProperty.isConstant) { - attributes.show = ShowGeometryInstanceAttribute.toValue(showProperty.getValue(time), attributes.show); - } else { - cache.showProperty = showProperty; - } - - this.attributes.set(instance.id.id, cache); + this.attributes.set(instance.id.id, attributes); } - attributes = cache.attributes; - colorProperty = cache.colorProperty; - if (defined(colorProperty)) { - var colorValue = colorProperty.getValue(time, cache.colorValue); - if (defined(colorValue)) { - attributes.color = ColorGeometryInstanceAttribute.toValue(colorValue, attributes.color); - if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { - this.itemsToRemove[removedCount++] = updater; - } - } - } - showProperty = updater.showProperty; - if (defined(showProperty)) { - var showValue = showProperty.getValue(time); - if (defined(showValue)) { - attributes.show = ShowGeometryInstanceAttribute.toValue(showValue, attributes.show); - } + var outlineColorProperty = updater.outlineColorProperty; + outlineColorProperty.getValue(time, colorScratch); + attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; } + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.showOutlineProperty.getValue(time), attributes.show); } } this.itemsToRemove.length = removedCount; @@ -152,7 +118,7 @@ define(['../Core/Color', StaticOutlineGeometryBatch.prototype.add = function(time, updater) { var instance = updater.createOutlineGeometryInstance(time); - if (!defined(instance.attributes.color) || instance.attributes.color.value[3] === 255) { + if (instance.attributes.color.value[3] === 255) { this._solidBatch.add(updater, instance); } else { this._translucentBatch.add(updater, instance); From 8303835a9cc988d5f3a8c216c8d029be3c749fe0 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 31 Jan 2014 16:10:27 -0500 Subject: [PATCH 15/81] Add support for geometry with materials Still needs cleanup and ability to handle changed materials. --- Source/DynamicScene/EllipseGeometryUpdater.js | 17 +- Source/DynamicScene/GeometryVisualizer.js | 6 +- .../StaticGeometryPerMaterialBatch.js | 153 ++++++++++++++++++ 3 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 Source/DynamicScene/StaticGeometryPerMaterialBatch.js diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index c24b0d3e1314..bf6b0e8893b2 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -151,22 +151,13 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - var attributes; - if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(this._outlineColorProperty.getValue(time)) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)) - }; - } - return new GeometryInstance({ id : this._dynamicObject, geometry : new EllipseOutlineGeometry(this._options), - attributes : attributes + attributes : { + show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(this._outlineColorProperty.getValue(time)) + } }); }; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index b3c802730387..1cd4ea7480d1 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -11,7 +11,7 @@ define(['../Core/defined', './DynamicObjectCollection', './GeometryBatchType', './StaticGeometryColorBatch', - //'./StaticGeometryPerMaterialBatch', + './StaticGeometryPerMaterialBatch', './StaticOutlineGeometryBatch' ], function( defined, @@ -26,7 +26,7 @@ define(['../Core/defined', DynamicObjectCollection, GeometryBatchType, StaticGeometryColorBatch, - //StaticGeometryPerMaterialBatch, + StaticGeometryPerMaterialBatch, StaticOutlineGeometryBatch) { "use strict"; @@ -75,7 +75,7 @@ define(['../Core/defined', this._batches = []; this._batches[GeometryBatchType.COLOR.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType); - //this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); + this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); //this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); this._updaters = new Map(); diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js new file mode 100644 index 000000000000..cbfcb3c5b3b2 --- /dev/null +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -0,0 +1,153 @@ +/*global define*/ +define(['../Core/defined', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/Primitive', + '../Scene/Material', + './MaterialProperty' + ], function( + defined, + ShowGeometryInstanceAttribute, + Primitive, + Material, + MaterialProperty) { + "use strict"; + + var Batch = function(primitives, appearanceType, materialProperty) { + this._materialProperty = materialProperty; + this._updaters = new Map(); + this._createPrimitive = true; + this._primitive = undefined; + this._primitives = primitives; + this._geometries = new Map(); + this._material = Material.fromType('Color'); + this._appearanceType = appearanceType; + }; + + Batch.prototype.isMaterial = function(updater) { + var material = this._materialProperty; + var updaterMaterial = updater._materialProperty; + if (updaterMaterial === material) { + return true; + } + if (defined(material)) { + return material.equals(updaterMaterial); + } + return false; + }; + + Batch.prototype.add = function(time, updater) { + this._updaters.set(updater.id, updater); + this._geometries.set(updater.id, updater.createGeometryInstance(time)); + this._createPrimitive = true; + }; + + Batch.prototype.remove = function(updater) { + this._createPrimitive = this._updaters.remove(updater.id); + this._geometries.remove(updater.id); + return this._createPrimitive; + }; + + Batch.prototype.update = function(time) { + var primitive = this._primitive; + var primitives = this._primitives; + var geometries = this._geometries.getValues(); + if (this._createPrimitive) { + if (defined(primitive)) { + primitives.remove(primitive); + } + if (geometries.length > 0) { + primitive = new Primitive({ + asynchronous : false, + geometryInstances : geometries, + appearance : new this._appearanceType({ + material : MaterialProperty.getValue(time, this._materialProperty, this._material), + faceForward : true, + translucent : this._material.isTranslucent(), + closed : true + }) + }); + + primitives.add(primitive); + } + this._primitive = primitive; + this._createPrimitive = false; + } else { + this._primitive.appearance.material = MaterialProperty.getValue(time, this._materialProperty, this._material); + + var updaters = this._updaters.getValues(); + for (var i = geometries.length - 1; i > -1; i--) { + var instance = geometries[i]; + var updater = updaters[i]; + + var attributes = updater.attributes; + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + updater.attributes = attributes; + } + var show = updater.show; + if (defined(show)) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } + } + } + }; + + Batch.prototype.destroy = function(time) { + var primitive = this._primitive; + var primitives = this._primitives; + if (defined(primitive)) { + primitives.remove(primitive); + } + }; + + var StaticGeometryPerMaterialBatch = function(primitives, appearanceType) { + this._items = []; + this._primitives = primitives; + this._appearanceType = appearanceType; + }; + + StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if (item.isMaterial(updater)) { + item.add(time, updater); + return; + } + } + var batch = new Batch(this._primitives, this._appearanceType, updater.materialProperty); + batch.add(time, updater); + items.push(batch); + }; + + StaticGeometryPerMaterialBatch.prototype.remove = function(updater) { + var items = this._items; + var length = items.length; + for (var i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.remove(updater)) { + break; + } + } + }; + + StaticGeometryPerMaterialBatch.prototype.update = function(time) { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + items[i].update(time); + } + }; + + StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + items[i].destroy(); + } + this._items = []; + }; + + return StaticGeometryPerMaterialBatch; +}); From a8a28d82ecc278c3afea101046a5e1f717200e7e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 31 Jan 2014 17:47:32 -0500 Subject: [PATCH 16/81] Add some really rough around the edges dynamic geometry support. --- Source/DynamicScene/EllipseGeometryUpdater.js | 70 ++++++++++++++++++- Source/DynamicScene/GeometryVisualizer.js | 34 ++++++++- .../StaticGeometryPerMaterialBatch.js | 2 + 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index bf6b0e8893b2..729d7200f437 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -15,7 +15,9 @@ define(['../Core/Color', '../DynamicScene/ConstantProperty', '../DynamicScene/GeometryBatchType', '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance' + '../DynamicScene/MaterialProperty', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive' ], function( Color, ColorGeometryInstanceAttribute, @@ -33,7 +35,9 @@ define(['../Core/Color', ConstantProperty, GeometryBatchType, MaterialAppearance, - PerInstanceColorAppearance) { + MaterialProperty, + PerInstanceColorAppearance, + Primitive) { "use strict"; var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); @@ -274,5 +278,67 @@ define(['../Core/Color', } }; + EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + return new DynamicGeometryBatchItem(primitives, this); + }; + + var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._geometryUpdater = geometryUpdater; + }; + + DynamicGeometryBatchItem.prototype.update = function(time) { + var geometryUpdater = this._geometryUpdater; + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); + var material = this._material; + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + + var d = geometryUpdater._dynamicObject; + var options = {}; + + var ellipse = d.ellipse; + var position = d.position; + var semiMajorAxis = ellipse.semiMajorAxis; + var semiMinorAxis = ellipse.semiMinorAxis; + var rotation = ellipse.rotation; + var height = ellipse.height; + var extrudedHeight = ellipse.extrudedHeight; + var granularity = ellipse.granularity; + var stRotation = ellipse.stRotation; + + options.vertexFormat = appearance.vertexFormat; + options.center = position.getValue(time, options.center); + options.semiMajorAxis = semiMajorAxis.getValue(time, options.semiMajorAxis); + options.semiMinorAxis = semiMinorAxis.getValue(time, options.semiMinorAxis); + options.rotation = defined(rotation) ? rotation.getValue(time, options.rotation) : undefined; + options.height = defined(height) ? height.getValue(time, options.height) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(time, options.extrudedHeight) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(time, options.granularity) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(time, options.stRotation) : undefined; + + this._primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseGeometry(options) + }), + appearance : appearance, + asynchronous : false + }); + this._primitives.add(this._primitive); + }; + + DynamicGeometryBatchItem.prototype.destroy = function() { + this._primitives.remove(this._primitive); + }; + return EllipseGeometryUpdater; }); \ No newline at end of file diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 1cd4ea7480d1..02e786a71bd1 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -7,7 +7,6 @@ define(['../Core/defined', '../Scene/PolylineColorAppearance', '../Scene/MaterialAppearance', '../Scene/PolylineMaterialAppearance', - //'./DynamicGeometryBatch', './DynamicObjectCollection', './GeometryBatchType', './StaticGeometryColorBatch', @@ -22,7 +21,6 @@ define(['../Core/defined', PolylineColorAppearance, MaterialAppearance, PolylineMaterialAppearance, - //DynamicGeometryBatch, DynamicObjectCollection, GeometryBatchType, StaticGeometryColorBatch, @@ -32,6 +30,36 @@ define(['../Core/defined', var emptyArray = []; + var DynamicGeometryBatch = function(primitives) { + this._primitives = primitives; + this._items = new Map(); + }; + + DynamicGeometryBatch.prototype.add = function(time, updater) { + this._items.set(updater.id, updater.createDynamicUpdater(this._primitives)); + }; + + DynamicGeometryBatch.prototype.remove = function(updater) { + var id = updater.id; + var primitive = this._items.get(id); + primitive.destroy(); + this._items.remove(id); + }; + + DynamicGeometryBatch.prototype.update = function(time) { + var geometries = this._items.getValues(); + for (var i = 0, len = geometries.length; i < len; i++) { + geometries[i].update(time); + } + }; + + DynamicGeometryBatch.prototype.removeAllPrimitives = function() { + var geometries = this._items.getValues(); + for (var i = 0, len = geometries.length; i < len; i++) { + geometries[i].destroy(); + } + }; + /** * A DynamicObject visualizer which maps the DynamicPolygon instance * in DynamicObject.polygon to a Polygon primitive. @@ -76,7 +104,7 @@ define(['../Core/defined', this._batches = []; this._batches[GeometryBatchType.COLOR.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType); this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); - //this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); + this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); this._updaters = new Map(); this.setDynamicObjectCollection(dynamicObjectCollection); diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index cbfcb3c5b3b2..85a0f2265dae 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -1,11 +1,13 @@ /*global define*/ define(['../Core/defined', + '../Core/Map', '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', '../Scene/Material', './MaterialProperty' ], function( defined, + Map, ShowGeometryInstanceAttribute, Primitive, Material, From a3275e48ca75f2aa6a7aa8b8356bdb5a03b59509 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 2 Feb 2014 20:09:12 -0500 Subject: [PATCH 17/81] Add iniitial support for dynamic outlines. Also fix some failing specs. --- Source/DynamicScene/EllipseGeometryUpdater.js | 32 ++++++++++++++++++- Source/DynamicScene/GeometryVisualizer.js | 14 ++++---- Specs/DynamicScene/DataSourceDisplaySpec.js | 9 ++++-- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 729d7200f437..8b1372304462 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -285,6 +285,7 @@ define(['../Core/Color', var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; + this._outlinePrimitive = undefined; this._geometryUpdater = geometryUpdater; }; @@ -292,6 +293,7 @@ define(['../Core/Color', var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { this._primitives.remove(this._primitive); + this._primitives.remove(this._outlinePrimitive); } this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); @@ -334,10 +336,38 @@ define(['../Core/Color', asynchronous : false }); this._primitives.add(this._primitive); + + if (defined(ellipse.outline) && ellipse.outline.getValue(time)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + var outlineColor = defined(ellipse.outlineColor) ? ellipse.outlineColor.getValue(time) : Color.BLACK; + this._outlinePrimitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : false, + renderState : { + depthTest : { + enabled : true + } + } + }), + asynchronous : false + }); + this._primitives.add(this._outlinePrimitive); + } }; DynamicGeometryBatchItem.prototype.destroy = function() { - this._primitives.remove(this._primitive); + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + this._primitives.add(this._outlinePrimitive); + } }; return EllipseGeometryUpdater; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 02e786a71bd1..45855f434bad 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -32,29 +32,29 @@ define(['../Core/defined', var DynamicGeometryBatch = function(primitives) { this._primitives = primitives; - this._items = new Map(); + this._dynamicUpdaters = new Map(); }; DynamicGeometryBatch.prototype.add = function(time, updater) { - this._items.set(updater.id, updater.createDynamicUpdater(this._primitives)); + this._dynamicUpdaters.set(updater.id, updater.createDynamicUpdater(this._primitives)); }; DynamicGeometryBatch.prototype.remove = function(updater) { var id = updater.id; - var primitive = this._items.get(id); - primitive.destroy(); - this._items.remove(id); + var dynamicUpdater = this._dynamicUpdaters.get(id); + dynamicUpdater.destroy(); + this._dynamicUpdaters.remove(id); }; DynamicGeometryBatch.prototype.update = function(time) { - var geometries = this._items.getValues(); + var geometries = this._dynamicUpdaters.getValues(); for (var i = 0, len = geometries.length; i < len; i++) { geometries[i].update(time); } }; DynamicGeometryBatch.prototype.removeAllPrimitives = function() { - var geometries = this._items.getValues(); + var geometries = this._dynamicUpdaters.getValues(); for (var i = 0, len = geometries.length; i < len; i++) { geometries[i].destroy(); } diff --git a/Specs/DynamicScene/DataSourceDisplaySpec.js b/Specs/DynamicScene/DataSourceDisplaySpec.js index 31cd4dade441..3aa28ea3a565 100644 --- a/Specs/DynamicScene/DataSourceDisplaySpec.js +++ b/Specs/DynamicScene/DataSourceDisplaySpec.js @@ -65,8 +65,11 @@ defineSuite([ this.destroyed = true; }; + var visualizerTypes = [function() { + return new MockVisualizer(); + }]; + it('constructor sets expected values', function() { - var visualizerTypes = [MockVisualizer]; var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); expect(display.getScene()).toBe(scene); expect(display.getVisualizerTypes()).toEqual(visualizerTypes); @@ -94,7 +97,7 @@ defineSuite([ var dynamicSource = new MockDataSource(); dynamicSource.isTimeVarying = true; - var display = new DataSourceDisplay(scene, dataSourceCollection, [MockVisualizer]); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); dataSourceCollection.add(staticSource); dataSourceCollection.add(dynamicSource); @@ -139,7 +142,7 @@ defineSuite([ var source = new MockDataSource(); dataSourceCollection.add(source); - var display = new DataSourceDisplay(scene, dataSourceCollection, [MockVisualizer]); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); var sourceVisualizer = source._visualizerCollection.getVisualizers()[0]; expect(sourceVisualizer).toBeInstanceOf(MockVisualizer); From df72363f0b2bf71e6b0aa41e2d7e71dc63f91d18 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 2 Feb 2014 21:54:23 -0500 Subject: [PATCH 18/81] Add availability checks. --- Source/DynamicScene/EllipseGeometryUpdater.js | 94 +++++++++++-------- 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 8b1372304462..5943fb20e9d8 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -40,6 +40,7 @@ define(['../Core/Color', Primitive) { "use strict"; + //TODO Fix fill for static objects var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); var defaultShow = new ConstantProperty(true); var defaultFill = new ColorMaterialProperty(true); @@ -135,32 +136,35 @@ define(['../Core/Color', }); EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { - var attributes; + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time)); if (this._geometryType === GeometryBatchType.COLOR) { - attributes = { - show : new ShowGeometryInstanceAttribute(this._showProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(defined(this._materialProperty.color) ? this._materialProperty.color.getValue(time) : Color.WHTE) - }; - } else if (this._geometryType === GeometryBatchType.MATERIAL) { - attributes = { - show : new ShowGeometryInstanceAttribute(this._showProperty.getValue(time)) - }; + var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + color = ColorGeometryInstanceAttribute.fromColor(currentColor); } - return new GeometryInstance({ - id : this._dynamicObject, + id : dynamicObject, geometry : new EllipseGeometry(this._options), - attributes : attributes + attributes : { + show : show, + color : color + } }); }; EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + return new GeometryInstance({ - id : this._dynamicObject, + id : dynamicObject, geometry : new EllipseOutlineGeometry(this._options), attributes : { - show : new ShowGeometryInstanceAttribute(this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(this._outlineColorProperty.getValue(time)) + show : new ShowGeometryInstanceAttribute(isAvailable && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) } }); }; @@ -287,28 +291,31 @@ define(['../Core/Color', this._primitive = undefined; this._outlinePrimitive = undefined; this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._dynamicObject); }; DynamicGeometryBatchItem.prototype.update = function(time) { var geometryUpdater = this._geometryUpdater; + if (defined(this._primitive)) { this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { this._primitives.remove(this._outlinePrimitive); } - this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); - var material = this._material; - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true - }); + var dynamicObject = geometryUpdater._dynamicObject; + var show = dynamicObject.show; + + if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + return; + } - var d = geometryUpdater._dynamicObject; - var options = {}; + var options = this._options; + var ellipse = dynamicObject.ellipse; - var ellipse = d.ellipse; - var position = d.position; + var position = dynamicObject.position; var semiMajorAxis = ellipse.semiMajorAxis; var semiMinorAxis = ellipse.semiMinorAxis; var rotation = ellipse.rotation; @@ -317,7 +324,6 @@ define(['../Core/Color', var granularity = ellipse.granularity; var stRotation = ellipse.stRotation; - options.vertexFormat = appearance.vertexFormat; options.center = position.getValue(time, options.center); options.semiMajorAxis = semiMajorAxis.getValue(time, options.semiMajorAxis); options.semiMinorAxis = semiMinorAxis.getValue(time, options.semiMinorAxis); @@ -327,15 +333,26 @@ define(['../Core/Color', options.granularity = defined(granularity) ? granularity.getValue(time, options.granularity) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(time, options.stRotation) : undefined; - this._primitive = new Primitive({ - geometryInstances : new GeometryInstance({ - id : this._dynamicObject, - geometry : new EllipseGeometry(options) - }), - appearance : appearance, - asynchronous : false - }); - this._primitives.add(this._primitive); + if (!defined(ellipse.fill) || ellipse.fill.getValue(time)) { + this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); + var material = this._material; + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : this._dynamicObject, + geometry : new EllipseGeometry(options) + }), + appearance : appearance, + asynchronous : false + }); + this._primitives.add(this._primitive); + } if (defined(ellipse.outline) && ellipse.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; @@ -366,7 +383,10 @@ define(['../Core/Color', DynamicGeometryBatchItem.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); - this._primitives.add(this._outlinePrimitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); } }; From 4c9742514c26e0300c3e40a767010a2683a45f4e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 3 Feb 2014 09:13:41 -0500 Subject: [PATCH 19/81] Add support for DynamicEllipse.numberOfVerticalLines --- Source/DynamicScene/CzmlDataSource.js | 1 + Source/DynamicScene/DynamicEllipse.js | 13 +++++++- Source/DynamicScene/EllipseGeometryUpdater.js | 33 +++++++++++-------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index a7da9ae88158..2883d9bb2778 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -1024,6 +1024,7 @@ define(['../Core/Cartesian2', processPacketData(Boolean, ellipse, 'fill', ellipseData.fill, interval, sourceUri); processPacketData(Boolean, ellipse, 'outline', ellipseData.outline, interval, sourceUri); processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri); + processPacketData(Number, ellipse, 'numberOfVerticalLines', ellipseData.numberOfVerticalLines, interval, sourceUri); } function processEllipsoid(dynamicObject, packet, dynamicObjectCollection, sourceUri) { diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index 0fac459fddb5..7ecc311a4dcb 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -39,6 +39,7 @@ define(['../Core/Cartesian3', this._propertyChanged = new Event(); this._outline = undefined; this._outlineColor = undefined; + this._numberOfVerticalLines = undefined; }; defineProperties(DynamicEllipse.prototype, { @@ -140,7 +141,15 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + + /** + * Gets or sets the Number {@link Property} specifying the number of vertical lines + * to use when outlining the ellipse. + * @memberof DynamicEllipse.prototype + * @type {Property} + */ + numberOfVerticalLines : createDynamicPropertyDescriptor('numberOfVerticalLines', '_numberOfVerticalLines') }); /** @@ -166,6 +175,7 @@ define(['../Core/Cartesian3', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; + result.numberOfVerticalLines = this.numberOfVerticalLines; return result; }; @@ -196,6 +206,7 @@ define(['../Core/Cartesian3', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines); }; return DynamicEllipse; diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 5943fb20e9d8..f2d35b457895 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -14,8 +14,8 @@ define(['../Core/Color', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', '../DynamicScene/GeometryBatchType', - '../Scene/MaterialAppearance', '../DynamicScene/MaterialProperty', + '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive' ], function( @@ -34,8 +34,8 @@ define(['../Core/Color', ColorMaterialProperty, ConstantProperty, GeometryBatchType, - MaterialAppearance, MaterialProperty, + MaterialAppearance, PerInstanceColorAppearance, Primitive) { "use strict"; @@ -79,7 +79,6 @@ define(['../Core/Color', this._outlineColorProperty = undefined; this._outlineGeometryChanged = new Event(); this._options = new GeometryOptions(dynamicObject); - this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); }; @@ -246,6 +245,7 @@ define(['../Core/Color', var extrudedHeight = ellipse.extrudedHeight; var granularity = ellipse.granularity; var stRotation = ellipse.stRotation; + var numberOfVerticalLines = ellipse.numberOfVerticalLines; if (!position.isConstant || // !semiMajorAxis.isConstant || // @@ -254,7 +254,8 @@ define(['../Core/Color', defined(height) && !height.isConstant || // defined(extrudedHeight) && !extrudedHeight.isConstant || // defined(granularity) && !granularity.isConstant || // - defined(stRotation) && !stRotation.isConstant) { + defined(stRotation) && !stRotation.isConstant || // + defined(numberOfVerticalLines) && !numberOfVerticalLines.isConstant) { if (this._geometryType !== GeometryBatchType.DYNAMIC) { this._geometryType = GeometryBatchType.DYNAMIC; this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); @@ -265,11 +266,12 @@ define(['../Core/Color', options.center = position.getValue(Iso8601.MINIMUM_VALUE, options.center); options.semiMajorAxis = semiMajorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMajorAxis); options.semiMinorAxis = semiMinorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMinorAxis); - options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE, options.rotation) : undefined; - options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE, options.height) : undefined; - options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE, options.extrudedHeight) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE, options.granularity) : undefined; - options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE, options.stRotation) : undefined; + options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; if (isFilled) { this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; @@ -323,15 +325,16 @@ define(['../Core/Color', var extrudedHeight = ellipse.extrudedHeight; var granularity = ellipse.granularity; var stRotation = ellipse.stRotation; + var numberOfVerticalLines = ellipse.numberOfVerticalLines; options.center = position.getValue(time, options.center); options.semiMajorAxis = semiMajorAxis.getValue(time, options.semiMajorAxis); options.semiMinorAxis = semiMinorAxis.getValue(time, options.semiMinorAxis); - options.rotation = defined(rotation) ? rotation.getValue(time, options.rotation) : undefined; - options.height = defined(height) ? height.getValue(time, options.height) : undefined; - options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(time, options.extrudedHeight) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(time, options.granularity) : undefined; - options.stRotation = defined(stRotation) ? stRotation.getValue(time, options.stRotation) : undefined; + options.rotation = defined(rotation) ? rotation.getValue(time, options) : undefined; + options.height = defined(height) ? height.getValue(time, options) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(time, options) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(time) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(time) : undefined; if (!defined(ellipse.fill) || ellipse.fill.getValue(time)) { this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); @@ -356,6 +359,8 @@ define(['../Core/Color', if (defined(ellipse.outline) && ellipse.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + var outlineColor = defined(ellipse.outlineColor) ? ellipse.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ geometryInstances : new GeometryInstance({ From 6ae899001422c8e7d1decaa13062d71a0519274e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 3 Feb 2014 10:36:46 -0500 Subject: [PATCH 20/81] Ongoing geometry work Better support for show/fill/outline properties. Fix material handling and other misc cleanup. --- Source/DynamicScene/EllipseGeometryUpdater.js | 80 ++++++++++++------- Source/DynamicScene/GeometryVisualizer.js | 2 +- .../DynamicScene/StaticGeometryColorBatch.js | 6 +- .../StaticGeometryPerMaterialBatch.js | 8 +- .../StaticOutlineGeometryBatch.js | 4 +- 5 files changed, 59 insertions(+), 41 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index f2d35b457895..2045e6a95e32 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -43,7 +43,7 @@ define(['../Core/Color', //TODO Fix fill for static objects var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); var defaultShow = new ConstantProperty(true); - var defaultFill = new ColorMaterialProperty(true); + var defaultFill = new ConstantProperty(true); var defaultOutline = new ConstantProperty(false); var defaultOutlineColor = new ConstantProperty(Color.BLACK); @@ -74,7 +74,8 @@ define(['../Core/Color', this._geometryChanged = new Event(); this._showProperty = undefined; this._materialProperty = undefined; - this._isOutlined = false; + this._outlineEnabled = false; + this._hasConstantOutline = true; this._showOutlineProperty = undefined; this._outlineColorProperty = undefined; this._outlineGeometryChanged = new Event(); @@ -102,24 +103,24 @@ define(['../Core/Color', return this._geometryChanged; } }, - showProperty : { + fillMaterialProperty : { get : function() { - return this._showProperty; + return this._materialProperty; } }, - materialProperty : { + outlineEnabled : { get : function() { - return this._materialProperty; + return this._outlineEnabled; } }, - isOutlined : { + hasConstantFill : { get : function() { - return this._isOutlined; + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; } }, - showOutlineProperty : { + hasConstantOutline : { get : function() { - return this._showOutlineProperty; + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; } }, outlineColorProperty : { @@ -134,23 +135,41 @@ define(['../Core/Color', } }); + EllipseGeometryUpdater.prototype.isOutlineVisible = function(time){ + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + EllipseGeometryUpdater.prototype.isFilled = function(time){ + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; + EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); + var attributes; + var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time)); + var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); if (this._geometryType === GeometryBatchType.COLOR) { var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + color : color + }; + } else { + attributes = { + show : show + }; } + return new GeometryInstance({ id : dynamicObject, geometry : new EllipseGeometry(this._options), - attributes : { - show : show, - color : color - } + attributes : attributes }); }; @@ -162,7 +181,7 @@ define(['../Core/Color', id : dynamicObject, geometry : new EllipseOutlineGeometry(this._options), attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && this._showOutlineProperty.getValue(time)), + show : new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) } }); @@ -195,9 +214,9 @@ define(['../Core/Color', this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } - if(this._isOutlined){ - this._isOutlined = false; - this._outlineGeometryChanged.raiseEvent(this._isOutlined); + if(this._outlineEnabled){ + this._outlineEnabled = false; + this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); } return; } @@ -206,12 +225,12 @@ define(['../Core/Color', var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; var outlineProperty = ellipse.outline; - var isOutlined = defined(outlineProperty); - if (isOutlined && outlineProperty.isConstant) { - isOutlined = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - if (!isFilled && !isOutlined) { + if (!isFilled && !outlineEnabled) { return; } @@ -226,9 +245,9 @@ define(['../Core/Color', this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } - if (this._isOutlined) { - this._isOutlined = false; - this._outlineGeometryChanged.raiseEvent(this._isOutlined); + if (this._outlineEnabled) { + this._outlineEnabled = false; + this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); } return; } @@ -236,6 +255,7 @@ define(['../Core/Color', var material = defaultValue(ellipse.material, defaultMaterial); var isColorMaterial = material instanceof ColorMaterialProperty; this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); this._outlineColorProperty = defaultValue(ellipse.outlineColor, defaultOutlineColor); @@ -277,9 +297,9 @@ define(['../Core/Color', this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); } - if (isOutlined) { - this._isOutlined = true; - this._outlineGeometryChanged.raiseEvent(this._isOutlined); + if (outlineEnabled) { + this._outlineEnabled = true; + this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); } } }; @@ -337,7 +357,7 @@ define(['../Core/Color', options.stRotation = defined(stRotation) ? stRotation.getValue(time) : undefined; if (!defined(ellipse.fill) || ellipse.fill.getValue(time)) { - this._material = MaterialProperty.getValue(time, geometryUpdater.materialProperty, this._material); + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); var material = this._material; var appearance = new MaterialAppearance({ material : material, diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 45855f434bad..321892bb3d6f 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -200,7 +200,7 @@ define(['../Core/defined', batch.add(time, updater); } - if (updater.isOutlined) { + if (updater.outlineEnabled) { this._outlineBatch.add(time, updater); } } diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 8c32219b24f4..d2bfb511118b 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -32,7 +32,7 @@ define(['../Core/Color', this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); - if (!updater.showProperty.isConstant || !updater.materialProperty.isConstant) { + if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) { this.updatersWithAttributes.set(id, updater); } }; @@ -82,13 +82,13 @@ define(['../Core/Color', this.attributes.set(instance.id.id, attributes); } - var colorProperty = updater.materialProperty.color; + var colorProperty = updater.fillMaterialProperty.color; colorProperty.getValue(time, colorScratch); attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { this.itemsToRemove[removedCount++] = updater; } - attributes.show = ShowGeometryInstanceAttribute.toValue(updater.showProperty.getValue(time), attributes.show); + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show); } } this.itemsToRemove.length = removedCount; diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 85a0f2265dae..1b8fc4694f59 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -86,10 +86,8 @@ define(['../Core/defined', attributes = primitive.getGeometryInstanceAttributes(instance.id); updater.attributes = attributes; } - var show = updater.show; - if (defined(show)) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); - } + var show = updater.isFilled(time); + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); } } }; @@ -118,7 +116,7 @@ define(['../Core/defined', return; } } - var batch = new Batch(this._primitives, this._appearanceType, updater.materialProperty); + var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty); batch.add(time, updater); items.push(batch); }; diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 09369e2ab0d4..6a860446bda3 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -34,7 +34,7 @@ define(['../Core/Color', this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); - if (!updater.showOutlineProperty.isConstant || !updater.materialProperty.isConstant) { + if (!updater.hasConstantOutline || !updater.outlineColorProperty.isConstant) { this.updatersWithAttributes.set(id, updater); } }; @@ -95,7 +95,7 @@ define(['../Core/Color', if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { this.itemsToRemove[removedCount++] = updater; } - attributes.show = ShowGeometryInstanceAttribute.toValue(updater.showOutlineProperty.getValue(time), attributes.show); + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isOutlineVisible(time), attributes.show); } } this.itemsToRemove.length = removedCount; From 4bef033132bcfc6911ab0131369744ea62b685b3 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 3 Feb 2014 11:17:18 -0500 Subject: [PATCH 21/81] Improve material batching to only evaluate time-dynamic attributes. Also some other minor fixes. --- Source/DynamicScene/EllipseGeometryUpdater.js | 3 +- .../DynamicScene/StaticGeometryColorBatch.js | 17 +++++--- .../StaticGeometryPerMaterialBatch.js | 39 ++++++++++++------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 2045e6a95e32..a5d42d86ce80 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -40,7 +40,6 @@ define(['../Core/Color', Primitive) { "use strict"; - //TODO Fix fill for static objects var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); @@ -379,7 +378,7 @@ define(['../Core/Color', if (defined(ellipse.outline) && ellipse.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(time) : undefined; var outlineColor = defined(ellipse.outlineColor) ? ellipse.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index d2bfb511118b..bc8e9420c6aa 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -82,13 +82,18 @@ define(['../Core/Color', this.attributes.set(instance.id.id, attributes); } - var colorProperty = updater.fillMaterialProperty.color; - colorProperty.getValue(time, colorScratch); - attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); - if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { - this.itemsToRemove[removedCount++] = updater; + if (!updater.fillMaterialProperty.isConstant) { + var colorProperty = updater.fillMaterialProperty.color; + colorProperty.getValue(time, colorScratch); + attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; + } + } + + if (!updater.hasConstantFill) { + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show); } - attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show); } } this.itemsToRemove.length = removedCount; diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 1b8fc4694f59..1c620e1a1996 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -20,9 +20,11 @@ define(['../Core/defined', this._createPrimitive = true; this._primitive = undefined; this._primitives = primitives; - this._geometries = new Map(); + this._geometry = new Map(); this._material = Material.fromType('Color'); this._appearanceType = appearanceType; + this._updatersWithAttributes = new Map(); + this._attributes = new Map(); }; Batch.prototype.isMaterial = function(updater) { @@ -38,21 +40,27 @@ define(['../Core/defined', }; Batch.prototype.add = function(time, updater) { - this._updaters.set(updater.id, updater); - this._geometries.set(updater.id, updater.createGeometryInstance(time)); + var id = updater.id; + this._updaters.set(id, updater); + this._geometry.set(id, updater.createGeometryInstance(time)); + if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) { + this._updatersWithAttributes.set(id, updater); + } this._createPrimitive = true; }; Batch.prototype.remove = function(updater) { - this._createPrimitive = this._updaters.remove(updater.id); - this._geometries.remove(updater.id); + var id = updater.id; + this._createPrimitive = this._updaters.remove(id); + this._geometry.remove(id); + this._updatersWithAttributes.remove(id); return this._createPrimitive; }; Batch.prototype.update = function(time) { var primitive = this._primitive; var primitives = this._primitives; - var geometries = this._geometries.getValues(); + var geometries = this._geometry.getValues(); if (this._createPrimitive) { if (defined(primitive)) { primitives.remove(primitive); @@ -76,18 +84,21 @@ define(['../Core/defined', } else { this._primitive.appearance.material = MaterialProperty.getValue(time, this._materialProperty, this._material); - var updaters = this._updaters.getValues(); - for (var i = geometries.length - 1; i > -1; i--) { - var instance = geometries[i]; - var updater = updaters[i]; + var updatersWithAttributes = this._updatersWithAttributes.getValues(); + var length = updatersWithAttributes.length; + for (var i = 0; i < length; i++) { + var updater = updatersWithAttributes[i]; + var instance = this._geometry.get(updater.id); - var attributes = updater.attributes; + var attributes = this._attributes.get(instance.id.id); if (!defined(attributes)) { attributes = primitive.getGeometryInstanceAttributes(instance.id); - updater.attributes = attributes; + this._attributes.set(instance.id.id, attributes); + } + + if (!updater.hasConstantFill) { + attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show); } - var show = updater.isFilled(time); - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); } } }; From 80179cf786136a2fd22d4efa9be66f7ba85a7321 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 5 Feb 2014 11:15:56 -0500 Subject: [PATCH 22/81] Change property events to be more coarse grained This is the start of larger set of changes to move to a more event driven graphics update loop, rather than the polling we do now. --- Source/DynamicScene/EllipseGeometryUpdater.js | 6 +++++- .../createDynamicPropertyDescriptor.js | 17 ++++++++++++++++- .../DynamicScene/EllipseGeometryUpdaterSpec.js | 14 -------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index a5d42d86ce80..ed600f78d268 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -195,7 +195,7 @@ define(['../Core/Color', this._ellipse = newValue; if (defined(newValue)) { - this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._update, this); + this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); } this._update(); @@ -204,6 +204,10 @@ define(['../Core/Color', } }; + EllipseGeometryUpdater.prototype._onEllipsePropertyChanged = function(ellipse, propertyName, oldValue, newValue) { + this._update(); + }; + EllipseGeometryUpdater.prototype._update = function() { var ellipse = this._dynamicObject.ellipse; var oldGeometryType = this._geometryType; diff --git a/Source/DynamicScene/createDynamicPropertyDescriptor.js b/Source/DynamicScene/createDynamicPropertyDescriptor.js index 12005b6b7329..7ca7581a150d 100644 --- a/Source/DynamicScene/createDynamicPropertyDescriptor.js +++ b/Source/DynamicScene/createDynamicPropertyDescriptor.js @@ -1,5 +1,9 @@ /*global define*/ -define(['../Core/defaultValue'], function(defaultValue) { +define(['../Core/defaultValue', + '../Core/defined' + ], function( + defaultValue, + defined) { "use strict"; /** @@ -7,6 +11,7 @@ define(['../Core/defaultValue'], function(defaultValue) { * @private */ function createDynamicPropertyDescriptor(name, privateName, configurable) { + var subscriptionName = privateName + 'Subsription'; return { configurable : defaultValue(configurable, false), get : function() { @@ -14,10 +19,20 @@ define(['../Core/defaultValue'], function(defaultValue) { }, set : function(value) { var oldValue = this[privateName]; + var subscription = this[subscriptionName]; + if (defined(subscription)) { + subscription(); + this[subscriptionName] = undefined; + } if (oldValue !== value) { this[privateName] = value; this._propertyChanged.raiseEvent(this, name, value, oldValue); } + if (defined(value) && defined(value.definitionChanged)) { + this[subscriptionName] = value.definitionChanged.addEventListener(function() { + this._propertyChanged.raiseEvent(this, name, value, value); + }, this); + } } }; } diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 8c0a16697ba0..dc4ec6715d32 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -35,90 +35,76 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', //Undefined ellipse dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.NONE); //Undefined ellipse.semiMajorAxis && ellipse.semiMinorAxis var ellipse = new DynamicEllipse(); dynamicObject.ellipse = ellipse; - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.NONE); //Undefined ellipse.semiMinorAxis ellipse.semiMajorAxis = new ConstantProperty(1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.NONE); //Undefined ellipse.semiMajorAxis ellipse.semiMajorAxis = undefined; ellipse.semiMinorAxis = new ConstantProperty(2); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.NONE); //Default color ellipse.semiMajorAxis = new ConstantProperty(1); ellipse.semiMinorAxis = new ConstantProperty(2); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.COLOR); //Non-color material ellipse.material = new GridMaterialProperty(); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.MATERIAL); //Dynamic position dynamicObject.position = new SampledPositionProperty(); dynamicObject.position.addSample(new JulianDate(), new Cartesian3()); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic semiMinorAxis dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); ellipse.semiMinorAxis = new SampledProperty(Number); ellipse.semiMinorAxis.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic semiMajorAxis ellipse.semiMinorAxis = new ConstantProperty(1); ellipse.semiMajorAxis = new SampledProperty(Number); ellipse.semiMajorAxis.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic rotation ellipse.semiMajorAxis = new ConstantProperty(1); ellipse.rotation = new SampledProperty(Number); ellipse.rotation.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic height ellipse.rotation = new ConstantProperty(1); ellipse.height = new SampledProperty(Number); ellipse.height.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic extrudedHeight ellipse.height = new ConstantProperty(1); ellipse.extrudedHeight = new SampledProperty(Number); ellipse.extrudedHeight.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic granularity ellipse.extrudedHeight = new ConstantProperty(1); ellipse.granularity = new SampledProperty(Number); ellipse.granularity.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); //Dynamic stRotation ellipse.granularity = new ConstantProperty(1); ellipse.stRotation = new SampledProperty(Number); ellipse.stRotation.addSample(new JulianDate(), 1); - updater = new EllipseGeometryUpdater(dynamicObject); expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); }); From 9cb4482c762517db6d6b6914892f11e91a0c739a Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 5 Feb 2014 11:30:31 -0500 Subject: [PATCH 23/81] Rename `propertyChanged` to `definitionChanged` `definitionChanged` is raised when any aspect of the object changes, i.e either by assigning a new property or modifying an existing property. --- .../DynamicScene/CompositeDynamicObjectCollection.js | 8 ++++---- Source/DynamicScene/DynamicBillboard.js | 6 +++--- Source/DynamicScene/DynamicClock.js | 6 +++--- Source/DynamicScene/DynamicCone.js | 6 +++--- Source/DynamicScene/DynamicEllipse.js | 6 +++--- Source/DynamicScene/DynamicEllipsoid.js | 6 +++--- Source/DynamicScene/DynamicLabel.js | 6 +++--- Source/DynamicScene/DynamicObject.js | 12 ++++++------ Source/DynamicScene/DynamicPath.js | 6 +++--- Source/DynamicScene/DynamicPoint.js | 6 +++--- Source/DynamicScene/DynamicPolygon.js | 6 +++--- Source/DynamicScene/DynamicPolyline.js | 6 +++--- Source/DynamicScene/DynamicPyramid.js | 6 +++--- Source/DynamicScene/DynamicVector.js | 6 +++--- Source/DynamicScene/EllipseGeometryUpdater.js | 4 ++-- .../DynamicScene/createDynamicPropertyDescriptor.js | 4 ++-- Specs/DynamicScene/DynamicObjectSpec.js | 6 +++--- 17 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Source/DynamicScene/CompositeDynamicObjectCollection.js b/Source/DynamicScene/CompositeDynamicObjectCollection.js index e811a07d9147..e8f2ab759c70 100644 --- a/Source/DynamicScene/CompositeDynamicObjectCollection.js +++ b/Source/DynamicScene/CompositeDynamicObjectCollection.js @@ -92,12 +92,12 @@ define(['../Core/createGuid', } function subscribeToProperty(that, eventHash, collectionId, dynamicObject, propertyName, property) { - if (defined(property) && defined(property.propertyChanged)) { - var subpropertyChanged = createSubPropertyChangedCallback(that, dynamicObject, propertyName); + if (defined(property) && defined(property.definitionChanged)) { + var subdefinitionChanged = createSubPropertyChangedCallback(that, dynamicObject, propertyName); propertyIdScratch[0] = collectionId; propertyIdScratch[1] = dynamicObject.id; propertyIdScratch[2] = propertyName; - eventHash[JSON.stringify(propertyIdScratch)] = property.propertyChanged.addEventListener(subpropertyChanged); + eventHash[JSON.stringify(propertyIdScratch)] = property.definitionChanged.addEventListener(subdefinitionChanged); } } @@ -116,7 +116,7 @@ define(['../Core/createGuid', function subscribeToDynamicObject(that, eventHash, collectionId, dynamicObject) { dynamicObjectIdScratch[0] = collectionId; dynamicObjectIdScratch[1] = dynamicObject.id; - eventHash[JSON.stringify(dynamicObjectIdScratch)] = dynamicObject.propertyChanged.addEventListener(createPropertyChangedCallback(that, collectionId)); + eventHash[JSON.stringify(dynamicObjectIdScratch)] = dynamicObject.definitionChanged.addEventListener(createPropertyChangedCallback(that, collectionId)); var properties = dynamicObject.propertyNames; var length = properties.length; diff --git a/Source/DynamicScene/DynamicBillboard.js b/Source/DynamicScene/DynamicBillboard.js index 50c67a01ac02..437e32417caf 100644 --- a/Source/DynamicScene/DynamicBillboard.js +++ b/Source/DynamicScene/DynamicBillboard.js @@ -36,7 +36,7 @@ define(['../Core/defaultValue', this._scaleByDistance = undefined; this._translucencyByDistance = undefined; this._pixelOffsetScaleByDistance = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicBillboard.prototype, { @@ -45,9 +45,9 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicClock.js b/Source/DynamicScene/DynamicClock.js index 2ddcb1db6413..e7eaf4a9240d 100644 --- a/Source/DynamicScene/DynamicClock.js +++ b/Source/DynamicScene/DynamicClock.js @@ -31,7 +31,7 @@ define(['../Core/Clock', this._clockRange = undefined; this._clockStep = undefined; this._multiplier = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicClock.prototype, { @@ -40,9 +40,9 @@ define(['../Core/Clock', * @memberof DynamicClock.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicCone.js b/Source/DynamicScene/DynamicCone.js index 67f1ff06fa6f..bc80fa3be2ab 100644 --- a/Source/DynamicScene/DynamicCone.js +++ b/Source/DynamicScene/DynamicCone.js @@ -34,7 +34,7 @@ define(['../Core/defaultValue', this._showIntersection = undefined; this._radius = undefined; this._show = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicCone.prototype, { @@ -43,9 +43,9 @@ define(['../Core/defaultValue', * @memberof DynamicCone.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index 7ecc311a4dcb..8b040a6e952e 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -36,7 +36,7 @@ define(['../Core/Cartesian3', this._extrudedHeight = undefined; this._granularity = undefined; this._stRotation = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); this._outline = undefined; this._outlineColor = undefined; this._numberOfVerticalLines = undefined; @@ -48,9 +48,9 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicEllipsoid.js b/Source/DynamicScene/DynamicEllipsoid.js index 6b68b2c3c095..da7106e1a8f3 100644 --- a/Source/DynamicScene/DynamicEllipsoid.js +++ b/Source/DynamicScene/DynamicEllipsoid.js @@ -24,7 +24,7 @@ define(['../Core/defaultValue', this._show = undefined; this._radii = undefined; this._material = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicEllipsoid.prototype, { @@ -33,9 +33,9 @@ define(['../Core/defaultValue', * @memberof DynamicEllipsoid.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicLabel.js b/Source/DynamicScene/DynamicLabel.js index 6708eaaa4145..448021baa14e 100644 --- a/Source/DynamicScene/DynamicLabel.js +++ b/Source/DynamicScene/DynamicLabel.js @@ -34,7 +34,7 @@ define(['../Core/defaultValue', this._show = undefined; this._translucencyByDistance = undefined; this._pixelOffsetScaleByDistance = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicLabel.prototype, { @@ -43,9 +43,9 @@ define(['../Core/defaultValue', * @memberof DynamicLabel.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicObject.js b/Source/DynamicScene/DynamicObject.js index ada5ca1bceef..e2f82afad6e7 100644 --- a/Source/DynamicScene/DynamicObject.js +++ b/Source/DynamicScene/DynamicObject.js @@ -20,7 +20,7 @@ define(['../Core/createGuid', createDynamicPropertyDescriptor) { "use strict"; - var reservedPropertyNames = ['cachedAvailabilityDate', 'cachedAvailabilityValue', 'id', 'propertyChanged', // + var reservedPropertyNames = ['cachedAvailabilityDate', 'cachedAvailabilityValue', 'id', 'definitionChanged', // 'propertyNames', 'isAvailable', 'clean', 'merge', 'addProperty', 'removeProperty']; /** @@ -64,7 +64,7 @@ define(['../Core/createGuid', this._viewFrom = undefined; this._description = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); this._propertyNames = ['parent', 'position', 'orientation', 'billboard', // 'cone', 'ellipsoid', 'ellipse', 'label', 'path', 'point', 'polygon', // 'polyline', 'pyramid', 'vertexPositions', 'vector', 'viewFrom', 'description']; @@ -76,9 +76,9 @@ define(['../Core/createGuid', * @memberof DynamicObject.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, /** @@ -116,7 +116,7 @@ define(['../Core/createGuid', var oldValue = this._name; if (oldValue !== value) { this._name = value; - this._propertyChanged.raiseEvent(this, 'name', value, oldValue); + this._definitionChanged.raiseEvent(this, 'name', value, oldValue); } } }, @@ -257,7 +257,7 @@ define(['../Core/createGuid', /** * Adds a property to this object. Once a property is added, it can be - * observed with {@link DynamicObject.propertyChanged} and composited + * observed with {@link DynamicObject.definitionChanged} and composited * with {@link CompositeDynamicObjectCollection} * @memberof DynamicObject * diff --git a/Source/DynamicScene/DynamicPath.js b/Source/DynamicScene/DynamicPath.js index 27a93ff371b8..e0f184a1f68a 100644 --- a/Source/DynamicScene/DynamicPath.js +++ b/Source/DynamicScene/DynamicPath.js @@ -28,7 +28,7 @@ define(['../Core/defaultValue', this._resolution = undefined; this._leadTime = undefined; this._trailTime = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicPath.prototype, { @@ -37,9 +37,9 @@ define(['../Core/defaultValue', * @memberof DynamicPath.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicPoint.js b/Source/DynamicScene/DynamicPoint.js index b7b78b7bc086..c4cca13a60b5 100644 --- a/Source/DynamicScene/DynamicPoint.js +++ b/Source/DynamicScene/DynamicPoint.js @@ -26,7 +26,7 @@ define(['../Core/defaultValue', this._outlineWidth = undefined; this._show = undefined; this._scaleByDistance = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicPoint.prototype, { @@ -35,9 +35,9 @@ define(['../Core/defaultValue', * @memberof DynamicPoint.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicPolygon.js b/Source/DynamicScene/DynamicPolygon.js index 195dd7bf4bc7..625db9fe9114 100644 --- a/Source/DynamicScene/DynamicPolygon.js +++ b/Source/DynamicScene/DynamicPolygon.js @@ -27,7 +27,7 @@ define(['../Core/defaultValue', this._extrudedHeight = undefined; this._granularity = undefined; this._stRotation = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicPolygon.prototype, { @@ -36,9 +36,9 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicPolyline.js b/Source/DynamicScene/DynamicPolyline.js index 7e213beec192..e869564b2068 100644 --- a/Source/DynamicScene/DynamicPolyline.js +++ b/Source/DynamicScene/DynamicPolyline.js @@ -23,7 +23,7 @@ define(['../Core/defaultValue', this._show = undefined; this._material = undefined; this._width = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicPolyline.prototype, { @@ -32,9 +32,9 @@ define(['../Core/defaultValue', * @memberof DynamicPolyline.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicPyramid.js b/Source/DynamicScene/DynamicPyramid.js index 310caa43d706..f68fd6d9326c 100644 --- a/Source/DynamicScene/DynamicPyramid.js +++ b/Source/DynamicScene/DynamicPyramid.js @@ -28,7 +28,7 @@ define(['../Core/defaultValue', this._intersectionColor = undefined; this._intersectionWidth = undefined; this._material = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicPyramid.prototype, { @@ -37,9 +37,9 @@ define(['../Core/defaultValue', * @memberof DynamicPyramid.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/DynamicVector.js b/Source/DynamicScene/DynamicVector.js index 11b528fdd699..b0a19b1738bc 100644 --- a/Source/DynamicScene/DynamicVector.js +++ b/Source/DynamicScene/DynamicVector.js @@ -25,7 +25,7 @@ define(['../Core/defaultValue', this._width = undefined; this._direction = undefined; this._length = undefined; - this._propertyChanged = new Event(); + this._definitionChanged = new Event(); }; defineProperties(DynamicVector.prototype, { @@ -34,9 +34,9 @@ define(['../Core/defaultValue', * @memberof DynamicVector.prototype * @type {Event} */ - propertyChanged : { + definitionChanged : { get : function() { - return this._propertyChanged; + return this._definitionChanged; } }, diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index ed600f78d268..da65a17b0621 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -67,7 +67,7 @@ define(['../Core/Color', this._id = dynamicObject.id; this._dynamicObject = dynamicObject; - this._dynamicObjectSubscription = dynamicObject.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); + this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._ellipseSubscription = undefined; this._geometryType = GeometryBatchType.NONE; this._geometryChanged = new Event(); @@ -195,7 +195,7 @@ define(['../Core/Color', this._ellipse = newValue; if (defined(newValue)) { - this._ellipseSubscription = newValue.propertyChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); + this._ellipseSubscription = newValue.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); } this._update(); diff --git a/Source/DynamicScene/createDynamicPropertyDescriptor.js b/Source/DynamicScene/createDynamicPropertyDescriptor.js index 7ca7581a150d..720985cac5d9 100644 --- a/Source/DynamicScene/createDynamicPropertyDescriptor.js +++ b/Source/DynamicScene/createDynamicPropertyDescriptor.js @@ -26,11 +26,11 @@ define(['../Core/defaultValue', } if (oldValue !== value) { this[privateName] = value; - this._propertyChanged.raiseEvent(this, name, value, oldValue); + this._definitionChanged.raiseEvent(this, name, value, oldValue); } if (defined(value) && defined(value.definitionChanged)) { this[subscriptionName] = value.definitionChanged.addEventListener(function() { - this._propertyChanged.raiseEvent(this, name, value, value); + this._definitionChanged.raiseEvent(this, name, value, value); }, this); } } diff --git a/Specs/DynamicScene/DynamicObjectSpec.js b/Specs/DynamicScene/DynamicObjectSpec.js index 599c42875dd6..f190dcc964f9 100644 --- a/Specs/DynamicScene/DynamicObjectSpec.js +++ b/Specs/DynamicScene/DynamicObjectSpec.js @@ -52,12 +52,12 @@ defineSuite([ expect(dynamicObject.isAvailable(interval.stop.addSeconds(1))).toEqual(false); }); - it('propertyChanged works for all properties', function() { + it('definitionChanged works for all properties', function() { var dynamicObject = new DynamicObject(); var propertyNames = dynamicObject.propertyNames; var propertyNamesLength = propertyNames.length; - spyOn(dynamicObject.propertyChanged, 'raiseEvent'); + spyOn(dynamicObject.definitionChanged, 'raiseEvent'); var i; var name; @@ -70,7 +70,7 @@ defineSuite([ newValue = new ConstantProperty(1); oldValue = dynamicObject[propertyNames[i]]; dynamicObject[name] = newValue; - expect(dynamicObject.propertyChanged.raiseEvent).toHaveBeenCalledWith(dynamicObject, name, newValue, oldValue); + expect(dynamicObject.definitionChanged.raiseEvent).toHaveBeenCalledWith(dynamicObject, name, newValue, oldValue); } } }); From dd396f4523225a5cfb5b206fb873ccbffa3cc944 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 5 Feb 2014 12:34:45 -0500 Subject: [PATCH 24/81] Use `id` property for consistent picking. This is a breaking change which removes the practice of monkey patching primitives with a `dynamicObject` property. --- .../DynamicBillboardVisualizer.js | 2 +- .../DynamicConeVisualizerUsingCustomSensor.js | 2 +- .../DynamicEllipsoidVisualizer.js | 2 +- Source/DynamicScene/DynamicLabelVisualizer.js | 2 +- Source/DynamicScene/DynamicPathVisualizer.js | 2 +- Source/DynamicScene/DynamicPointVisualizer.js | 2 +- .../DynamicScene/DynamicPolygonVisualizer.js | 2 +- .../DynamicScene/DynamicPolylineVisualizer.js | 2 +- .../DynamicScene/DynamicPyramidVisualizer.js | 2 +- .../DynamicScene/DynamicVectorVisualizer.js | 2 +- .../Viewer/viewerDynamicObjectMixin.js | 22 +++++++++++-------- .../DynamicBillboardVisualizerSpec.js | 6 ++--- ...amicConeVisualizerUsingCustomSensorSpec.js | 6 ++--- .../DynamicEllipsoidVisualizerSpec.js | 6 ++--- .../DynamicLabelVisualizerSpec.js | 6 ++--- .../DynamicScene/DynamicPathVisualizerSpec.js | 6 ++--- .../DynamicPointVisualizerSpec.js | 6 ++--- .../DynamicPolygonVisualizerSpec.js | 6 ++--- .../DynamicPolylineVisualizerSpec.js | 6 ++--- .../DynamicPyramidVisualizerSpec.js | 6 ++--- .../DynamicVectorVisualizerSpec.js | 6 ++--- 21 files changed, 53 insertions(+), 49 deletions(-) diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index 9245001c155a..6aba6e90dc8b 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -250,7 +250,7 @@ define([ billboard = dynamicBillboardVisualizer._billboardCollection.add(); } dynamicObject._billboardVisualizerIndex = billboardVisualizerIndex; - billboard.dynamicObject = dynamicObject; + billboard.id = dynamicObject; billboard._visualizerUrl = undefined; billboard._visualizerTextureAvailable = false; diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index ff4016e5e75c..4dda6b180655 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -285,7 +285,7 @@ define([ dynamicConeVisualizerUsingCustomSensor._primitives.add(cone); } dynamicObject._coneVisualizerIndex = coneVisualizerIndex; - cone.dynamicObject = dynamicObject; + cone.id = dynamicObject; // CZML_TODO Determine official defaults cone.material = Material.fromType(Material.ColorType); diff --git a/Source/DynamicScene/DynamicEllipsoidVisualizer.js b/Source/DynamicScene/DynamicEllipsoidVisualizer.js index 0e3a46591712..d38f14abd3c5 100644 --- a/Source/DynamicScene/DynamicEllipsoidVisualizer.js +++ b/Source/DynamicScene/DynamicEllipsoidVisualizer.js @@ -240,7 +240,7 @@ define([ dynamicEllipsoidVisualizer._primitives.add(ellipsoid); } dynamicObject._ellipsoidVisualizerIndex = ellipsoidVisualizerIndex; - ellipsoid.dynamicObject = dynamicObject; + ellipsoid.id = dynamicObject; ellipsoid.material = Material.fromType(Material.ColorType); } else { diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index 55d2ef821590..85cd371600f7 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -228,7 +228,7 @@ define([ label = dynamicLabelVisualizer._labelCollection.add(); } dynamicObject._labelVisualizerIndex = labelVisualizerIndex; - label.dynamicObject = dynamicObject; + label.id = dynamicObject; // CZML_TODO Determine official defaults label.setText(''); diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 651976606a0a..ae33147d77dd 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -310,7 +310,7 @@ define([ polyline = this._polylineCollection.add(); } dynamicObject._pathVisualizerIndex = pathVisualizerIndex; - polyline.dynamicObject = dynamicObject; + polyline.id = dynamicObject; // CZML_TODO Determine official defaults polyline.setWidth(1); diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index fcb50d0b0028..c874e8bde8e5 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -220,7 +220,7 @@ define([ billboard = dynamicPointVisualizer._billboardCollection.add(); } dynamicObject._pointVisualizerIndex = pointVisualizerIndex; - billboard.dynamicObject = dynamicObject; + billboard.id = dynamicObject; // CZML_TODO Determine official defaults billboard._visualizerColor = Color.clone(Color.WHITE, billboard._visualizerColor); diff --git a/Source/DynamicScene/DynamicPolygonVisualizer.js b/Source/DynamicScene/DynamicPolygonVisualizer.js index b07ac790ed21..3a9a388319b3 100644 --- a/Source/DynamicScene/DynamicPolygonVisualizer.js +++ b/Source/DynamicScene/DynamicPolygonVisualizer.js @@ -216,7 +216,7 @@ define([ dynamicPolygonVisualizer._primitives.add(polygon); } dynamicObject._polygonVisualizerIndex = polygonVisualizerIndex; - polygon.dynamicObject = dynamicObject; + polygon.id = dynamicObject; // CZML_TODO Determine official defaults polygon.material = Material.fromType(Material.ColorType); diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index ace322b6cb66..2e0dbdb14954 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -214,7 +214,7 @@ define([ polyline = dynamicPolylineVisualizer._polylineCollection.add(); } dynamicObject._polylineVisualizerIndex = polylineVisualizerIndex; - polyline.dynamicObject = dynamicObject; + polyline.id = dynamicObject; // CZML_TODO Determine official defaults polyline.setWidth(1); diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index 59c789a233fc..83341fbf4cff 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -243,7 +243,7 @@ define([ dynamicPyramidVisualizer._primitives.add(pyramid); } dynamicObject._pyramidVisualizerIndex = pyramidVisualizerIndex; - pyramid.dynamicObject = dynamicObject; + pyramid.id = dynamicObject; // CZML_TODO Determine official defaults pyramid.radius = Number.POSITIVE_INFINITY; diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index ef78ebaa19b8..cd12f5a697ef 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -214,7 +214,7 @@ define([ polyline._visualizerPositions = [new Cartesian3(), new Cartesian3()]; } dynamicObject._vectorVisualizerIndex = vectorVisualizerIndex; - polyline.dynamicObject = dynamicObject; + polyline.id = dynamicObject; // CZML_TODO Determine official defaults polyline.setWidth(1); diff --git a/Source/Widgets/Viewer/viewerDynamicObjectMixin.js b/Source/Widgets/Viewer/viewerDynamicObjectMixin.js index 58cf05de3bba..d89c352ac26b 100644 --- a/Source/Widgets/Viewer/viewerDynamicObjectMixin.js +++ b/Source/Widgets/Viewer/viewerDynamicObjectMixin.js @@ -8,6 +8,7 @@ define(['../../Core/BoundingSphere', '../../Core/wrapFunction', '../../Scene/SceneMode', '../subscribeAndEvaluate', + '../../DynamicScene/DynamicObject', '../../DynamicScene/DynamicObjectView', '../../ThirdParty/knockout' ], function( @@ -20,6 +21,7 @@ define(['../../Core/BoundingSphere', wrapFunction, SceneMode, subscribeAndEvaluate, + DynamicObject, DynamicObjectView, knockout) { "use strict"; @@ -151,20 +153,22 @@ define(['../../Core/BoundingSphere', } eventHelper.add(viewer.clock.onTick, onTick); - function pickAndTrackObject(e) { + function pickDynamicObject(e) { var picked = viewer.scene.pick(e.position); - if (defined(picked) && defined(picked.primitive) && defined(picked.primitive.dynamicObject)) { - viewer.trackedObject = picked.primitive.dynamicObject; + if (defined(picked)) { + var id = defaultValue(picked.id, picked.primitive.id); + if (id instanceof DynamicObject) { + return id; + } } } + function pickAndTrackObject(e) { + viewer.trackedObject = defaultValue(pickDynamicObject(e), viewer.trackedObject); + } + function pickAndSelectObject(e) { - var picked = viewer.scene.pick(e.position); - if (defined(picked) && defined(picked.primitive) && defined(picked.primitive.dynamicObject)) { - viewer.selectedObject = picked.primitive.dynamicObject; - } else { - viewer.selectedObject = undefined; - } + viewer.selectedObject = pickDynamicObject(e); } // Subscribe to the home button beforeExecute event if it exists, diff --git a/Specs/DynamicScene/DynamicBillboardVisualizerSpec.js b/Specs/DynamicScene/DynamicBillboardVisualizerSpec.js index f2d6ae1fa2e0..ea793132b61e 100644 --- a/Specs/DynamicScene/DynamicBillboardVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicBillboardVisualizerSpec.js @@ -285,7 +285,7 @@ defineSuite([ visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); var bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject); + expect(bb.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -311,12 +311,12 @@ defineSuite([ visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); var bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject); + expect(bb.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject2); + expect(bb.id).toEqual(testObject2); }); }, 'WebGL'); diff --git a/Specs/DynamicScene/DynamicConeVisualizerUsingCustomSensorSpec.js b/Specs/DynamicScene/DynamicConeVisualizerUsingCustomSensorSpec.js index 4639c684cfe6..5fb572c02bf8 100644 --- a/Specs/DynamicScene/DynamicConeVisualizerUsingCustomSensorSpec.js +++ b/Specs/DynamicScene/DynamicConeVisualizerUsingCustomSensorSpec.js @@ -250,7 +250,7 @@ defineSuite([ var time = new JulianDate(); visualizer.update(time); - expect(scene.getPrimitives().get(0).dynamicObject).toEqual(testObject); + expect(scene.getPrimitives().get(0).id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -277,12 +277,12 @@ defineSuite([ visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); var conePrimitive = scene.getPrimitives().get(0); - expect(conePrimitive.dynamicObject).toEqual(testObject); + expect(conePrimitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); conePrimitive = scene.getPrimitives().get(0); - expect(conePrimitive.dynamicObject).toEqual(testObject2); + expect(conePrimitive.id).toEqual(testObject2); }); }, 'WebGL'); diff --git a/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js b/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js index 214800fdfc72..46e793592f6b 100644 --- a/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js @@ -191,7 +191,7 @@ defineSuite([ var time = new JulianDate(); visualizer.update(time); - expect(scene.getPrimitives().get(0).dynamicObject).toEqual(testObject); + expect(scene.getPrimitives().get(0).id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -216,12 +216,12 @@ defineSuite([ visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); var ellipsoidPrimitive = scene.getPrimitives().get(0); - expect(ellipsoidPrimitive.dynamicObject).toEqual(testObject); + expect(ellipsoidPrimitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); ellipsoidPrimitive = scene.getPrimitives().get(0); - expect(ellipsoidPrimitive.dynamicObject).toEqual(testObject2); + expect(ellipsoidPrimitive.id).toEqual(testObject2); }); }, 'WebGL'); diff --git a/Specs/DynamicScene/DynamicLabelVisualizerSpec.js b/Specs/DynamicScene/DynamicLabelVisualizerSpec.js index f69018e54673..9016ce5dcfa1 100644 --- a/Specs/DynamicScene/DynamicLabelVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicLabelVisualizerSpec.js @@ -259,7 +259,7 @@ defineSuite([ visualizer.update(time); expect(labelCollection.getLength()).toEqual(1); var l = labelCollection.get(0); - expect(l.dynamicObject).toEqual(testObject); + expect(l.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -285,12 +285,12 @@ defineSuite([ visualizer.update(time); expect(labelCollection.getLength()).toEqual(1); var l = labelCollection.get(0); - expect(l.dynamicObject).toEqual(testObject); + expect(l.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(labelCollection.getLength()).toEqual(1); l = labelCollection.get(0); - expect(l.dynamicObject).toEqual(testObject2); + expect(l.id).toEqual(testObject2); }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPathVisualizerSpec.js b/Specs/DynamicScene/DynamicPathVisualizerSpec.js index 8ca71e986606..520922b85915 100644 --- a/Specs/DynamicScene/DynamicPathVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPathVisualizerSpec.js @@ -207,7 +207,7 @@ defineSuite([ visualizer.update(updateTime); var polylineCollection = scene.getPrimitives().get(0); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -255,13 +255,13 @@ defineSuite([ var polylineCollection = scene.getPrimitives().get(0); expect(polylineCollection.getLength()).toEqual(1); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(updateTime); expect(scene.getPrimitives().getLength()).toEqual(1); polylineCollection = scene.getPrimitives().get(0); primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject2); + expect(primitive.id).toEqual(testObject2); }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPointVisualizerSpec.js b/Specs/DynamicScene/DynamicPointVisualizerSpec.js index 278e7ddce04e..f0f1f70316dd 100644 --- a/Specs/DynamicScene/DynamicPointVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPointVisualizerSpec.js @@ -201,7 +201,7 @@ defineSuite([ visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); var bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject); + expect(bb.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -225,12 +225,12 @@ defineSuite([ visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); var bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject); + expect(bb.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(billboardCollection.getLength()).toEqual(1); bb = billboardCollection.get(0); - expect(bb.dynamicObject).toEqual(testObject2); + expect(bb.id).toEqual(testObject2); }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js b/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js index 532bf80ef0b4..7fa8e314739c 100644 --- a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js @@ -174,7 +174,7 @@ defineSuite([ visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); var primitive = scene.getPrimitives().get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -197,12 +197,12 @@ defineSuite([ visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); var primitive = scene.getPrimitives().get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); primitive = scene.getPrimitives().get(0); - expect(primitive.dynamicObject).toEqual(testObject2); + expect(primitive.id).toEqual(testObject2); }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index f9e3f4e062ad..ee4e3dd1fa4e 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -194,7 +194,7 @@ defineSuite([ var polylineCollection = scene.getPrimitives().get(0); expect(polylineCollection.getLength()).toEqual(1); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -219,12 +219,12 @@ defineSuite([ var polylineCollection = scene.getPrimitives().get(0); expect(polylineCollection.getLength()).toEqual(1); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject2); + expect(primitive.id).toEqual(testObject2); }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPyramidVisualizerSpec.js b/Specs/DynamicScene/DynamicPyramidVisualizerSpec.js index 67570b49ab9c..24c447b28c41 100644 --- a/Specs/DynamicScene/DynamicPyramidVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPyramidVisualizerSpec.js @@ -185,7 +185,7 @@ defineSuite([ var time = new JulianDate(); visualizer.update(time); - expect(scene.getPrimitives().get(0).dynamicObject).toEqual(testObject); + expect(scene.getPrimitives().get(0).id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -210,12 +210,12 @@ defineSuite([ visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); var pyramidPrimitive = scene.getPrimitives().get(0); - expect(pyramidPrimitive.dynamicObject).toEqual(testObject); + expect(pyramidPrimitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); pyramidPrimitive = scene.getPrimitives().get(0); - expect(pyramidPrimitive.dynamicObject).toEqual(testObject2); + expect(pyramidPrimitive.id).toEqual(testObject2); }); }, 'WebGL'); diff --git a/Specs/DynamicScene/DynamicVectorVisualizerSpec.js b/Specs/DynamicScene/DynamicVectorVisualizerSpec.js index 453afc9f60d7..6d41f87bdf12 100644 --- a/Specs/DynamicScene/DynamicVectorVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicVectorVisualizerSpec.js @@ -207,7 +207,7 @@ defineSuite([ var polylineCollection = scene.getPrimitives().get(0); expect(polylineCollection.getLength()).toEqual(1); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); }); it('setDynamicObjectCollection removes old objects and add new ones.', function() { @@ -240,12 +240,12 @@ defineSuite([ var polylineCollection = scene.getPrimitives().get(0); expect(polylineCollection.getLength()).toEqual(1); var primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject); + expect(primitive.id).toEqual(testObject); visualizer.setDynamicObjectCollection(dynamicObjectCollection2); visualizer.update(time); expect(scene.getPrimitives().getLength()).toEqual(1); primitive = polylineCollection.get(0); - expect(primitive.dynamicObject).toEqual(testObject2); + expect(primitive.id).toEqual(testObject2); }); }, 'WebGL'); From 3ff6b18f18bc3824eef2c2fa8d2dd6b8d2a56fc6 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 5 Feb 2014 16:24:26 -0500 Subject: [PATCH 25/81] Ongoing DynamicScene geometry work 1. Add some basic specs for GeometryVisualizer. 2. Fix a bug in ColorMaterialProperty 3. Have GeometryVisualizer subscribe to an object and receive notification when it's geometry changes. 4. Misc cleanup. --- Source/Core/Map.js | 4 + Source/DynamicScene/ColorMaterialProperty.js | 4 +- Source/DynamicScene/EllipseGeometryUpdater.js | 83 ++++------ Source/DynamicScene/GeometryVisualizer.js | 65 +++++++- .../DynamicScene/StaticGeometryColorBatch.js | 3 +- .../StaticGeometryPerMaterialBatch.js | 100 +++++++----- Specs/DynamicScene/GeometryVisualizerSpec.js | 150 ++++++++++++++++++ 7 files changed, 312 insertions(+), 97 deletions(-) create mode 100644 Specs/DynamicScene/GeometryVisualizerSpec.js diff --git a/Source/Core/Map.js b/Source/Core/Map.js index 41b54ecc261e..fde63d834c14 100644 --- a/Source/Core/Map.js +++ b/Source/Core/Map.js @@ -19,6 +19,10 @@ define(['./defined', return this._hash[key]; }; + Map.prototype.getCount = function() { + return this._array.length; + }; + Map.prototype.getValues = function() { return this._array; }; diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 1f385cd6f972..9415bb628f3b 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -21,9 +21,9 @@ define(['../Core/Color', */ var ColorMaterialProperty = function(color) { this._definitionChanged = new Event(); - this._color = color; + this._color = undefined; this._colorSubscription = undefined; - this.color = new ConstantProperty(Color.WHITE); + this.color = new ConstantProperty(color); }; defineProperties(ColorMaterialProperty.prototype, { diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index da65a17b0621..3ec8f0577400 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -4,6 +4,7 @@ define(['../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', '../Core/EllipseGeometry', '../Core/EllipseOutlineGeometry', @@ -24,6 +25,7 @@ define(['../Core/Color', defaultValue, defined, defineProperties, + destroyObject, DeveloperError, EllipseGeometry, EllipseOutlineGeometry, @@ -40,7 +42,7 @@ define(['../Core/Color', Primitive) { "use strict"; - var defaultMaterial = new ColorMaterialProperty(new ConstantProperty(Color.WHITE)); + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); var defaultOutline = new ConstantProperty(false); @@ -68,7 +70,6 @@ define(['../Core/Color', this._id = dynamicObject.id; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); - this._ellipseSubscription = undefined; this._geometryType = GeometryBatchType.NONE; this._geometryChanged = new Event(); this._showProperty = undefined; @@ -77,7 +78,6 @@ define(['../Core/Color', this._hasConstantOutline = true; this._showOutlineProperty = undefined; this._outlineColorProperty = undefined; - this._outlineGeometryChanged = new Event(); this._options = new GeometryOptions(dynamicObject); this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); }; @@ -92,6 +92,11 @@ define(['../Core/Color', return this._id; } }, + dynamicObject :{ + get : function() { + return this._dynamicObject; + } + }, geometryType : { get : function() { return this._geometryType; @@ -126,20 +131,15 @@ define(['../Core/Color', get : function() { return this._outlineColorProperty; } - }, - outlineGeometryChanged : { - get : function() { - return this._outlineGeometryChanged; - } } }); - EllipseGeometryUpdater.prototype.isOutlineVisible = function(time){ + EllipseGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; - EllipseGeometryUpdater.prototype.isFilled = function(time){ + EllipseGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; @@ -186,40 +186,23 @@ define(['../Core/Color', }); }; - EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { - if (propertyName === 'ellipse') { - if (defined(oldValue)) { - this._ellipseSubscription(); - } - - this._ellipse = newValue; - - if (defined(newValue)) { - this._ellipseSubscription = newValue.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onEllipsePropertyChanged, this); - } - - this._update(); - } else if (propertyName === 'position') { - this._update(); - } + EllipseGeometryUpdater.prototype.destroy = function() { + this._dynamicObjectSubscription(); + destroyObject(this); }; - EllipseGeometryUpdater.prototype._onEllipsePropertyChanged = function(ellipse, propertyName, oldValue, newValue) { - this._update(); - }; + EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'ellipse')) { + return; + } - EllipseGeometryUpdater.prototype._update = function() { var ellipse = this._dynamicObject.ellipse; - var oldGeometryType = this._geometryType; if (!defined(ellipse)) { - if (this._geometryType !== GeometryBatchType.NONE) { - this._geometryType = GeometryBatchType.NONE; - this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); - } - if(this._outlineEnabled){ + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { this._outlineEnabled = false; - this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); } return; } @@ -244,13 +227,10 @@ define(['../Core/Color', var show = ellipse.show; if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { - if (this._geometryType !== GeometryBatchType.NONE) { - this._geometryType = GeometryBatchType.NONE; - this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); - } - if (this._outlineEnabled) { + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { this._outlineEnabled = false; - this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); } return; } @@ -281,7 +261,7 @@ define(['../Core/Color', defined(numberOfVerticalLines) && !numberOfVerticalLines.isConstant) { if (this._geometryType !== GeometryBatchType.DYNAMIC) { this._geometryType = GeometryBatchType.DYNAMIC; - this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); + this._geometryChanged.raiseEvent(this); } } else { var options = this._options; @@ -296,14 +276,8 @@ define(['../Core/Color', options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; - if (isFilled) { - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; - this._geometryChanged.raiseEvent(this._geometryType, oldGeometryType); - } - if (outlineEnabled) { - this._outlineEnabled = true; - this._outlineGeometryChanged.raiseEvent(this._outlineEnabled); - } + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryChanged.raiseEvent(this); } }; @@ -371,7 +345,7 @@ define(['../Core/Color', this._primitive = new Primitive({ geometryInstances : new GeometryInstance({ - id : this._dynamicObject, + id : dynamicObject, geometry : new EllipseGeometry(options) }), appearance : appearance, @@ -387,7 +361,7 @@ define(['../Core/Color', var outlineColor = defined(ellipse.outlineColor) ? ellipse.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ geometryInstances : new GeometryInstance({ - id : this._dynamicObject, + id : dynamicObject, geometry : new EllipseOutlineGeometry(options), attributes : { color : ColorGeometryInstanceAttribute.fromColor(outlineColor) @@ -416,6 +390,7 @@ define(['../Core/Color', if (defined(this._outlinePrimitive)) { this._primitives.remove(this._outlinePrimitive); } + destroyObject(this); }; return EllipseGeometryUpdater; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 321892bb3d6f..ee0be0f697e9 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -42,8 +42,10 @@ define(['../Core/defined', DynamicGeometryBatch.prototype.remove = function(updater) { var id = updater.id; var dynamicUpdater = this._dynamicUpdaters.get(id); - dynamicUpdater.destroy(); - this._dynamicUpdaters.remove(id); + if (defined(dynamicUpdater)) { + this._dynamicUpdaters.remove(id); + dynamicUpdater.destroy(); + } }; DynamicGeometryBatch.prototype.update = function(time) { @@ -86,6 +88,10 @@ define(['../Core/defined', * @see DynamicPyramidVisualizer */ var GeometryVisualizer = function(type, scene, dynamicObjectCollection) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + if (!defined(scene)) { throw new DeveloperError('scene is required.'); } @@ -98,6 +104,7 @@ define(['../Core/defined', this._dynamicObjectCollection = undefined; this._addedObjects = new DynamicObjectCollection(); this._removedObjects = new DynamicObjectCollection(); + this._changedObjects = new DynamicObjectCollection(); this._outlineBatch = new StaticOutlineGeometryBatch(primitives); @@ -106,6 +113,7 @@ define(['../Core/defined', this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); + this._subscriptions = new Map(); this._updaters = new Map(); this.setDynamicObjectCollection(dynamicObjectCollection); }; @@ -166,6 +174,8 @@ define(['../Core/defined', var added = addedObjects.getObjects(); var removedObjects = this._removedObjects; var removed = removedObjects.getObjects(); + var changedObjects = this._changedObjects; + var changed = changedObjects.getObjects(); var i; var g; @@ -174,6 +184,8 @@ define(['../Core/defined', var updater; var batch; var batches = this._batches; + var batchesLength = batches.length; + for (i = removed.length - 1; i > -1; i--) { dynamicObject = removed[i]; id = dynamicObject.id; @@ -187,6 +199,8 @@ define(['../Core/defined', updater.destroy(); this._updaters.remove(id); + this._subscriptions.get(id)(); + this._subscriptions.remove(id); } for (i = added.length - 1; i > -1; i--) { @@ -200,6 +214,28 @@ define(['../Core/defined', batch.add(time, updater); } + if (updater.outlineEnabled) { + this._outlineBatch.add(time, updater); + } + this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometyChanged, this)); + } + + for (i = changed.length - 1; i > -1; i--) { + dynamicObject = changed[i]; + id = dynamicObject.id; + updater = this._updaters.get(id); + for (g = 0; g < batchesLength; g++) { + if (batches[g].remove(updater)) { + break; + } + } + this._outlineBatch.remove(updater); + + batch = batches[updater.geometryType.value]; + if (defined(batch)) { + batch.add(time, updater); + } + if (updater.outlineEnabled) { this._outlineBatch.add(time, updater); } @@ -207,6 +243,7 @@ define(['../Core/defined', addedObjects.removeAll(); removedObjects.removeAll(); + changedObjects.removeAll(); for (g = 0; g < batches.length; g++) { batches[g].update(time); @@ -226,6 +263,12 @@ define(['../Core/defined', for (var g = 0; g < batchesLength; g++) { batches[g].removeAllPrimitives(); } + + var subscriptions = this._subscriptions.getValues(); + var len = subscriptions.length; + for (var i = 0; i < len; i++) { + subscriptions[i](); + } }; /** @@ -268,9 +311,22 @@ define(['../Core/defined', return destroyObject(this); }; + GeometryVisualizer._onGeometyChanged = function(updater) { + var removedObjects = this._removedObjects; + var changedObjects = this._changedObjects; + + var dynamicObject = updater.dynamicObject; + var id = dynamicObject.id; + + if (!defined(removedObjects.getById(id)) && !defined(this._changedObjects.getById(id))) { + this._changedObjects.add(dynamicObject); + } + }; + GeometryVisualizer.prototype._onCollectionChanged = function(dynamicObjectCollection, added, removed) { var addedObjects = this._addedObjects; var removedObjects = this._removedObjects; + var changedObjects = this._changedObjects; var i; var dynamicObject; @@ -278,12 +334,15 @@ define(['../Core/defined', dynamicObject = removed[i]; if (!addedObjects.remove(dynamicObject)) { removedObjects.add(dynamicObject); + changedObjects.remove(dynamicObject); } } for (i = added.length - 1; i > -1; i--) { dynamicObject = added[i]; - if (!removedObjects.remove(dynamicObject)) { + if (removedObjects.remove(dynamicObject)) { + changedObjects.add(dynamicObject); + } else { addedObjects.add(dynamicObject); } } diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index bc8e9420c6aa..fa5abce09c13 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -14,6 +14,8 @@ define(['../Core/Color', Primitive) { "use strict"; + var colorScratch = new Color(); + var Batch = function(primitives, translucent, appearanceType) { this.translucent = translucent; this.appearanceType = appearanceType; @@ -44,7 +46,6 @@ define(['../Core/Color', this.updatersWithAttributes.remove(id); }; - var colorScratch = new Color(); Batch.prototype.update = function(time) { var removedCount = 0; var primitive = this.primitive; diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 1c620e1a1996..3d79ebb5dbe9 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -15,21 +15,27 @@ define(['../Core/defined', "use strict"; var Batch = function(primitives, appearanceType, materialProperty) { - this._materialProperty = materialProperty; - this._updaters = new Map(); - this._createPrimitive = true; - this._primitive = undefined; - this._primitives = primitives; - this._geometry = new Map(); - this._material = Material.fromType('Color'); - this._appearanceType = appearanceType; - this._updatersWithAttributes = new Map(); - this._attributes = new Map(); + this.materialProperty = materialProperty; + this.updaters = new Map(); + this.createPrimitive = true; + this.primitive = undefined; + this.primitives = primitives; + this.geometry = new Map(); + this.material = Material.fromType('Color'); + this.appearanceType = appearanceType; + this.updatersWithAttributes = new Map(); + this.attributes = new Map(); + this.invalidated = false; + this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); + }; + + Batch.prototype.onMaterialChanged = function() { + this.invalidated = true; }; Batch.prototype.isMaterial = function(updater) { - var material = this._materialProperty; - var updaterMaterial = updater._materialProperty; + var material = this.materialProperty; + var updaterMaterial = updater.materialProperty; if (updaterMaterial === material) { return true; } @@ -41,27 +47,27 @@ define(['../Core/defined', Batch.prototype.add = function(time, updater) { var id = updater.id; - this._updaters.set(id, updater); - this._geometry.set(id, updater.createGeometryInstance(time)); + this.updaters.set(id, updater); + this.geometry.set(id, updater.createGeometryInstance(time)); if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) { - this._updatersWithAttributes.set(id, updater); + this.updatersWithAttributes.set(id, updater); } - this._createPrimitive = true; + this.createPrimitive = true; }; Batch.prototype.remove = function(updater) { var id = updater.id; - this._createPrimitive = this._updaters.remove(id); - this._geometry.remove(id); - this._updatersWithAttributes.remove(id); - return this._createPrimitive; + this.createPrimitive = this.updaters.remove(id); + this.geometry.remove(id); + this.updatersWithAttributes.remove(id); + return this.createPrimitive; }; Batch.prototype.update = function(time) { - var primitive = this._primitive; - var primitives = this._primitives; - var geometries = this._geometry.getValues(); - if (this._createPrimitive) { + var primitive = this.primitive; + var primitives = this.primitives; + var geometries = this.geometry.getValues(); + if (this.createPrimitive) { if (defined(primitive)) { primitives.remove(primitive); } @@ -69,31 +75,31 @@ define(['../Core/defined', primitive = new Primitive({ asynchronous : false, geometryInstances : geometries, - appearance : new this._appearanceType({ - material : MaterialProperty.getValue(time, this._materialProperty, this._material), + appearance : new this.appearanceType({ + material : MaterialProperty.getValue(time, this.materialProperty, this.material), faceForward : true, - translucent : this._material.isTranslucent(), + translucent : this.material.isTranslucent(), closed : true }) }); primitives.add(primitive); } - this._primitive = primitive; - this._createPrimitive = false; + this.primitive = primitive; + this.createPrimitive = false; } else { - this._primitive.appearance.material = MaterialProperty.getValue(time, this._materialProperty, this._material); + this.primitive.appearance.material = MaterialProperty.getValue(time, this.materialProperty, this.material); - var updatersWithAttributes = this._updatersWithAttributes.getValues(); + var updatersWithAttributes = this.updatersWithAttributes.getValues(); var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; - var instance = this._geometry.get(updater.id); + var instance = this.geometry.get(updater.id); - var attributes = this._attributes.get(instance.id.id); + var attributes = this.attributes.get(instance.id.id); if (!defined(attributes)) { attributes = primitive.getGeometryInstanceAttributes(instance.id); - this._attributes.set(instance.id.id, attributes); + this.attributes.set(instance.id.id, attributes); } if (!updater.hasConstantFill) { @@ -104,11 +110,12 @@ define(['../Core/defined', }; Batch.prototype.destroy = function(time) { - var primitive = this._primitive; - var primitives = this._primitives; + var primitive = this.primitive; + var primitives = this.primitives; if (defined(primitive)) { primitives.remove(primitive); } + this.removeMaterialSubscription(); }; var StaticGeometryPerMaterialBatch = function(primitives, appearanceType) { @@ -138,15 +145,34 @@ define(['../Core/defined', for (var i = length - 1; i >= 0; i--) { var item = items[i]; if (item.remove(updater)) { + if (item.updaters.getCount() === 0) { + items.splice(i, 1); + item.destroy(); + } break; } } }; StaticGeometryPerMaterialBatch.prototype.update = function(time) { + var i; var items = this._items; var length = items.length; - for (var i = 0; i < length; i++) { + + for (i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.invalidated) { + items.splice(i, 1); + var updaters = item.updaters.getValues(); + var updatersLength = updaters.length; + for (var h = 0; h < updatersLength; i++) { + this.add(updaters[h]); + } + item.destroy(); + } + } + + for (i = 0; i < length; i++) { items[i].update(time); } }; diff --git a/Specs/DynamicScene/GeometryVisualizerSpec.js b/Specs/DynamicScene/GeometryVisualizerSpec.js new file mode 100644 index 000000000000..15d4dedeabc2 --- /dev/null +++ b/Specs/DynamicScene/GeometryVisualizerSpec.js @@ -0,0 +1,150 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/GeometryVisualizer', + 'DynamicScene/DynamicEllipse', + 'DynamicScene/DynamicObjectCollection', + 'DynamicScene/EllipseGeometryUpdater', + 'DynamicScene/ColorMaterialProperty', + 'DynamicScene/ConstantProperty', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/DynamicObject', + 'DynamicScene/GridMaterialProperty', + 'Core/Cartesian3', + 'Core/Color', + 'Core/ColorGeometryInstanceAttribute', + 'Core/ShowGeometryInstanceAttribute', + 'Core/JulianDate', + 'Specs/createScene', + 'Specs/destroyScene' + ], function( + GeometryVisualizer, + DynamicEllipse, + DynamicObjectCollection, + EllipseGeometryUpdater, + ColorMaterialProperty, + ConstantProperty, + ConstantPositionProperty, + DynamicObject, + GridMaterialProperty, + Cartesian3, + Color, + ColorGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + JulianDate, + createScene, + destroyScene) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + var scene; + beforeAll(function() { + scene = createScene(); + }); + + afterAll(function() { + destroyScene(scene); + }); + + it('Constructor sets expected values', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + expect(visualizer.getScene()).toBe(scene); + expect(visualizer.getDynamicObjectCollection()).toBe(objects); + visualizer.update(time); + expect(scene.getPrimitives().getLength()).toBe(0); + expect(visualizer.isDestroyed()).toBe(false); + visualizer.destroy(); + expect(visualizer.isDestroyed()).toBe(true); + + visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene); + expect(visualizer.getDynamicObjectCollection()).toBeUndefined(); + visualizer.update(time); + expect(scene.getPrimitives().getLength()).toBe(0); + visualizer.destroy(); + }); + + it('Creates and removes static color primitives', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.getPrimitives().getLength()).toBe(1); + + var primitive = scene.getPrimitives().get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.getPrimitives().getLength()).toBe(0); + + visualizer.destroy(); + }); + + + it('Correctly handles changing appearance type', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + dynamicObject.ellipse.material = new GridMaterialProperty(); + + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + var primitive = scene.getPrimitives().get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + + visualizer.destroy(); + }); + + it('Constructor throws without type', function() { + var objects = new DynamicObjectCollection(); + expect(function() { + return new GeometryVisualizer(undefined, scene, objects); + }).toThrowDeveloperError(); + }); + + it('Constructor throws without scene', function() { + var objects = new DynamicObjectCollection(); + expect(function() { + return new GeometryVisualizer(EllipseGeometryUpdater, undefined, objects); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file From 54f1105842c0adf7509744a6357abe5b9ca4a112 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 6 Feb 2014 09:02:29 -0500 Subject: [PATCH 26/81] Fix static outlines --- Source/DynamicScene/EllipseGeometryUpdater.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 3ec8f0577400..dc9334121b73 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -242,6 +242,7 @@ define(['../Core/Color', this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); this._outlineColorProperty = defaultValue(ellipse.outlineColor, defaultOutlineColor); + this._outlineEnabled = outlineEnabled; var rotation = ellipse.rotation; var height = ellipse.height; From 1e87c1e063cc047d1790f1b0427c4493b918fdc5 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 6 Feb 2014 09:47:30 -0500 Subject: [PATCH 27/81] Remove DynamicPolygonVisualizer, replace with PolygonGeometryUpdater We're still using the `vertexPositions` property, but this will be removed in a later commit. --- Source/DynamicScene/CzmlDataSource.js | 1 + Source/DynamicScene/DataSourceDisplay.js | 6 +- .../DynamicBillboardVisualizer.js | 1 - .../DynamicConeVisualizerUsingCustomSensor.js | 1 - .../DynamicEllipsoidVisualizer.js | 1 - Source/DynamicScene/DynamicLabelVisualizer.js | 1 - Source/DynamicScene/DynamicPathVisualizer.js | 1 - Source/DynamicScene/DynamicPointVisualizer.js | 1 - Source/DynamicScene/DynamicPolygon.js | 13 +- .../DynamicScene/DynamicPolygonVisualizer.js | 256 ------------ .../DynamicScene/DynamicPolylineVisualizer.js | 1 - .../DynamicScene/DynamicPyramidVisualizer.js | 1 - .../DynamicScene/DynamicVectorVisualizer.js | 1 - Source/DynamicScene/EllipseGeometryUpdater.js | 2 +- Source/DynamicScene/GeometryVisualizer.js | 3 + Source/DynamicScene/PolygonGeometryUpdater.js | 382 ++++++++++++++++++ 16 files changed, 402 insertions(+), 270 deletions(-) delete mode 100644 Source/DynamicScene/DynamicPolygonVisualizer.js create mode 100644 Source/DynamicScene/PolygonGeometryUpdater.js diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 2883d9bb2778..95fabe502bdd 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -1155,6 +1155,7 @@ define(['../Core/Cartesian2', processPacketData(Boolean, polygon, 'fill', polygonData.fill, interval, sourceUri); processPacketData(Boolean, polygon, 'outline', polygonData.outline, interval, sourceUri); processPacketData(Color, polygon, 'outlineColor', polygonData.outlineColor, interval, sourceUri); + processPacketData(Boolean, polygon, 'perPositionHeight', polygonData.perPositionHeight, interval, sourceUri); } function processPolyline(dynamicObject, packet, dynamicObjectCollection, sourceUri) { diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index d1296205bcb5..aab70cdd0886 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -12,7 +12,7 @@ define([ './DynamicLabelVisualizer', './DynamicPathVisualizer', './DynamicPointVisualizer', - './DynamicPolygonVisualizer', + './PolygonGeometryUpdater', './DynamicPolylineVisualizer', './DynamicPyramidVisualizer', './DynamicVectorVisualizer', @@ -31,7 +31,7 @@ define([ DynamicLabelVisualizer, DynamicPathVisualizer, DynamicPointVisualizer, - DynamicPolygonVisualizer, + PolygonGeometryUpdater, DynamicPolylineVisualizer, DynamicPyramidVisualizer, DynamicVectorVisualizer, @@ -52,7 +52,7 @@ define([ }, function(scene) { return new DynamicPointVisualizer(scene); }, function(scene) { - return new DynamicPolygonVisualizer(scene); + return new GeometryVisualizer(PolygonGeometryUpdater, scene); }, function(scene) { return new DynamicPolylineVisualizer(scene); }, function(scene) { diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index 6aba6e90dc8b..fa389df5c471 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -61,7 +61,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer * diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index 4dda6b180655..7c409a6e6bab 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -97,7 +97,6 @@ define([ * @see DynamicConeVisualizer * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer * diff --git a/Source/DynamicScene/DynamicEllipsoidVisualizer.js b/Source/DynamicScene/DynamicEllipsoidVisualizer.js index d38f14abd3c5..c0a75a4f1b2b 100644 --- a/Source/DynamicScene/DynamicEllipsoidVisualizer.js +++ b/Source/DynamicScene/DynamicEllipsoidVisualizer.js @@ -49,7 +49,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer */ var DynamicEllipsoidVisualizer = function(scene, dynamicObjectCollection) { diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index 85cd371600f7..68f72649f846 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -44,7 +44,6 @@ define([ * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer * diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index ae33147d77dd..e1ee0ceb71b7 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -400,7 +400,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPyramidVisualizer * */ diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index c874e8bde8e5..35e592cd539b 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -38,7 +38,6 @@ define([ * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer * diff --git a/Source/DynamicScene/DynamicPolygon.js b/Source/DynamicScene/DynamicPolygon.js index 625db9fe9114..2dd5d5e28200 100644 --- a/Source/DynamicScene/DynamicPolygon.js +++ b/Source/DynamicScene/DynamicPolygon.js @@ -27,6 +27,8 @@ define(['../Core/defaultValue', this._extrudedHeight = undefined; this._granularity = undefined; this._stRotation = undefined; + this._perPositionHeight = undefined; + this._definitionChanged = new Event(); }; @@ -108,7 +110,14 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + + /** + * Gets or sets the Boolean {@link Property} specifying whether the polygon uses per-position heights. + * @memberof DynamicPolygon.prototype + * @type {Property} + */ + perPositionHeight : createDynamicPropertyDescriptor('perPositionHeight', '_perPositionHeight') }); /** @@ -131,6 +140,7 @@ define(['../Core/defaultValue', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; + result.perPositionHeight = this.perPositionHeight; return result; }; @@ -158,6 +168,7 @@ define(['../Core/defaultValue', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.perPositionHeight = defaultValue(this.perPositionHeight, source.perPositionHeight); }; return DynamicPolygon; diff --git a/Source/DynamicScene/DynamicPolygonVisualizer.js b/Source/DynamicScene/DynamicPolygonVisualizer.js deleted file mode 100644 index 3a9a388319b3..000000000000 --- a/Source/DynamicScene/DynamicPolygonVisualizer.js +++ /dev/null @@ -1,256 +0,0 @@ -/*global define*/ -define([ - '../Core/Cartesian3', - '../Core/defined', - '../Core/DeveloperError', - '../Core/destroyObject', - '../Scene/Polygon', - '../Scene/Material', - './MaterialProperty' - ], function( - Cartesian3, - defined, - DeveloperError, - destroyObject, - Polygon, - Material, - MaterialProperty) { - "use strict"; - - /** - * A DynamicObject visualizer which maps the DynamicPolygon instance - * in DynamicObject.polygon to a Polygon primitive. - * @alias DynamicPolygonVisualizer - * @constructor - * - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. - * - * @exception {DeveloperError} scene is required. - * - * @see DynamicPolygon - * @see Scene - * @see DynamicObject - * @see DynamicObjectCollection - * @see CompositeDynamicObjectCollection - * @see VisualizerCollection - * @see DynamicBillboardVisualizer - * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr - * @see DynamicLabelVisualizer - * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer - * @see DynamicPyramidVisualizer - * - */ - var DynamicPolygonVisualizer = function(scene, dynamicObjectCollection) { - //>>includeStart('debug', pragmas.debug); - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - //>>includeEnd('debug'); - - this._scene = scene; - this._unusedIndexes = []; - this._primitives = scene.getPrimitives(); - this._polygonCollection = []; - this._dynamicObjectCollection = undefined; - this.setDynamicObjectCollection(dynamicObjectCollection); - }; - - /** - * Returns the scene being used by this visualizer. - * - * @returns {Scene} The scene being used by this visualizer. - */ - DynamicPolygonVisualizer.prototype.getScene = function() { - return this._scene; - }; - - /** - * Gets the DynamicObjectCollection being visualized. - * - * @returns {DynamicObjectCollection} The DynamicObjectCollection being visualized. - */ - DynamicPolygonVisualizer.prototype.getDynamicObjectCollection = function() { - return this._dynamicObjectCollection; - }; - - /** - * Sets the DynamicObjectCollection to visualize. - * - * @param dynamicObjectCollection The DynamicObjectCollection to visualizer. - */ - DynamicPolygonVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { - var oldCollection = this._dynamicObjectCollection; - if (oldCollection !== dynamicObjectCollection) { - if (defined(oldCollection)) { - oldCollection.collectionChanged.removeEventListener(DynamicPolygonVisualizer.prototype._onObjectsRemoved, this); - this.removeAllPrimitives(); - } - this._dynamicObjectCollection = dynamicObjectCollection; - if (defined(dynamicObjectCollection)) { - dynamicObjectCollection.collectionChanged.addEventListener(DynamicPolygonVisualizer.prototype._onObjectsRemoved, this); - } - } - }; - - /** - * Updates all of the primitives created by this visualizer to match their - * DynamicObject counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * - * @exception {DeveloperError} time is required. - */ - DynamicPolygonVisualizer.prototype.update = function(time) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is requied.'); - } - //>>includeEnd('debug'); - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for ( var i = 0, len = dynamicObjects.length; i < len; i++) { - updateObject(this, time, dynamicObjects[i]); - } - } - }; - - /** - * Removes all primitives from the scene. - */ - DynamicPolygonVisualizer.prototype.removeAllPrimitives = function() { - var i, len; - for (i = 0, len = this._polygonCollection.length; i < len; i++) { - this._primitives.remove(this._polygonCollection[i]); - } - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for (i = dynamicObjects.length - 1; i > -1; i--) { - dynamicObjects[i]._polygonVisualizerIndex = undefined; - } - } - - this._unusedIndexes = []; - this._polygonCollection = []; - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - *

- * If this object was destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. - * - * @memberof DynamicPolygonVisualizer - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see DynamicPolygonVisualizer#destroy - */ - DynamicPolygonVisualizer.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - *

- * Once an object is destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (undefined) to the object as done in the example. - * - * @memberof DynamicPolygonVisualizer - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see DynamicPolygonVisualizer#isDestroyed - * - * @example - * visualizer = visualizer && visualizer.destroy(); - */ - DynamicPolygonVisualizer.prototype.destroy = function() { - this.setDynamicObjectCollection(undefined); - return destroyObject(this); - }; - - var cachedPosition = new Cartesian3(); - function updateObject(dynamicPolygonVisualizer, time, dynamicObject) { - var dynamicPolygon = dynamicObject._polygon; - if (!defined(dynamicPolygon)) { - return; - } - - var polygon; - var showProperty = dynamicPolygon._show; - var positionProperty = dynamicObject._position; - var vertexPositionsProperty = dynamicObject._vertexPositions; - var polygonVisualizerIndex = dynamicObject._polygonVisualizerIndex; - var show = dynamicObject.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); - if (!show || !defined(vertexPositionsProperty)) { - //Remove the existing primitive if we have one - if (defined(polygonVisualizerIndex)) { - polygon = dynamicPolygonVisualizer._polygonCollection[polygonVisualizerIndex]; - polygon.show = false; - dynamicObject._polygonVisualizerIndex = undefined; - dynamicPolygonVisualizer._unusedIndexes.push(polygonVisualizerIndex); - } - return; - } - - if (!defined(polygonVisualizerIndex)) { - var unusedIndexes = dynamicPolygonVisualizer._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - polygonVisualizerIndex = unusedIndexes.pop(); - polygon = dynamicPolygonVisualizer._polygonCollection[polygonVisualizerIndex]; - } else { - polygonVisualizerIndex = dynamicPolygonVisualizer._polygonCollection.length; - polygon = new Polygon(); - polygon.asynchronous = false; - dynamicPolygonVisualizer._polygonCollection.push(polygon); - dynamicPolygonVisualizer._primitives.add(polygon); - } - dynamicObject._polygonVisualizerIndex = polygonVisualizerIndex; - polygon.id = dynamicObject; - - // CZML_TODO Determine official defaults - polygon.material = Material.fromType(Material.ColorType); - } else { - polygon = dynamicPolygonVisualizer._polygonCollection[polygonVisualizerIndex]; - } - - polygon.show = true; - - var vertexPositions = vertexPositionsProperty.getValue(time); - if (polygon._visualizerPositions !== vertexPositions && // - defined(vertexPositions) && // - vertexPositions.length > 3) { - polygon.setPositions(vertexPositions); - polygon._visualizerPositions = vertexPositions; - } - - polygon.material = MaterialProperty.getValue(time, dynamicPolygon._material, polygon.material); - } - - DynamicPolygonVisualizer.prototype._onObjectsRemoved = function(dynamicObjectCollection, added, dynamicObjects) { - var thisPolygonCollection = this._polygonCollection; - var thisUnusedIndexes = this._unusedIndexes; - for ( var i = dynamicObjects.length - 1; i > -1; i--) { - var dynamicObject = dynamicObjects[i]; - var polygonVisualizerIndex = dynamicObject._polygonVisualizerIndex; - if (defined(polygonVisualizerIndex)) { - var polygon = thisPolygonCollection[polygonVisualizerIndex]; - polygon.show = false; - thisUnusedIndexes.push(polygonVisualizerIndex); - dynamicObject._polygonVisualizerIndex = undefined; - } - } - }; - - return DynamicPolygonVisualizer; -}); \ No newline at end of file diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index 2e0dbdb14954..ef57e5d73ef6 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -39,7 +39,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPyramidVisualizer * */ diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index 83341fbf4cff..6546843a8385 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -51,7 +51,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPolylineVisualizer * */ diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index cd12f5a697ef..cfb09b37af9c 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -39,7 +39,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolygonVisualizer * @see DynamicPyramidVisualizer * */ diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index dc9334121b73..bcc9e89093fe 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -242,7 +242,6 @@ define(['../Core/Color', this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); this._outlineColorProperty = defaultValue(ellipse.outlineColor, defaultOutlineColor); - this._outlineEnabled = outlineEnabled; var rotation = ellipse.rotation; var height = ellipse.height; @@ -277,6 +276,7 @@ define(['../Core/Color', options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineEnabled = outlineEnabled; this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; this._geometryChanged.raiseEvent(this); } diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index ee0be0f697e9..6ce6411927ec 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -60,6 +60,7 @@ define(['../Core/defined', for (var i = 0, len = geometries.length; i < len; i++) { geometries[i].destroy(); } + this._dynamicUpdaters.removeAll(); }; /** @@ -263,12 +264,14 @@ define(['../Core/defined', for (var g = 0; g < batchesLength; g++) { batches[g].removeAllPrimitives(); } + this._outlineBatch.removeAllPrimitives(); var subscriptions = this._subscriptions.getValues(); var len = subscriptions.length; for (var i = 0; i < len; i++) { subscriptions[i](); } + this._subscriptions.removeAll(); }; /** diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js new file mode 100644 index 000000000000..48c9fe077d7f --- /dev/null +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -0,0 +1,382 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/PolygonGeometry', + '../Core/PolygonOutlineGeometry', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/ShowGeometryInstanceAttribute', + '../DynamicScene/ColorMaterialProperty', + '../DynamicScene/ConstantProperty', + '../DynamicScene/GeometryBatchType', + '../DynamicScene/MaterialProperty', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + PolygonGeometry, + PolygonOutlineGeometry, + Event, + GeometryInstance, + Iso8601, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + GeometryBatchType, + MaterialProperty, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive) { + "use strict"; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + + var GeometryOptions = function(dynamicObject) { + this.id = dynamicObject; + this.vertexFormat = undefined; + this.polygonHierarchy = { + positions : undefined + }; + this.perPositionHeight = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + this.stRotation = undefined; + }; + + var PolygonGeometryUpdater = function(dynamicObject) { + if (!defined(dynamicObject)) { + throw new DeveloperError('dynamicObject is required'); + } + + this._id = dynamicObject.id; + this._dynamicObject = dynamicObject; + this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._outlineEnabled = false; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._options = new GeometryOptions(dynamicObject); + this._onDynamicObjectPropertyChanged(dynamicObject, 'polygon', dynamicObject.polygon, undefined); + }; + + PolygonGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; + + PolygonGeometryUpdater.MaterialAppearanceType = MaterialAppearance; + + defineProperties(PolygonGeometryUpdater.prototype, { + id : { + get : function() { + return this._id; + } + }, + dynamicObject :{ + get : function() { + return this._dynamicObject; + } + }, + geometryType : { + get : function() { + return this._geometryType; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } + }, + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + hasConstantFill : { + get : function() { + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; + } + }, + hasConstantOutline : { + get : function() { + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; + } + }, + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + } + }); + + PolygonGeometryUpdater.prototype.isOutlineVisible = function(time) { + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + PolygonGeometryUpdater.prototype.isFilled = function(time) { + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; + + PolygonGeometryUpdater.prototype.createGeometryInstance = function(time) { + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + if (this._geometryType === GeometryBatchType.COLOR) { + var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + color : color + }; + } else { + attributes = { + show : show + }; + } + + return new GeometryInstance({ + id : dynamicObject, + geometry : new PolygonGeometry(this._options), + attributes : attributes + }); + }; + + PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + + return new GeometryInstance({ + id : dynamicObject, + geometry : new PolygonOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) + } + }); + }; + + PolygonGeometryUpdater.prototype.destroy = function() { + this._dynamicObjectSubscription(); + destroyObject(this); + }; + + PolygonGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'vertexPositions' || propertyName === 'polygon')) { + return; + } + + var polygon = this._dynamicObject.polygon; + + if (!defined(polygon)) { + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + this._outlineEnabled = false; + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = polygon.fill; + var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = polygon.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!isFilled && !outlineEnabled) { + return; + } + + var vertexPositions = this._dynamicObject.vertexPositions; + + var show = polygon.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(vertexPositions))) { + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + this._outlineEnabled = false; + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(polygon.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(polygon.outline, defaultOutline); + this._outlineColorProperty = defaultValue(polygon.outlineColor, defaultOutlineColor); + + var perPositionHeight = polygon.perPositionHeight; + var height = polygon.height; + var extrudedHeight = polygon.extrudedHeight; + var granularity = polygon.granularity; + var stRotation = polygon.stRotation; + + if (!vertexPositions.isConstant || // + defined(perPositionHeight) && !perPositionHeight.isConstant || // + defined(height) && !height.isConstant || // + defined(extrudedHeight) && !extrudedHeight.isConstant || // + defined(granularity) && !granularity.isConstant || // + defined(stRotation) && !stRotation.isConstant) { + if (this._geometryType !== GeometryBatchType.DYNAMIC) { + this._geometryType = GeometryBatchType.DYNAMIC; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.VERTEX_FORMAT; + options.polygonHierarchy.positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.polygonHierarchy.positions); + options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + + this._outlineEnabled = outlineEnabled; + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryChanged.raiseEvent(this); + } + }; + + PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + return new DynamicGeometryBatchItem(primitives, this); + }; + + var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._dynamicObject); + }; + + DynamicGeometryBatchItem.prototype.update = function(time) { + var geometryUpdater = this._geometryUpdater; + + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); + } + + var dynamicObject = geometryUpdater._dynamicObject; + var show = dynamicObject.show; + + if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + return; + } + + var options = this._options; + var polygon = dynamicObject.polygon; + + var vertexPositions = dynamicObject.vertexPositions; + var perPositionHeight = polygon.perPositionHeight; + var height = polygon.height; + var extrudedHeight = polygon.extrudedHeight; + var granularity = polygon.granularity; + var stRotation = polygon.stRotation; + + options.polygonHierarchy.positions = vertexPositions.getValue(time, options.polygonHierarchy.positions); + options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(time) : undefined; + options.height = defined(height) ? height.getValue(time, options) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(time, options) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(time) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(time) : undefined; + + if (!defined(polygon.fill) || polygon.fill.getValue(time)) { + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + var material = this._material; + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : dynamicObject, + geometry : new PolygonGeometry(options) + }), + appearance : appearance, + asynchronous : false + }); + this._primitives.add(this._primitive); + } + + if (defined(polygon.outline) && polygon.outline.getValue(time)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = defined(polygon.outlineColor) ? polygon.outlineColor.getValue(time) : Color.BLACK; + this._outlinePrimitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : dynamicObject, + geometry : new PolygonOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : false, + renderState : { + depthTest : { + enabled : true + } + } + }), + asynchronous : false + }); + this._primitives.add(this._outlinePrimitive); + } + }; + + DynamicGeometryBatchItem.prototype.destroy = function() { + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); + } + destroyObject(this); + }; + + return PolygonGeometryUpdater; +}); \ No newline at end of file From 7c31f795737a92610d186f4ba64d2e9dbdf6d861 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 6 Feb 2014 09:51:16 -0500 Subject: [PATCH 28/81] Fix specs --- Source/DynamicScene/ColorMaterialProperty.js | 4 +- .../DynamicPolygonVisualizerSpec.js | 208 ------------------ 2 files changed, 3 insertions(+), 209 deletions(-) delete mode 100644 Specs/DynamicScene/DynamicPolygonVisualizerSpec.js diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 9415bb628f3b..5040b37a82d7 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -1,5 +1,6 @@ /*global define*/ define(['../Core/Color', + '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/Event', @@ -7,6 +8,7 @@ define(['../Core/Color', './Property' ], function( Color, + defaultValue, defined, defineProperties, Event, @@ -23,7 +25,7 @@ define(['../Core/Color', this._definitionChanged = new Event(); this._color = undefined; this._colorSubscription = undefined; - this.color = new ConstantProperty(color); + this.color = new ConstantProperty(defaultValue(color, Color.WHITE)); }; defineProperties(ColorMaterialProperty.prototype, { diff --git a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js b/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js deleted file mode 100644 index 7fa8e314739c..000000000000 --- a/Specs/DynamicScene/DynamicPolygonVisualizerSpec.js +++ /dev/null @@ -1,208 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/DynamicPolygonVisualizer', - 'Specs/createScene', - 'Specs/destroyScene', - 'DynamicScene/ConstantProperty', - 'Core/Cartesian3', - 'Core/Color', - 'Core/JulianDate', - 'DynamicScene/DynamicEllipse', - 'DynamicScene/DynamicPolygon', - 'DynamicScene/DynamicObjectCollection', - 'DynamicScene/ColorMaterialProperty' - ], function( - DynamicPolygonVisualizer, - createScene, - destroyScene, - ConstantProperty, - Cartesian3, - Color, - JulianDate, - DynamicEllipse, - DynamicPolygon, - DynamicObjectCollection, - ColorMaterialProperty) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var scene; - var visualizer; - - beforeAll(function() { - scene = createScene(); - }); - - afterAll(function() { - destroyScene(scene); - }); - - afterEach(function() { - visualizer = visualizer && visualizer.destroy(); - }); - - it('constructor throws if no scene is passed.', function() { - expect(function() { - return new DynamicPolygonVisualizer(); - }).toThrowDeveloperError(); - }); - - it('constructor sets expected parameters and adds collection to scene.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - expect(visualizer.getScene()).toEqual(scene); - expect(visualizer.getDynamicObjectCollection()).toEqual(dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('update throws if no time specified.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - expect(function() { - visualizer.update(); - }).toThrowDeveloperError(); - }); - - it('update does nothing if no dynamicObjectCollection.', function() { - visualizer = new DynamicPolygonVisualizer(scene); - visualizer.update(new JulianDate()); - }); - - it('isDestroy returns false until destroyed.', function() { - visualizer = new DynamicPolygonVisualizer(scene); - expect(visualizer.isDestroyed()).toEqual(false); - visualizer.destroy(); - expect(visualizer.isDestroyed()).toEqual(true); - visualizer = undefined; - }); - - it('object with no polygon does not create one.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 910111)]); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('object with no vertexPosition does not create a polygon.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('A DynamicPolygon causes a primtive to be created and updated.', function() { - var time = new JulianDate(); - - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - expect(scene.getPrimitives().getLength()).toEqual(0); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 910111)]); - - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - polygon.material = new ColorMaterialProperty(); - - visualizer.update(time); - - expect(scene.getPrimitives().getLength()).toEqual(1); - - var primitive = scene.getPrimitives().get(0); - - visualizer.update(time); - expect(primitive.show).toEqual(testObject.polygon.show.getValue(time)); - expect(primitive.material.uniforms).toEqual(testObject.polygon.material.getValue(time)); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112), new Cartesian3(1234, 5678, 910111)]); - polygon.material = new ColorMaterialProperty(); - - visualizer.update(time); - expect(primitive.show).toEqual(testObject.polygon.show.getValue(time)); - expect(primitive.material.uniforms).toEqual(testObject.polygon.material.getValue(time)); - - polygon.show = new ConstantProperty(false); - visualizer.update(time); - expect(primitive.show).toEqual(testObject.polygon.show.getValue(time)); - }); - - it('clear hides primitives.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(0); - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - var time = new JulianDate(); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112), new Cartesian3(1234, 5678, 910111)]); - var polygon = testObject.polygon = new DynamicPolygon(); - polygon.show = new ConstantProperty(true); - visualizer.update(time); - - expect(scene.getPrimitives().getLength()).toEqual(1); - var primitive = scene.getPrimitives().get(0); - - visualizer.update(time); - //Clearing won't actually remove the primitive because of the - //internal cache used by the visualizer, instead it just hides it. - dynamicObjectCollection.removeAll(); - expect(primitive.show).toEqual(false); - }); - - it('Visualizer sets dynamicObject property.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - expect(scene.getPrimitives().getLength()).toEqual(0); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - - var time = new JulianDate(); - var polygon = testObject.polygon = new DynamicPolygon(); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112), new Cartesian3(1234, 5678, 910111)]); - polygon.show = new ConstantProperty(true); - - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - var primitive = scene.getPrimitives().get(0); - expect(primitive.id).toEqual(testObject); - }); - - it('setDynamicObjectCollection removes old objects and add new ones.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112), new Cartesian3(1234, 5678, 910111)]); - testObject.polygon = new DynamicPolygon(); - testObject.polygon.show = new ConstantProperty(true); - - var dynamicObjectCollection2 = new DynamicObjectCollection(); - var testObject2 = dynamicObjectCollection2.getOrCreateObject('test2'); - testObject2.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 910111)]); - testObject2.polygon = new DynamicPolygon(); - testObject2.polygon.show = new ConstantProperty(true); - - visualizer = new DynamicPolygonVisualizer(scene, dynamicObjectCollection); - - var time = new JulianDate(); - - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - var primitive = scene.getPrimitives().get(0); - expect(primitive.id).toEqual(testObject); - - visualizer.setDynamicObjectCollection(dynamicObjectCollection2); - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - primitive = scene.getPrimitives().get(0); - expect(primitive.id).toEqual(testObject2); - }); -}, 'WebGL'); \ No newline at end of file From 9cf4bf8dbade27ff4c9c003b150cf3ae3e946e53 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 6 Feb 2014 10:49:03 -0500 Subject: [PATCH 29/81] Replace DynamicEllipsoidVisualizer with EllipsoidGeometryUpdater --- Source/DynamicScene/DataSourceDisplay.js | 6 +- Source/DynamicScene/DynamicEllipsoid.js | 32 +- .../DynamicEllipsoidVisualizer.js | 284 ------------- .../DynamicScene/EllipsoidGeometryUpdater.js | 393 ++++++++++++++++++ Specs/DynamicScene/DynamicEllipsoidSpec.js | 24 ++ .../DynamicEllipsoidVisualizerSpec.js | 227 ---------- 6 files changed, 451 insertions(+), 515 deletions(-) delete mode 100644 Source/DynamicScene/DynamicEllipsoidVisualizer.js create mode 100644 Source/DynamicScene/EllipsoidGeometryUpdater.js delete mode 100644 Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index aab70cdd0886..64b220a7ae5d 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -7,7 +7,7 @@ define([ '../Core/EventHelper', './DynamicBillboardVisualizer', './EllipseGeometryUpdater', - './DynamicEllipsoidVisualizer', + './EllipsoidGeometryUpdater', './DynamicConeVisualizerUsingCustomSensor', './DynamicLabelVisualizer', './DynamicPathVisualizer', @@ -26,7 +26,7 @@ define([ EventHelper, DynamicBillboardVisualizer, EllipseGeometryUpdater, - DynamicEllipsoidVisualizer, + EllipsoidGeometryUpdater, DynamicConeVisualizerUsingCustomSensor, DynamicLabelVisualizer, DynamicPathVisualizer, @@ -44,7 +44,7 @@ define([ }, function(scene) { return new GeometryVisualizer(EllipseGeometryUpdater, scene); }, function(scene) { - return new DynamicEllipsoidVisualizer(scene); + return new GeometryVisualizer(EllipsoidGeometryUpdater, scene); }, function(scene) { return new DynamicConeVisualizerUsingCustomSensor(scene); }, function(scene) { diff --git a/Source/DynamicScene/DynamicEllipsoid.js b/Source/DynamicScene/DynamicEllipsoid.js index da7106e1a8f3..f16a55e39d77 100644 --- a/Source/DynamicScene/DynamicEllipsoid.js +++ b/Source/DynamicScene/DynamicEllipsoid.js @@ -24,6 +24,9 @@ define(['../Core/defaultValue', this._show = undefined; this._radii = undefined; this._material = undefined; + this._stackPartitions = undefined; + this._slicePartitions = undefined; + this._subdivisions = undefined; this._definitionChanged = new Event(); }; @@ -79,8 +82,28 @@ define(['../Core/defaultValue', * @memberof DynamicEllipsoid.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor') + outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + /** + * Gets or sets the Number {@link Property} specifying the number of times to partition the ellipsoid into stacks. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + stackPartitions : createDynamicPropertyDescriptor('stackPartitions', '_stackPartitions'), + + /** + * Gets or sets the Number {@link Property} specifying the number of times to partition the ellipsoid into radial slices. + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + slicePartitions : createDynamicPropertyDescriptor('slicePartitions', '_slicePartitions'), + + /** + * Gets or sets the Number {@link Property} specifying the number of points per line, determining the granularity of the curvature . + * @memberof DynamicEllipsoid.prototype + * @type {Property} + */ + subdivisions : createDynamicPropertyDescriptor('subdivisions', '_subdivisions') }); /** @@ -100,6 +123,10 @@ define(['../Core/defaultValue', result.fill = this.fill; result.outline = this.outline; result.outlineColor = this.outlineColor; + result.stackPartitions = this.stackPartitions; + result.slicePartitions = this.slicePartitions; + result.subdivisions = this.subdivisions; + return result; }; @@ -124,6 +151,9 @@ define(['../Core/defaultValue', this.fill = defaultValue(this.fill, source.fill); this.outline = defaultValue(this.outline, source.outline); this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.stackPartitions = defaultValue(this.stackPartitions, source.stackPartitions); + this.slicePartitions = defaultValue(this.slicePartitions, source.slicePartitions); + this.subdivisions = defaultValue(this.subdivisions, source.subdivisions); }; return DynamicEllipsoid; diff --git a/Source/DynamicScene/DynamicEllipsoidVisualizer.js b/Source/DynamicScene/DynamicEllipsoidVisualizer.js deleted file mode 100644 index c0a75a4f1b2b..000000000000 --- a/Source/DynamicScene/DynamicEllipsoidVisualizer.js +++ /dev/null @@ -1,284 +0,0 @@ -/*global define*/ -define([ - '../Core/defaultValue', - '../Core/defined', - '../Core/DeveloperError', - '../Core/destroyObject', - '../Core/Cartesian3', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/Quaternion', - '../Scene/EllipsoidPrimitive', - '../Scene/Material', - './MaterialProperty' - ], function( - defaultValue, - defined, - DeveloperError, - destroyObject, - Cartesian3, - Matrix3, - Matrix4, - Quaternion, - EllipsoidPrimitive, - Material, - MaterialProperty) { - "use strict"; - - var matrix3Scratch = new Matrix3(); - - /** - * A DynamicObject visualizer which maps the DynamicEllipsoid instance - * in DynamicObject.ellipsoid to a Ellipsoid primitive. - * @alias DynamicEllipsoidVisualizer - * @constructor - * - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. - * - * @exception {DeveloperError} scene is required. - * - * @see DynamicEllipsoid - * @see Scene - * @see DynamicObject - * @see DynamicObjectCollection - * @see CompositeDynamicObjectCollection - * @see VisualizerCollection - * @see DynamicBillboardVisualizer - * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr - * @see DynamicLabelVisualizer - * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer - */ - var DynamicEllipsoidVisualizer = function(scene, dynamicObjectCollection) { - //>>includeStart('debug', pragmas.debug); - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - //>>includeEnd('debug'); - - this._scene = scene; - this._unusedIndexes = []; - this._primitives = scene.getPrimitives(); - this._ellipsoidCollection = []; - this._dynamicObjectCollection = undefined; - this.setDynamicObjectCollection(dynamicObjectCollection); - }; - - /** - * Returns the scene being used by this visualizer. - * - * @returns {Scene} The scene being used by this visualizer. - */ - DynamicEllipsoidVisualizer.prototype.getScene = function() { - return this._scene; - }; - - /** - * Gets the DynamicObjectCollection being visualized. - * - * @returns {DynamicObjectCollection} The DynamicObjectCollection being visualized. - */ - DynamicEllipsoidVisualizer.prototype.getDynamicObjectCollection = function() { - return this._dynamicObjectCollection; - }; - - /** - * Sets the DynamicObjectCollection to visualize. - * - * @param dynamicObjectCollection The DynamicObjectCollection to visualizer. - */ - DynamicEllipsoidVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { - var oldCollection = this._dynamicObjectCollection; - if (oldCollection !== dynamicObjectCollection) { - if (defined(oldCollection)) { - oldCollection.collectionChanged.removeEventListener(DynamicEllipsoidVisualizer.prototype._onObjectsRemoved, this); - this.removeAllPrimitives(); - } - this._dynamicObjectCollection = dynamicObjectCollection; - if (defined(dynamicObjectCollection)) { - dynamicObjectCollection.collectionChanged.addEventListener(DynamicEllipsoidVisualizer.prototype._onObjectsRemoved, this); - } - } - }; - - /** - * Updates all of the primitives created by this visualizer to match their - * DynamicObject counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * - * @exception {DeveloperError} time is required. - */ - DynamicEllipsoidVisualizer.prototype.update = function(time) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is requied.'); - } - //>>includeEnd('debug'); - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for ( var i = 0, len = dynamicObjects.length; i < len; i++) { - updateObject(this, time, dynamicObjects[i]); - } - } - }; - - /** - * Removes all primitives from the scene. - */ - DynamicEllipsoidVisualizer.prototype.removeAllPrimitives = function() { - var i, len; - for (i = 0, len = this._ellipsoidCollection.length; i < len; i++) { - this._primitives.remove(this._ellipsoidCollection[i]); - } - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for (i = dynamicObjects.length - 1; i > -1; i--) { - dynamicObjects[i]._ellipsoidVisualizerIndex = undefined; - } - } - - this._unusedIndexes = []; - this._ellipsoidCollection = []; - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - *

- * If this object was destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. - * - * @memberof DynamicEllipsoidVisualizer - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see DynamicEllipsoidVisualizer#destroy - */ - DynamicEllipsoidVisualizer.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - *

- * Once an object is destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (undefined) to the object as done in the example. - * - * @memberof DynamicEllipsoidVisualizer - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see DynamicEllipsoidVisualizer#isDestroyed - * - * @example - * visualizer = visualizer && visualizer.destroy(); - */ - DynamicEllipsoidVisualizer.prototype.destroy = function() { - this.setDynamicObjectCollection(undefined); - return destroyObject(this); - }; - - var position; - var orientation; - function updateObject(dynamicEllipsoidVisualizer, time, dynamicObject) { - var dynamicEllipsoid = dynamicObject._ellipsoid; - if (!defined(dynamicEllipsoid)) { - return; - } - - var radiiProperty = dynamicEllipsoid._radii; - if (!defined(radiiProperty)) { - return; - } - - var positionProperty = dynamicObject._position; - if (!defined(positionProperty)) { - return; - } - - var orientationProperty = dynamicObject._orientation; - if (!defined(orientationProperty)) { - return; - } - - var ellipsoid; - var showProperty = dynamicEllipsoid._show; - var ellipsoidVisualizerIndex = dynamicObject._ellipsoidVisualizerIndex; - var show = dynamicObject.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); - - if (!show) { - //don't bother creating or updating anything else - if (defined(ellipsoidVisualizerIndex)) { - ellipsoid = dynamicEllipsoidVisualizer._ellipsoidCollection[ellipsoidVisualizerIndex]; - ellipsoid.show = false; - dynamicObject._ellipsoidVisualizerIndex = undefined; - dynamicEllipsoidVisualizer._unusedIndexes.push(ellipsoidVisualizerIndex); - } - return; - } - - if (!defined(ellipsoidVisualizerIndex)) { - var unusedIndexes = dynamicEllipsoidVisualizer._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - ellipsoidVisualizerIndex = unusedIndexes.pop(); - ellipsoid = dynamicEllipsoidVisualizer._ellipsoidCollection[ellipsoidVisualizerIndex]; - } else { - ellipsoidVisualizerIndex = dynamicEllipsoidVisualizer._ellipsoidCollection.length; - ellipsoid = new EllipsoidPrimitive(); - - dynamicEllipsoidVisualizer._ellipsoidCollection.push(ellipsoid); - dynamicEllipsoidVisualizer._primitives.add(ellipsoid); - } - dynamicObject._ellipsoidVisualizerIndex = ellipsoidVisualizerIndex; - ellipsoid.id = dynamicObject; - - ellipsoid.material = Material.fromType(Material.ColorType); - } else { - ellipsoid = dynamicEllipsoidVisualizer._ellipsoidCollection[ellipsoidVisualizerIndex]; - } - - ellipsoid.show = true; - - ellipsoid.radii = radiiProperty.getValue(time, ellipsoid.radii); - - position = defaultValue(positionProperty.getValue(time, position), ellipsoid._visualizerPosition); - orientation = defaultValue(orientationProperty.getValue(time, orientation), ellipsoid._visualizerOrientation); - - if (defined(position) && - defined(orientation) && - (!Cartesian3.equals(position, ellipsoid._visualizerPosition) || - !Quaternion.equals(orientation, ellipsoid._visualizerOrientation))) { - Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, ellipsoid.modelMatrix); - ellipsoid._visualizerPosition = Cartesian3.clone(position, ellipsoid._visualizerPosition); - ellipsoid._visualizerOrientation = Quaternion.clone(orientation, ellipsoid._visualizerOrientation); - } - - ellipsoid.material = MaterialProperty.getValue(time, dynamicEllipsoid._material, ellipsoid.material); - } - - DynamicEllipsoidVisualizer.prototype._onObjectsRemoved = function(dynamicObjectCollection, added, dynamicObjects) { - var thisEllipsoidCollection = this._ellipsoidCollection; - var thisUnusedIndexes = this._unusedIndexes; - for ( var i = dynamicObjects.length - 1; i > -1; i--) { - var dynamicObject = dynamicObjects[i]; - var ellipsoidVisualizerIndex = dynamicObject._ellipsoidVisualizerIndex; - if (defined(ellipsoidVisualizerIndex)) { - var ellipsoid = thisEllipsoidCollection[ellipsoidVisualizerIndex]; - ellipsoid.show = false; - thisUnusedIndexes.push(ellipsoidVisualizerIndex); - dynamicObject._ellipsoidVisualizerIndex = undefined; - } - } - }; - - return DynamicEllipsoidVisualizer; -}); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js new file mode 100644 index 000000000000..eebe4ccca4cf --- /dev/null +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -0,0 +1,393 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/EllipsoidGeometry', + '../Core/EllipsoidOutlineGeometry', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/ShowGeometryInstanceAttribute', + '../DynamicScene/ColorMaterialProperty', + '../DynamicScene/ConstantProperty', + '../DynamicScene/GeometryBatchType', + '../DynamicScene/MaterialProperty', + '../Scene/EllipsoidSurfaceAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + EllipsoidGeometry, + EllipsoidOutlineGeometry, + Event, + GeometryInstance, + Iso8601, + Matrix3, + Matrix4, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + GeometryBatchType, + MaterialProperty, + EllipsoidSurfaceAppearance, + PerInstanceColorAppearance, + Primitive) { + "use strict"; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + + var positionScratch; + var orientationScratch; + + var GeometryOptions = function(dynamicObject) { + this.id = dynamicObject; + this.vertexFormat = undefined; + this.radii = undefined; + this.stackPartitions = undefined; + this.slicePartitions = undefined; + this.subdivisions = undefined; + }; + + var EllipsoidGeometryUpdater = function(dynamicObject) { + if (!defined(dynamicObject)) { + throw new DeveloperError('dynamicObject is required'); + } + + this._id = dynamicObject.id; + this._dynamicObject = dynamicObject; + this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._outlineEnabled = false; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._options = new GeometryOptions(dynamicObject); + this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipsoid', dynamicObject.ellipsoid, undefined); + this._modelMatrix = undefined; + }; + + EllipsoidGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; + + EllipsoidGeometryUpdater.MaterialAppearanceType = EllipsoidSurfaceAppearance; + + defineProperties(EllipsoidGeometryUpdater.prototype, { + id : { + get : function() { + return this._id; + } + }, + dynamicObject :{ + get : function() { + return this._dynamicObject; + } + }, + geometryType : { + get : function() { + return this._geometryType; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } + }, + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + hasConstantFill : { + get : function() { + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; + } + }, + hasConstantOutline : { + get : function() { + return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; + } + }, + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + } + }); + + EllipsoidGeometryUpdater.prototype.isOutlineVisible = function(time) { + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + EllipsoidGeometryUpdater.prototype.isFilled = function(time) { + var dynamicObject = this._dynamicObject; + return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; + + EllipsoidGeometryUpdater.prototype.createGeometryInstance = function(time) { + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + if (this._geometryType === GeometryBatchType.COLOR) { + var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + color : color + }; + } else { + attributes = { + show : show + }; + } + + return new GeometryInstance({ + id : dynamicObject, + geometry : new EllipsoidGeometry(this._options), + attributes : attributes, + modelMatrix : this._modelMatrix + }); + }; + + EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + + return new GeometryInstance({ + id : dynamicObject, + geometry : new EllipsoidOutlineGeometry(this._options), + modelMatrix : this._modelMatrix, + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) + } + }); + }; + + EllipsoidGeometryUpdater.prototype.destroy = function() { + this._dynamicObjectSubscription(); + destroyObject(this); + }; + + EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'ellipsoid')) { + return; + } + + var ellipsoid = this._dynamicObject.ellipsoid; + + if (!defined(ellipsoid)) { + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + this._outlineEnabled = false; + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = ellipsoid.fill; + var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = ellipsoid.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!isFilled && !outlineEnabled) { + return; + } + + var position = this._dynamicObject.position; + var orientation = this._dynamicObject.orientation; + var radii = ellipsoid.radii; + + var show = ellipsoid.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(position) || !defined(orientation) || !defined(radii))) { + if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + this._outlineEnabled = false; + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(ellipsoid.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(ellipsoid.outline, defaultOutline); + this._outlineColorProperty = defaultValue(ellipsoid.outlineColor, defaultOutlineColor); + + var stackPartitions = ellipsoid.stackPartitions; + var slicePartitions = ellipsoid.slicePartitions; + var subdivisions = ellipsoid.subdivisions; + + if (!position.isConstant || // + !orientation.isConstant || // + !radii.isConstant || // + defined(stackPartitions) && !stackPartitions.isConstant || // + defined(slicePartitions) && !slicePartitions.isConstant || // + defined(subdivisions) && !subdivisions.isConstant) { + if (this._geometryType !== GeometryBatchType.DYNAMIC) { + this._geometryType = GeometryBatchType.DYNAMIC; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : EllipsoidSurfaceAppearance.VERTEX_FORMAT; + options.radii = radii.getValue(Iso8601.MINIMUM_VALUE, options.radii); + options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.subdivisions = defined(subdivisions) ? subdivisions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + + positionScratch = position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); + orientationScratch = orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); + this._modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch); + this._outlineEnabled = outlineEnabled; + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryChanged.raiseEvent(this); + } + }; + + EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + return new DynamicGeometryBatchItem(primitives, this); + }; + + var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._dynamicObject); + }; + + DynamicGeometryBatchItem.prototype.update = function(time) { + var geometryUpdater = this._geometryUpdater; + + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); + } + + var dynamicObject = geometryUpdater._dynamicObject; + var show = dynamicObject.show; + + if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + return; + } + + var options = this._options; + var ellipsoid = dynamicObject.ellipsoid; + + var position = dynamicObject.position; + var orientation = dynamicObject.orientation; + var radii = ellipsoid.radii; + var stackPartitions = ellipsoid.stackPartitions; + var slicePartitions = ellipsoid.slicePartitions; + var subdivisions = ellipsoid.subdivisions; + + positionScratch = position.getValue(time, positionScratch); + orientationScratch = orientation.getValue(time, orientationScratch); + var modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch); + + options.radii = radii.getValue(time, options.radii); + options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(time, options) : undefined; + options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(time, options) : undefined; + options.subdivisions = defined(subdivisions) ? subdivisions.getValue(time) : undefined; + + if (!defined(ellipsoid.fill) || ellipsoid.fill.getValue(time)) { + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + var material = this._material; + var appearance = new EllipsoidSurfaceAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : dynamicObject, + geometry : new EllipsoidGeometry(options), + modelMatrix : modelMatrix + }), + appearance : appearance, + asynchronous : false + }); + this._primitives.add(this._primitive); + } + + if (defined(ellipsoid.outline) && ellipsoid.outline.getValue(time)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; + this._outlinePrimitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : dynamicObject, + geometry : new EllipsoidOutlineGeometry(options), + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : false, + renderState : { + depthTest : { + enabled : true + } + } + }), + asynchronous : false + }); + this._primitives.add(this._outlinePrimitive); + } + }; + + DynamicGeometryBatchItem.prototype.destroy = function() { + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); + } + destroyObject(this); + }; + + return EllipsoidGeometryUpdater; +}); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicEllipsoidSpec.js b/Specs/DynamicScene/DynamicEllipsoidSpec.js index a1a6bb582dcd..1960f015b509 100644 --- a/Specs/DynamicScene/DynamicEllipsoidSpec.js +++ b/Specs/DynamicScene/DynamicEllipsoidSpec.js @@ -19,6 +19,9 @@ defineSuite([ source.material = new ColorMaterialProperty(); source.radii = new ConstantProperty(new Cartesian3()); source.show = new ConstantProperty(true); + source.stackPartitions = new ConstantProperty(16); + source.slicePartitions = new ConstantProperty(32); + source.subdivisions = new ConstantProperty(64); var target = new DynamicEllipsoid(); target.merge(source); @@ -26,6 +29,9 @@ defineSuite([ expect(target.material).toBe(source.material); expect(target.radii).toBe(source.radii); expect(target.show).toBe(source.show); + expect(target.stackPartitions).toBe(source.stackPartitions); + expect(target.slicePartitions).toBe(source.slicePartitions); + expect(target.subdivisions).toBe(source.subdivisions); }); it('merge does not assign assigned properties', function() { @@ -33,21 +39,33 @@ defineSuite([ source.material = new ColorMaterialProperty(); source.radii = new ConstantProperty(new Cartesian3()); source.show = new ConstantProperty(true); + source.stackPartitions = new ConstantProperty(16); + source.slicePartitions = new ConstantProperty(32); + source.subdivisions = new ConstantProperty(64); var material = new ColorMaterialProperty(); var radii = new ConstantProperty(new Cartesian3()); var show = new ConstantProperty(true); + var stackPartitions = new ConstantProperty(1); + var slicePartitions = new ConstantProperty(2); + var subdivisions = new ConstantProperty(3); var target = new DynamicEllipsoid(); target.material = material; target.radii = radii; target.show = show; + target.stackPartitions = stackPartitions; + target.slicePartitions = slicePartitions; + target.subdivisions = subdivisions; target.merge(source); expect(target.material).toBe(material); expect(target.radii).toBe(radii); expect(target.show).toBe(show); + expect(target.stackPartitions).toBe(stackPartitions); + expect(target.slicePartitions).toBe(slicePartitions); + expect(target.subdivisions).toBe(subdivisions); }); it('clone works', function() { @@ -55,11 +73,17 @@ defineSuite([ source.material = new ColorMaterialProperty(); source.radii = new ConstantProperty(new Cartesian3()); source.show = new ConstantProperty(true); + source.stackPartitions = new ConstantProperty(16); + source.slicePartitions = new ConstantProperty(32); + source.subdivisions = new ConstantProperty(64); var result = source.clone(); expect(result.material).toBe(source.material); expect(result.radii).toBe(source.radii); expect(result.show).toBe(source.show); + expect(result.stackPartitions).toBe(source.stackPartitions); + expect(result.slicePartitions).toBe(source.slicePartitions); + expect(result.subdivisions).toBe(source.subdivisions); }); it('merge throws if source undefined', function() { diff --git a/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js b/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js deleted file mode 100644 index 46e793592f6b..000000000000 --- a/Specs/DynamicScene/DynamicEllipsoidVisualizerSpec.js +++ /dev/null @@ -1,227 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/DynamicEllipsoidVisualizer', - 'Specs/createScene', - 'Specs/destroyScene', - 'DynamicScene/ConstantProperty', - 'Core/JulianDate', - 'Core/Math', - 'Core/Matrix3', - 'Core/Matrix4', - 'Core/Quaternion', - 'Core/Cartesian3', - 'Core/Spherical', - 'Core/Color', - 'DynamicScene/DynamicEllipsoid', - 'DynamicScene/DynamicObjectCollection', - 'DynamicScene/ColorMaterialProperty' - ], function( - DynamicEllipsoidVisualizer, - createScene, - destroyScene, - ConstantProperty, - JulianDate, - CesiumMath, - Matrix3, - Matrix4, - Quaternion, - Cartesian3, - Spherical, - Color, - DynamicEllipsoid, - DynamicObjectCollection, - ColorMaterialProperty) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var scene; - var visualizer; - - beforeAll(function() { - scene = createScene(); - }); - - afterAll(function() { - destroyScene(scene); - }); - - afterEach(function() { - visualizer = visualizer && visualizer.destroy(); - }); - - it('constructor throws if no scene is passed.', function() { - expect(function() { - return new DynamicEllipsoidVisualizer(); - }).toThrowDeveloperError(); - }); - - it('constructor sets expected parameters.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - expect(visualizer.getScene()).toEqual(scene); - expect(visualizer.getDynamicObjectCollection()).toEqual(dynamicObjectCollection); - }); - - it('update throws if no time specified.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - expect(function() { - visualizer.update(); - }).toThrowDeveloperError(); - }); - - it('update does nothing if no dynamicObjectCollection.', function() { - visualizer = new DynamicEllipsoidVisualizer(scene); - visualizer.update(new JulianDate()); - }); - - it('isDestroy returns false until destroyed.', function() { - visualizer = new DynamicEllipsoidVisualizer(scene); - expect(visualizer.isDestroyed()).toEqual(false); - visualizer.destroy(); - expect(visualizer.isDestroyed()).toEqual(true); - visualizer = undefined; - }); - - it('object with no ellipsoid does not create a primitive.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('object with no position does not create a primitive.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - var ellipsoid = testObject.ellipsoid = new DynamicEllipsoid(); - ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('object with no radii does not create a primitive.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - testObject.ellipsoid = new DynamicEllipsoid(); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('object with no orientation does not create a primitive.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.ellipsoid = new DynamicEllipsoid(); - testObject.ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(0); - }); - - it('A DynamicEllipsoid causes a EllipsoidPrimitive to be created and updated.', function() { - var time = new JulianDate(); - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR))); - - var ellipsoid = testObject.ellipsoid = new DynamicEllipsoid(); - ellipsoid.directions = new ConstantProperty([new Spherical(0, 0, 0), new Spherical(1, 0, 0), new Spherical(2, 0, 0), new Spherical(3, 0, 0)]); - ellipsoid.radii = new ConstantProperty(123.5); - ellipsoid.show = new ConstantProperty(true); - ellipsoid.material = new ColorMaterialProperty(); - visualizer.update(time); - - expect(scene.getPrimitives().getLength()).toEqual(1); - var p = scene.getPrimitives().get(0); - expect(p.radii).toEqual(testObject.ellipsoid.radii.getValue(time)); - expect(p.show).toEqual(testObject.ellipsoid.show.getValue(time)); - expect(p.material.uniforms).toEqual(testObject.ellipsoid.material.getValue(time)); - expect(p.modelMatrix).toEqual(Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(testObject.orientation.getValue(time)), testObject.position.getValue(time))); - - ellipsoid.show.value = false; - visualizer.update(time); - expect(p.show).toEqual(testObject.ellipsoid.show.getValue(time)); - }); - - it('clear hides ellipsoids.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - var ellipsoid = testObject.ellipsoid = new DynamicEllipsoid(); - ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - - var time = new JulianDate(); - expect(scene.getPrimitives().getLength()).toEqual(0); - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - expect(scene.getPrimitives().get(0).show).toEqual(true); - dynamicObjectCollection.removeAll(); - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - expect(scene.getPrimitives().get(0).show).toEqual(false); - }); - - it('Visualizer sets dynamicObject property.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - var ellipsoid = testObject.ellipsoid = new DynamicEllipsoid(); - ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - - var time = new JulianDate(); - visualizer.update(time); - expect(scene.getPrimitives().get(0).id).toEqual(testObject); - }); - - it('setDynamicObjectCollection removes old objects and add new ones.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.position = new ConstantProperty(new Cartesian3(1234, 5678, 9101112)); - testObject.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1)); - var ellipsoid = testObject.ellipsoid = new DynamicEllipsoid(); - ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - - var dynamicObjectCollection2 = new DynamicObjectCollection(); - var testObject2 = dynamicObjectCollection2.getOrCreateObject('test2'); - testObject2.position = new ConstantProperty(new Cartesian3(5678, 9101112, 1234)); - testObject2.orientation = new ConstantProperty(new Quaternion(1, 0, 0, 0)); - var ellipsoid2 = testObject2.ellipsoid = new DynamicEllipsoid(); - ellipsoid2.radii = new ConstantProperty(new Cartesian3(4, 5, 6)); - - visualizer = new DynamicEllipsoidVisualizer(scene, dynamicObjectCollection); - - var time = new JulianDate(); - - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - var ellipsoidPrimitive = scene.getPrimitives().get(0); - expect(ellipsoidPrimitive.id).toEqual(testObject); - - visualizer.setDynamicObjectCollection(dynamicObjectCollection2); - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - ellipsoidPrimitive = scene.getPrimitives().get(0); - expect(ellipsoidPrimitive.id).toEqual(testObject2); - }); -}, 'WebGL'); From b331eb51fc199ff78fd6c101402f51ab7499cf1e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 6 Feb 2014 12:14:58 -0500 Subject: [PATCH 30/81] Replace DynamicPolylineVisualizer with PolylineGeometryUpdater Also fix an issue with all dynamic updaters not properly handling the show property. --- Source/DynamicScene/DataSourceDisplay.js | 6 +- .../DynamicBillboardVisualizer.js | 2 - .../DynamicConeVisualizerUsingCustomSensor.js | 2 - Source/DynamicScene/DynamicLabelVisualizer.js | 2 - Source/DynamicScene/DynamicPointVisualizer.js | 2 - .../DynamicScene/DynamicPolylineVisualizer.js | 268 ----------------- .../DynamicScene/DynamicPyramidVisualizer.js | 2 - Source/DynamicScene/EllipseGeometryUpdater.js | 4 +- .../DynamicScene/EllipsoidGeometryUpdater.js | 5 +- Source/DynamicScene/GeometryVisualizer.js | 1 - Source/DynamicScene/PolygonGeometryUpdater.js | 5 +- .../DynamicScene/PolylineGeometryUpdater.js | 278 ++++++++++++++++++ .../DynamicPolylineVisualizerSpec.js | 230 --------------- 13 files changed, 287 insertions(+), 520 deletions(-) delete mode 100644 Source/DynamicScene/DynamicPolylineVisualizer.js create mode 100644 Source/DynamicScene/PolylineGeometryUpdater.js delete mode 100644 Specs/DynamicScene/DynamicPolylineVisualizerSpec.js diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 64b220a7ae5d..4f5fcb85c58b 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -13,7 +13,7 @@ define([ './DynamicPathVisualizer', './DynamicPointVisualizer', './PolygonGeometryUpdater', - './DynamicPolylineVisualizer', + './PolylineGeometryUpdater', './DynamicPyramidVisualizer', './DynamicVectorVisualizer', './GeometryVisualizer', @@ -32,7 +32,7 @@ define([ DynamicPathVisualizer, DynamicPointVisualizer, PolygonGeometryUpdater, - DynamicPolylineVisualizer, + PolylineGeometryUpdater, DynamicPyramidVisualizer, DynamicVectorVisualizer, GeometryVisualizer, @@ -54,7 +54,7 @@ define([ }, function(scene) { return new GeometryVisualizer(PolygonGeometryUpdater, scene); }, function(scene) { - return new DynamicPolylineVisualizer(scene); + return new GeometryVisualizer(PolylineGeometryUpdater, scene); }, function(scene) { return new DynamicVectorVisualizer(scene); }, function(scene) { diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index fa389df5c471..85fd514da24d 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -61,9 +61,7 @@ define([ * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer - * */ var DynamicBillboardVisualizer = function(scene, dynamicObjectCollection) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index 7c409a6e6bab..a8948450aa69 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -97,9 +97,7 @@ define([ * @see DynamicConeVisualizer * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer - * */ var DynamicConeVisualizerUsingCustomSensor = function(scene, dynamicObjectCollection) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index 68f72649f846..1886adbc5cef 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -44,9 +44,7 @@ define([ * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer - * */ var DynamicLabelVisualizer = function(scene, dynamicObjectCollection) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index 35e592cd539b..bf65631d4424 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -38,9 +38,7 @@ define([ * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer - * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer - * */ var DynamicPointVisualizer = function(scene, dynamicObjectCollection) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js deleted file mode 100644 index ef57e5d73ef6..000000000000 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ /dev/null @@ -1,268 +0,0 @@ -/*global define*/ -define([ - '../Core/DeveloperError', - '../Core/defined', - '../Core/destroyObject', - '../Core/Cartesian3', - './MaterialProperty', - '../Scene/Material', - '../Scene/PolylineCollection' - ], function( - DeveloperError, - defined, - destroyObject, - Cartesian3, - MaterialProperty, - Material, - PolylineCollection) { - "use strict"; - - /** - * A DynamicObject visualizer which maps the DynamicPolyline instance - * in DynamicObject.polyline to a Polyline primitive. - * @alias DynamicPolylineVisualizer - * @constructor - * - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. - * - * @exception {DeveloperError} scene is required. - * - * @see DynamicPolyline - * @see Scene - * @see DynamicObject - * @see DynamicObjectCollection - * @see CompositeDynamicObjectCollection - * @see VisualizerCollection - * @see DynamicBillboardVisualizer - * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr - * @see DynamicLabelVisualizer - * @see DynamicPointVisualizer - * @see DynamicPyramidVisualizer - * - */ - var DynamicPolylineVisualizer = function(scene, dynamicObjectCollection) { - //>>includeStart('debug', pragmas.debug); - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - //>>includeEnd('debug'); - - this._scene = scene; - this._unusedIndexes = []; - this._primitives = scene.getPrimitives(); - var polylineCollection = this._polylineCollection = new PolylineCollection(); - scene.getPrimitives().add(polylineCollection); - this._dynamicObjectCollection = undefined; - this.setDynamicObjectCollection(dynamicObjectCollection); - }; - - /** - * Returns the scene being used by this visualizer. - * - * @returns {Scene} The scene being used by this visualizer. - */ - DynamicPolylineVisualizer.prototype.getScene = function() { - return this._scene; - }; - - /** - * Gets the DynamicObjectCollection being visualized. - * - * @returns {DynamicObjectCollection} The DynamicObjectCollection being visualized. - */ - DynamicPolylineVisualizer.prototype.getDynamicObjectCollection = function() { - return this._dynamicObjectCollection; - }; - - /** - * Sets the DynamicObjectCollection to visualize. - * - * @param dynamicObjectCollection The DynamicObjectCollection to visualizer. - */ - DynamicPolylineVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { - var oldCollection = this._dynamicObjectCollection; - if (oldCollection !== dynamicObjectCollection) { - if (defined(oldCollection)) { - oldCollection.collectionChanged.removeEventListener(DynamicPolylineVisualizer.prototype._onObjectsRemoved, this); - this.removeAllPrimitives(); - } - this._dynamicObjectCollection = dynamicObjectCollection; - if (defined(dynamicObjectCollection)) { - dynamicObjectCollection.collectionChanged.addEventListener(DynamicPolylineVisualizer.prototype._onObjectsRemoved, this); - } - } - }; - - /** - * Updates all of the primitives created by this visualizer to match their - * DynamicObject counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * - * @exception {DeveloperError} time is required. - */ - DynamicPolylineVisualizer.prototype.update = function(time) { - //>>includeStart('debug', pragmas.debug); - if (!defined(time)) { - throw new DeveloperError('time is requied.'); - } - //>>includeEnd('debug'); - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for ( var i = 0, len = dynamicObjects.length; i < len; i++) { - updateObject(this, time, dynamicObjects[i]); - } - } - }; - - /** - * Removes all primitives from the scene. - */ - DynamicPolylineVisualizer.prototype.removeAllPrimitives = function() { - var i; - this._polylineCollection.removeAll(); - - if (defined(this._dynamicObjectCollection)) { - var dynamicObjects = this._dynamicObjectCollection.getObjects(); - for (i = dynamicObjects.length - 1; i > -1; i--) { - dynamicObjects[i]._polylineVisualizerIndex = undefined; - } - } - - this._unusedIndexes = []; - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - *

- * If this object was destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. - * - * @memberof DynamicPolylineVisualizer - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see DynamicPolylineVisualizer#destroy - */ - DynamicPolylineVisualizer.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - *

- * Once an object is destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (undefined) to the object as done in the example. - * - * @memberof DynamicPolylineVisualizer - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see DynamicPolylineVisualizer#isDestroyed - * - * @example - * visualizer = visualizer && visualizer.destroy(); - */ - DynamicPolylineVisualizer.prototype.destroy = function() { - this.setDynamicObjectCollection(undefined); - this._scene.getPrimitives().remove(this._polylineCollection); - return destroyObject(this); - }; - - var cachedPosition = new Cartesian3(); - function updateObject(dynamicPolylineVisualizer, time, dynamicObject) { - var dynamicPolyline = dynamicObject._polyline; - if (!defined(dynamicPolyline)) { - return; - } - - var polyline; - var showProperty = dynamicPolyline._show; - var positionProperty = dynamicObject._position; - var vertexPositionsProperty = dynamicObject._vertexPositions; - var polylineVisualizerIndex = dynamicObject._polylineVisualizerIndex; - var show = dynamicObject.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); - var context = dynamicPolylineVisualizer._scene.getContext(); - - if (!show || !defined(vertexPositionsProperty)) { - //Remove the existing primitive if we have one - if (defined(polylineVisualizerIndex)) { - polyline = dynamicPolylineVisualizer._polylineCollection.get(polylineVisualizerIndex); - polyline.setShow(false); - dynamicObject._polylineVisualizerIndex = undefined; - dynamicPolylineVisualizer._unusedIndexes.push(polylineVisualizerIndex); - } - return; - } - - if (!defined(polylineVisualizerIndex)) { - var unusedIndexes = dynamicPolylineVisualizer._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - polylineVisualizerIndex = unusedIndexes.pop(); - polyline = dynamicPolylineVisualizer._polylineCollection.get(polylineVisualizerIndex); - } else { - polylineVisualizerIndex = dynamicPolylineVisualizer._polylineCollection.getLength(); - polyline = dynamicPolylineVisualizer._polylineCollection.add(); - } - dynamicObject._polylineVisualizerIndex = polylineVisualizerIndex; - polyline.id = dynamicObject; - - // CZML_TODO Determine official defaults - polyline.setWidth(1); - var material = polyline.getMaterial(); - if (!defined(material) || (material.type !== Material.PolylineOutlineType)) { - material = Material.fromType(Material.PolylineOutlineType); - polyline.setMaterial(material); - } - } else { - polyline = dynamicPolylineVisualizer._polylineCollection.get(polylineVisualizerIndex); - } - - polyline.setShow(true); - - var vertexPositions = vertexPositionsProperty.getValue(time); - - if (defined(vertexPositions) && polyline._visualizerPositions !== vertexPositions) { - polyline.setPositions(vertexPositions); - polyline._visualizerPositions = vertexPositions; - } - - var property = dynamicPolyline._material; - if (defined(property)) { - polyline.setMaterial(MaterialProperty.getValue(time, property, polyline.getMaterial())); - } - - property = dynamicPolyline._width; - if (defined(property)) { - var width = property.getValue(time); - if (defined(width)) { - polyline.setWidth(width); - } - } - } - - DynamicPolylineVisualizer.prototype._onObjectsRemoved = function(dynamicObjectCollection, added, dynamicObjects) { - var thisPolylineCollection = this._polylineCollection; - var thisUnusedIndexes = this._unusedIndexes; - for ( var i = dynamicObjects.length - 1; i > -1; i--) { - var dynamicObject = dynamicObjects[i]; - var polylineVisualizerIndex = dynamicObject._polylineVisualizerIndex; - if (defined(polylineVisualizerIndex)) { - var polyline = thisPolylineCollection.get(polylineVisualizerIndex); - polyline.setShow(false); - thisUnusedIndexes.push(polylineVisualizerIndex); - dynamicObject._polylineVisualizerIndex = undefined; - } - } - }; - - return DynamicPolylineVisualizer; -}); diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index 6546843a8385..595d3aa911bf 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -51,8 +51,6 @@ define([ * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer - * */ var DynamicPyramidVisualizer = function(scene, dynamicObjectCollection) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index bcc9e89093fe..b164e7f29f5e 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -306,14 +306,14 @@ define(['../Core/Color', } var dynamicObject = geometryUpdater._dynamicObject; - var show = dynamicObject.show; + var ellipse = dynamicObject.ellipse; + var show = ellipse.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { return; } var options = this._options; - var ellipse = dynamicObject.ellipse; var position = dynamicObject.position; var semiMajorAxis = ellipse.semiMajorAxis; diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index eebe4ccca4cf..09d6fe97f59f 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -303,15 +303,14 @@ define(['../Core/Color', } var dynamicObject = geometryUpdater._dynamicObject; - var show = dynamicObject.show; + var ellipsoid = dynamicObject.ellipsoid; + var show = ellipsoid.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { return; } var options = this._options; - var ellipsoid = dynamicObject.ellipsoid; - var position = dynamicObject.position; var orientation = dynamicObject.orientation; var radii = ellipsoid.radii; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 6ce6411927ec..33b0617553f5 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -85,7 +85,6 @@ define(['../Core/defined', * @see DynamicConeVisualizerUsingCustomSensorr * @see DynamicLabelVisualizer * @see DynamicPointVisualizer - * @see DynamicPolylineVisualizer * @see DynamicPyramidVisualizer */ var GeometryVisualizer = function(type, scene, dynamicObjectCollection) { diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 48c9fe077d7f..b5a0f1413bb9 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -296,15 +296,14 @@ define(['../Core/Color', } var dynamicObject = geometryUpdater._dynamicObject; - var show = dynamicObject.show; + var polygon = dynamicObject.polygon; + var show = polygon.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { return; } var options = this._options; - var polygon = dynamicObject.polygon; - var vertexPositions = dynamicObject.vertexPositions; var perPositionHeight = polygon.perPositionHeight; var height = polygon.height; diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js new file mode 100644 index 000000000000..1f32c912ea3d --- /dev/null +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -0,0 +1,278 @@ +/*global define*/ +define(['../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/PolylineGeometry', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/ShowGeometryInstanceAttribute', + '../DynamicScene/ColorMaterialProperty', + '../DynamicScene/ConstantProperty', + '../DynamicScene/GeometryBatchType', + '../DynamicScene/MaterialProperty', + '../Scene/PolylineMaterialAppearance', + '../Scene/PolylineColorAppearance', + '../Scene/Primitive' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + PolylineGeometry, + Event, + GeometryInstance, + Iso8601, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + GeometryBatchType, + MaterialProperty, + PolylineMaterialAppearance, + PolylineColorAppearance, + Primitive) { + "use strict"; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + + var GeometryOptions = function(dynamicObject) { + this.id = dynamicObject; + this.vertexFormat = undefined; + this.positions = undefined; + this.width = undefined; + }; + + var PolylineGeometryUpdater = function(dynamicObject) { + if (!defined(dynamicObject)) { + throw new DeveloperError('dynamicObject is required'); + } + + this._id = dynamicObject.id; + this._dynamicObject = dynamicObject; + this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._options = new GeometryOptions(dynamicObject); + this._onDynamicObjectPropertyChanged(dynamicObject, 'polyline', dynamicObject.polyline, undefined); + }; + + PolylineGeometryUpdater.PerInstanceColorAppearanceType = PolylineColorAppearance; + + PolylineGeometryUpdater.MaterialAppearanceType = PolylineMaterialAppearance; + + defineProperties(PolylineGeometryUpdater.prototype, { + id : { + get : function() { + return this._id; + } + }, + dynamicObject :{ + get : function() { + return this._dynamicObject; + } + }, + geometryType : { + get : function() { + return this._geometryType; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } + }, + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + outlineEnabled : { + get : function() { + return false; + } + }, + hasConstantFill : { + get : function() { + return true; + } + }, + hasConstantOutline : { + get : function() { + return true; + } + }, + outlineColorProperty : { + get : function() { + return undefined; + } + } + }); + + PolylineGeometryUpdater.prototype.isOutlineVisible = function(time) { + return false; + }; + + PolylineGeometryUpdater.prototype.isFilled = function(time) { + return true; + }; + + PolylineGeometryUpdater.prototype.createGeometryInstance = function(time) { + var color; + var attributes; + var dynamicObject = this._dynamicObject; + var isAvailable = dynamicObject.isAvailable(time); + var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time)); + + if (this._geometryType === GeometryBatchType.COLOR) { + var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + color : color + }; + } else { + attributes = { + show : show + }; + } + + return new GeometryInstance({ + id : dynamicObject, + geometry : new PolylineGeometry(this._options), + attributes : attributes + }); + }; + + PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + throw new DeveloperError(); + }; + + PolylineGeometryUpdater.prototype.destroy = function() { + this._dynamicObjectSubscription(); + destroyObject(this); + }; + + PolylineGeometryUpdater.prototype._onDynamicObjectPropertyChanged = function(dynamicObject, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'vertexPositions' || propertyName === 'polyline')) { + return; + } + + var polyline = this._dynamicObject.polyline; + + if (!defined(polyline)) { + if (this._geometryType !== GeometryBatchType.NONE) { + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var vertexPositions = this._dynamicObject.vertexPositions; + + var show = polyline.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(vertexPositions))) { + if (this._geometryType !== GeometryBatchType.NONE) { + this._geometryType = GeometryBatchType.NONE; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(polyline.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._showProperty = defaultValue(show, defaultShow); + + var width = polyline.width; + + if (!vertexPositions.isConstant || // + defined(width) && !width.isConstant) { + if (this._geometryType !== GeometryBatchType.DYNAMIC) { + this._geometryType = GeometryBatchType.DYNAMIC; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PolylineColorAppearance.VERTEX_FORMAT : PolylineMaterialAppearance.VERTEX_FORMAT; + options.positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.positions); + options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; + + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryChanged.raiseEvent(this); + } + }; + + PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + return new DynamicGeometryBatchItem(primitives, this); + }; + + var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._dynamicObject); + }; + + DynamicGeometryBatchItem.prototype.update = function(time) { + var geometryUpdater = this._geometryUpdater; + + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + var dynamicObject = geometryUpdater._dynamicObject; + var polyline = dynamicObject.polyline; + var show = polyline.show; + + if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + return; + } + + var options = this._options; + var vertexPositions = dynamicObject.vertexPositions; + var width = polyline.width; + + options.positions = vertexPositions.getValue(time, options.positions); + options.width = defined(width) ? width.getValue(time) : undefined; + + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + var material = this._material; + var appearance = new PolylineMaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + id : dynamicObject, + geometry : new PolylineGeometry(options) + }), + appearance : appearance, + asynchronous : false + }); + this._primitives.add(this._primitive); + }; + + DynamicGeometryBatchItem.prototype.destroy = function() { + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + destroyObject(this); + }; + + return PolylineGeometryUpdater; +}); \ No newline at end of file diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js deleted file mode 100644 index ee4e3dd1fa4e..000000000000 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ /dev/null @@ -1,230 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/DynamicPolylineVisualizer', - 'Specs/createScene', - 'Specs/destroyScene', - 'DynamicScene/ConstantProperty', - 'DynamicScene/DynamicEllipse', - 'DynamicScene/DynamicPolyline', - 'DynamicScene/DynamicObjectCollection', - 'DynamicScene/DynamicObject', - 'DynamicScene/ColorMaterialProperty', - 'Core/JulianDate', - 'Core/Cartesian2', - 'Core/Cartesian3', - 'Scene/Scene' - ], function( - DynamicPolylineVisualizer, - createScene, - destroyScene, - ConstantProperty, - DynamicEllipse, - DynamicPolyline, - DynamicObjectCollection, - DynamicObject, - ColorMaterialProperty, - JulianDate, - Cartesian2, - Cartesian3, - Scene) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - var scene; - var visualizer; - - beforeAll(function() { - scene = createScene(); - }); - - afterAll(function() { - destroyScene(scene); - }); - - afterEach(function() { - visualizer = visualizer && visualizer.destroy(); - }); - - it('constructor throws if no scene is passed.', function() { - expect(function() { - return new DynamicPolylineVisualizer(); - }).toThrowDeveloperError(); - }); - - it('constructor sets expected parameters and adds collection to scene.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - expect(visualizer.getScene()).toEqual(scene); - expect(visualizer.getDynamicObjectCollection()).toEqual(dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(1); - }); - - it('update throws if no time specified.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - expect(function() { - visualizer.update(); - }).toThrowDeveloperError(); - }); - - it('update does nothing if no dynamicObjectCollection.', function() { - visualizer = new DynamicPolylineVisualizer(scene); - visualizer.update(new JulianDate()); - }); - - it('isDestroy returns false until destroyed.', function() { - visualizer = new DynamicPolylineVisualizer(scene); - expect(visualizer.isDestroyed()).toEqual(false); - visualizer.destroy(); - expect(visualizer.isDestroyed()).toEqual(true); - visualizer = undefined; - }); - - it('object with no polyline does not create one.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112)]); - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(0); - }); - - it('object with no vertexPosition does not create a polyline.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - - visualizer.update(new JulianDate()); - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(0); - }); - - it('A DynamicPolyline causes a primtive to be created and updated.', function() { - var time = new JulianDate(); - - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - expect(scene.getPrimitives().getLength()).toEqual(1); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112)]); - - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - polyline.material = new ColorMaterialProperty(); - polyline.width = new ConstantProperty(12.5); - - visualizer.update(time); - - expect(scene.getPrimitives().getLength()).toEqual(1); - - var polylineCollection = scene.getPrimitives().get(0); - var primitive = polylineCollection.get(0); - visualizer.update(time); - expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); - expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValue(time)); - expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); - - var material = primitive.getMaterial(); - expect(material.uniforms).toEqual(testObject.polyline.material.getValue(time)); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - polyline.material = new ColorMaterialProperty(); - polyline.width = new ConstantProperty(2.5); - - visualizer.update(time); - expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); - expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValue(time)); - expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); - - material = primitive.getMaterial(); - expect(material.uniforms).toEqual(testObject.polyline.material.getValue(time)); - - polyline.show = new ConstantProperty(false); - visualizer.update(time); - expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); - }); - - it('clear hides primitives.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - expect(scene.getPrimitives().getLength()).toEqual(1); - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - var time = new JulianDate(); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - var polyline = testObject.polyline = new DynamicPolyline(); - polyline.show = new ConstantProperty(true); - visualizer.update(time); - - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(1); - var primitive = polylineCollection.get(0); - - visualizer.update(time); - //Clearing won't actually remove the primitive because of the - //internal cache used by the visualizer, instead it just hides it. - dynamicObjectCollection.removeAll(); - expect(primitive.getShow()).toEqual(false); - }); - - it('Visualizer sets dynamicObject property.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - expect(scene.getPrimitives().getLength()).toEqual(1); - - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - - var time = new JulianDate(); - var polyline = testObject.polyline = new DynamicPolyline(); - - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - polyline.show = new ConstantProperty(true); - - visualizer.update(time); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(1); - var primitive = polylineCollection.get(0); - expect(primitive.id).toEqual(testObject); - }); - - it('setDynamicObjectCollection removes old objects and add new ones.', function() { - var dynamicObjectCollection = new DynamicObjectCollection(); - var testObject = dynamicObjectCollection.getOrCreateObject('test'); - testObject.vertexPositions = new ConstantProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - testObject.polyline = new DynamicPolyline(); - testObject.polyline.show = new ConstantProperty(true); - - var dynamicObjectCollection2 = new DynamicObjectCollection(); - var testObject2 = dynamicObjectCollection2.getOrCreateObject('test2'); - testObject2.vertexPositions = new ConstantProperty([new Cartesian3(1234, 5678, 9101112), new Cartesian3(5678, 1234, 1101112)]); - testObject2.polyline = new DynamicPolyline(); - testObject2.polyline.show = new ConstantProperty(true); - - visualizer = new DynamicPolylineVisualizer(scene, dynamicObjectCollection); - - var time = new JulianDate(); - - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - var polylineCollection = scene.getPrimitives().get(0); - expect(polylineCollection.getLength()).toEqual(1); - var primitive = polylineCollection.get(0); - expect(primitive.id).toEqual(testObject); - - visualizer.setDynamicObjectCollection(dynamicObjectCollection2); - visualizer.update(time); - expect(scene.getPrimitives().getLength()).toEqual(1); - primitive = polylineCollection.get(0); - expect(primitive.id).toEqual(testObject2); - }); -}, 'WebGL'); \ No newline at end of file From fe0efbe8949eb30b63bf4ed72868a600da3f9a61 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sat, 8 Feb 2014 11:49:31 -0500 Subject: [PATCH 31/81] Minor doc cleanup. --- Source/DynamicScene/GeometryVisualizer.js | 4 ---- Source/DynamicScene/PositionPropertyArray.js | 3 --- Source/DynamicScene/SampledPositionProperty.js | 2 -- Source/DynamicScene/SampledProperty.js | 2 -- 4 files changed, 11 deletions(-) diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 33b0617553f5..311393809430 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -72,8 +72,6 @@ define(['../Core/defined', * @param {Scene} scene The scene the primitives will be rendered in. * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. * - * @exception {DeveloperError} scene is required. - * * @see DynamicPolygon * @see Scene * @see DynamicObject @@ -162,8 +160,6 @@ define(['../Core/defined', * DynamicObject counterpart at the given time. * * @param {JulianDate} time The time to update to. - * - * @exception {DeveloperError} time is required. */ GeometryVisualizer.prototype.update = function(time) { if (!defined(time)) { diff --git a/Source/DynamicScene/PositionPropertyArray.js b/Source/DynamicScene/PositionPropertyArray.js index 6eec4bed8a13..f0eccba10817 100644 --- a/Source/DynamicScene/PositionPropertyArray.js +++ b/Source/DynamicScene/PositionPropertyArray.js @@ -103,9 +103,6 @@ define(['../Core/defaultValue', * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - * - * @exception {DeveloperError} time is required. - * @exception {DeveloperError} referenceFrame is required. */ PositionPropertyArray.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/SampledPositionProperty.js b/Source/DynamicScene/SampledPositionProperty.js index d17bbf7aee79..e37e7140e876 100644 --- a/Source/DynamicScene/SampledPositionProperty.js +++ b/Source/DynamicScene/SampledPositionProperty.js @@ -146,8 +146,6 @@ define(['./PositionProperty', * @param {Object} options The options * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - * - * @exception {DeveloperError} options is required. */ SampledPositionProperty.prototype.setInterpolationOptions = function(options) { this._property.setInterpolationOptions(options); diff --git a/Source/DynamicScene/SampledProperty.js b/Source/DynamicScene/SampledProperty.js index ddf2386196f5..637fc80c79ad 100644 --- a/Source/DynamicScene/SampledProperty.js +++ b/Source/DynamicScene/SampledProperty.js @@ -357,8 +357,6 @@ define(['../Core/binarySearch', * @param {Object} options The options * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - * - * @exception {DeveloperError} options is required. */ SampledProperty.prototype.setInterpolationOptions = function(options) { //>>includeStart('debug', pragmas.debug); From af95f5f9882ec81c7a90e95511059399dc595b87 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 10 Feb 2014 17:22:27 -0500 Subject: [PATCH 32/81] EllipsoidGeometryUpdater should not use EllipsoidSurfaceAppearance It should just use standard MaterialAppearance. --- Source/DynamicScene/EllipsoidGeometryUpdater.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 09d6fe97f59f..f5fffffa0ad7 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -18,7 +18,7 @@ define(['../Core/Color', '../DynamicScene/ConstantProperty', '../DynamicScene/GeometryBatchType', '../DynamicScene/MaterialProperty', - '../Scene/EllipsoidSurfaceAppearance', + '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive' ], function( @@ -41,7 +41,7 @@ define(['../Core/Color', ConstantProperty, GeometryBatchType, MaterialProperty, - EllipsoidSurfaceAppearance, + MaterialAppearance, PerInstanceColorAppearance, Primitive) { "use strict"; @@ -87,7 +87,7 @@ define(['../Core/Color', EllipsoidGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; - EllipsoidGeometryUpdater.MaterialAppearanceType = EllipsoidSurfaceAppearance; + EllipsoidGeometryUpdater.MaterialAppearanceType = MaterialAppearance; defineProperties(EllipsoidGeometryUpdater.prototype, { id : { @@ -264,7 +264,7 @@ define(['../Core/Color', } } else { var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : EllipsoidSurfaceAppearance.VERTEX_FORMAT; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.VERTEX_FORMAT; options.radii = radii.getValue(Iso8601.MINIMUM_VALUE, options.radii); options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; @@ -330,7 +330,7 @@ define(['../Core/Color', if (!defined(ellipsoid.fill) || ellipsoid.fill.getValue(time)) { this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); var material = this._material; - var appearance = new EllipsoidSurfaceAppearance({ + var appearance = new MaterialAppearance({ material : material, translucent : material.isTranslucent(), closed : true From 4043a150b450181c7a61bfa2900b8ec821f3fe4e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 10 Feb 2014 20:43:13 -0500 Subject: [PATCH 33/81] Fix translucency settings for outlines Also remove uneeded renderstate settings. --- Source/DynamicScene/EllipseGeometryUpdater.js | 7 +------ Source/DynamicScene/EllipsoidGeometryUpdater.js | 7 +------ Source/DynamicScene/PolygonGeometryUpdater.js | 7 +------ 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index b164e7f29f5e..7d7b0cb5f8ba 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -370,12 +370,7 @@ define(['../Core/Color', }), appearance : new PerInstanceColorAppearance({ flat : true, - translucent : false, - renderState : { - depthTest : { - enabled : true - } - } + translucent : outlineColor.alpha !== 1.0 }), asynchronous : false }); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index f5fffffa0ad7..fbf58c398ce5 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -364,12 +364,7 @@ define(['../Core/Color', }), appearance : new PerInstanceColorAppearance({ flat : true, - translucent : false, - renderState : { - depthTest : { - enabled : true - } - } + translucent : outlineColor.alpha !== 1.0 }), asynchronous : false }); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index b5a0f1413bb9..5b469a75bad9 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -353,12 +353,7 @@ define(['../Core/Color', }), appearance : new PerInstanceColorAppearance({ flat : true, - translucent : false, - renderState : { - depthTest : { - enabled : true - } - } + translucent : outlineColor.alpha !== 1.0 }), asynchronous : false }); From 71b13549c5c79f2859644548f53b6ca684914cf9 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 10 Feb 2014 20:58:24 -0500 Subject: [PATCH 34/81] Remove uneeded parameter. --- Source/DynamicScene/StaticOutlineGeometryBatch.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 6a860446bda3..9ad8bc36e361 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -63,12 +63,7 @@ define(['../Core/Color', geometryInstances : geometry, appearance : new PerInstanceColorAppearance({ flat : true, - translucent : this.translucent, - renderState : { - depthTest : { - enabled : true - } - } + translucent : this.translucent }) }); From 72f327e7d7d593773d164b1c6dc11095e00db3bc Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 10 Feb 2014 22:14:40 -0500 Subject: [PATCH 35/81] Further batch geometry based on open/closed. --- Source/DynamicScene/EllipseGeometryUpdater.js | 11 ++++++++--- Source/DynamicScene/EllipsoidGeometryUpdater.js | 4 ++-- Source/DynamicScene/GeometryBatchType.js | 10 ++++++---- Source/DynamicScene/GeometryVisualizer.js | 6 ++++-- Source/DynamicScene/PolygonGeometryUpdater.js | 11 ++++++++--- Source/DynamicScene/PolylineGeometryUpdater.js | 6 +++--- Source/DynamicScene/StaticGeometryColorBatch.js | 11 ++++++----- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 9 +++++---- Specs/DynamicScene/EllipseGeometryUpdaterSpec.js | 4 ++-- 9 files changed, 44 insertions(+), 28 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 7d7b0cb5f8ba..96b86aca0ea1 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -152,7 +152,7 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR) { + if (this._geometryType === GeometryBatchType.COLOR_OPEN || this._geometryType === GeometryBatchType.COLOR_CLOSED) { var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { @@ -276,8 +276,13 @@ define(['../Core/Color', options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + var isClosed = defined(options.extrudedHeight); + if (isClosed) { + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; + } else { + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; + } this._outlineEnabled = outlineEnabled; - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; this._geometryChanged.raiseEvent(this); } }; @@ -340,7 +345,7 @@ define(['../Core/Color', var appearance = new MaterialAppearance({ material : material, translucent : material.isTranslucent(), - closed : true + closed : defined(options.extrudedHeight) }); options.vertexFormat = appearance.vertexFormat; diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index fbf58c398ce5..c6e5c5d0290d 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -155,7 +155,7 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR) { + if (this._geometryType === GeometryBatchType.COLOR_CLOSED) { var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { @@ -274,7 +274,7 @@ define(['../Core/Color', orientationScratch = orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); this._modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch); this._outlineEnabled = outlineEnabled; - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; this._geometryChanged.raiseEvent(this); } }; diff --git a/Source/DynamicScene/GeometryBatchType.js b/Source/DynamicScene/GeometryBatchType.js index b7ea8cfbf9d1..f0069ee0e7c9 100644 --- a/Source/DynamicScene/GeometryBatchType.js +++ b/Source/DynamicScene/GeometryBatchType.js @@ -3,10 +3,12 @@ define(['../Core/Enumeration'], function(Enumeration) { "use strict"; var GeometryBatchType = { - COLOR : new Enumeration(0, 'COLOR'), - MATERIAL : new Enumeration(1, 'MATERIAL'), - DYNAMIC : new Enumeration(2, 'DYNAMIC'), - NONE : new Enumeration(3, 'NONE') + COLOR_CLOSED : new Enumeration(0, 'COLOR_CLOSED'), + MATERIAL_CLOSED : new Enumeration(1, 'MATERIAL_CLOSED'), + COLOR_OPEN : new Enumeration(2, 'COLOR_OPEN'), + MATERIAL_OPEN : new Enumeration(3, 'MATERIAL_OPEN'), + DYNAMIC : new Enumeration(4, 'DYNAMIC'), + NONE : new Enumeration(5, 'NONE') }; return GeometryBatchType; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 311393809430..21139814b951 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -107,8 +107,10 @@ define(['../Core/defined', this._outlineBatch = new StaticOutlineGeometryBatch(primitives); this._batches = []; - this._batches[GeometryBatchType.COLOR.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType); - this._batches[GeometryBatchType.MATERIAL.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType); + this._batches[GeometryBatchType.COLOR_CLOSED.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, true); + this._batches[GeometryBatchType.MATERIAL_CLOSED.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, true); + this._batches[GeometryBatchType.COLOR_OPEN.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, false); + this._batches[GeometryBatchType.MATERIAL_OPEN.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, false); this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); this._subscriptions = new Map(); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 5b469a75bad9..570bc07fb82a 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -151,7 +151,7 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR) { + if (this._geometryType === GeometryBatchType.COLOR_OPEN || this._geometryType === GeometryBatchType.COLOR_CLOSED) { var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { @@ -266,8 +266,13 @@ define(['../Core/Color', options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + var isClosed = defined(options.extrudedHeight); + if (isClosed) { + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; + } else { + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; + } this._outlineEnabled = outlineEnabled; - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; this._geometryChanged.raiseEvent(this); } }; @@ -324,7 +329,7 @@ define(['../Core/Color', var appearance = new MaterialAppearance({ material : material, translucent : material.isTranslucent(), - closed : true + closed : defined(options.extrudedHeight) }); options.vertexFormat = appearance.vertexFormat; diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 1f32c912ea3d..afa42d3ed2e2 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -134,7 +134,7 @@ define(['../Core/Color', var isAvailable = dynamicObject.isAvailable(time); var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR) { + if (this._geometryType === GeometryBatchType.COLOR_OPEN) { var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { @@ -209,7 +209,7 @@ define(['../Core/Color', options.positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.positions); options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR : GeometryBatchType.MATERIAL; + this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; this._geometryChanged.raiseEvent(this); } }; @@ -252,7 +252,7 @@ define(['../Core/Color', var appearance = new PolylineMaterialAppearance({ material : material, translucent : material.isTranslucent(), - closed : true + closed : false }); options.vertexFormat = appearance.vertexFormat; diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index fa5abce09c13..c85f10cdb032 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -16,9 +16,10 @@ define(['../Core/Color', var colorScratch = new Color(); - var Batch = function(primitives, translucent, appearanceType) { + var Batch = function(primitives, translucent, appearanceType, closed) { this.translucent = translucent; this.appearanceType = appearanceType; + this.closed = closed; this.primitives = primitives; this.createPrimitive = false; this.primitive = undefined; @@ -62,7 +63,7 @@ define(['../Core/Color', geometryInstances : geometry, appearance : new this.appearanceType({ translucent : this.translucent, - closed : true + closed : this.closed }) }); @@ -110,9 +111,9 @@ define(['../Core/Color', } }; - var StaticGeometryColorBatch = function(primitives, appearanceType) { - this._solidBatch = new Batch(primitives, false, appearanceType); - this._translucentBatch = new Batch(primitives, true, appearanceType); + var StaticGeometryColorBatch = function(primitives, appearanceType, closed) { + this._solidBatch = new Batch(primitives, false, appearanceType, closed); + this._translucentBatch = new Batch(primitives, true, appearanceType, closed); }; StaticGeometryColorBatch.prototype.add = function(time, updater) { diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 3d79ebb5dbe9..c5a62ae0b261 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -14,15 +14,16 @@ define(['../Core/defined', MaterialProperty) { "use strict"; - var Batch = function(primitives, appearanceType, materialProperty) { + var Batch = function(primitives, appearanceType, materialProperty, closed) { + this.primitives = primitives; + this.appearanceType = appearanceType; this.materialProperty = materialProperty; + this.closed = closed; this.updaters = new Map(); this.createPrimitive = true; this.primitive = undefined; - this.primitives = primitives; this.geometry = new Map(); this.material = Material.fromType('Color'); - this.appearanceType = appearanceType; this.updatersWithAttributes = new Map(); this.attributes = new Map(); this.invalidated = false; @@ -79,7 +80,7 @@ define(['../Core/defined', material : MaterialProperty.getValue(time, this.materialProperty, this.material), faceForward : true, translucent : this.material.isTranslucent(), - closed : true + closed : this.closed }) }); diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index dc4ec6715d32..6175fe887c06 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -54,11 +54,11 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', //Default color ellipse.semiMajorAxis = new ConstantProperty(1); ellipse.semiMinorAxis = new ConstantProperty(2); - expect(updater.geometryType).toBe(GeometryBatchType.COLOR); + expect(updater.geometryType).toBe(GeometryBatchType.COLOR_OPEN); //Non-color material ellipse.material = new GridMaterialProperty(); - expect(updater.geometryType).toBe(GeometryBatchType.MATERIAL); + expect(updater.geometryType).toBe(GeometryBatchType.MATERIAL_OPEN); //Dynamic position dynamicObject.position = new SampledPositionProperty(); From e2fefba15f57827c2d33af105291d53bfbac37ab Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 10 Feb 2014 22:32:35 -0500 Subject: [PATCH 36/81] Make static geometry asynchronous. This uses the private `Primitive._state` variable, which should be made public. --- Source/DynamicScene/StaticGeometryColorBatch.js | 10 ++++++---- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 6 ++++-- Source/DynamicScene/StaticOutlineGeometryBatch.js | 10 ++++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index c85f10cdb032..e2e2df026c82 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -4,14 +4,16 @@ define(['../Core/Color', '../Core/defined', '../Core/Map', '../Core/ShowGeometryInstanceAttribute', - '../Scene/Primitive' + '../Scene/Primitive', + '../Scene/PrimitiveState' ], function( Color, ColorGeometryInstanceAttribute, defined, Map, ShowGeometryInstanceAttribute, - Primitive) { + Primitive, + PrimitiveState) { "use strict"; var colorScratch = new Color(); @@ -59,7 +61,7 @@ define(['../Core/Color', var geometry = this.geometry.getValues(); if (geometry.length > 0) { primitive = new Primitive({ - asynchronous : false, + asynchronous : true, geometryInstances : geometry, appearance : new this.appearanceType({ translucent : this.translucent, @@ -71,7 +73,7 @@ define(['../Core/Color', } this.primitive = primitive; this.createPrimitive = false; - } else { + } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ var updatersWithAttributes = this.updatersWithAttributes.getValues(); var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index c5a62ae0b261..1d48f6db4937 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -4,6 +4,7 @@ define(['../Core/defined', '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', '../Scene/Material', + '../Scene/PrimitiveState', './MaterialProperty' ], function( defined, @@ -11,6 +12,7 @@ define(['../Core/defined', ShowGeometryInstanceAttribute, Primitive, Material, + PrimitiveState, MaterialProperty) { "use strict"; @@ -74,7 +76,7 @@ define(['../Core/defined', } if (geometries.length > 0) { primitive = new Primitive({ - asynchronous : false, + asynchronous : true, geometryInstances : geometries, appearance : new this.appearanceType({ material : MaterialProperty.getValue(time, this.materialProperty, this.material), @@ -88,7 +90,7 @@ define(['../Core/defined', } this.primitive = primitive; this.createPrimitive = false; - } else { + } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ this.primitive.appearance.material = MaterialProperty.getValue(time, this.materialProperty, this.material); var updatersWithAttributes = this.updatersWithAttributes.getValues(); diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 9ad8bc36e361..84a3f8ec6d9c 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -5,7 +5,8 @@ define(['../Core/Color', '../Core/Map', '../Core/ShowGeometryInstanceAttribute', '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive' + '../Scene/Primitive', + '../Scene/PrimitiveState' ], function( Color, ColorGeometryInstanceAttribute, @@ -13,7 +14,8 @@ define(['../Core/Color', Map, ShowGeometryInstanceAttribute, PerInstanceColorAppearance, - Primitive) { + Primitive, + PrimitiveState) { "use strict"; var Batch = function(primitives, translucent, appearanceType) { @@ -59,7 +61,7 @@ define(['../Core/Color', var geometry = this.geometry.getValues(); if (geometry.length > 0) { primitive = new Primitive({ - asynchronous : false, + asynchronous : true, geometryInstances : geometry, appearance : new PerInstanceColorAppearance({ flat : true, @@ -71,7 +73,7 @@ define(['../Core/Color', } this.primitive = primitive; this.createPrimitive = false; - } else { + } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ var updatersWithAttributes = this.updatersWithAttributes.getValues(); var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { From 30a354f87cf6544e9049fbb58340754e6777c6b7 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 11 Feb 2014 16:57:37 -0500 Subject: [PATCH 37/81] After discussion, it was decided to use `faceForward : true` everywhere We may eventually make this the default for all Appearances. --- Source/DynamicScene/EllipseGeometryUpdater.js | 1 + Source/DynamicScene/EllipsoidGeometryUpdater.js | 1 + Source/DynamicScene/PolygonGeometryUpdater.js | 1 + Source/DynamicScene/PolylineGeometryUpdater.js | 1 + Source/DynamicScene/StaticGeometryColorBatch.js | 1 + 5 files changed, 5 insertions(+) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 96b86aca0ea1..bf03113aa1e0 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -344,6 +344,7 @@ define(['../Core/Color', var material = this._material; var appearance = new MaterialAppearance({ material : material, + faceForward : true, translucent : material.isTranslucent(), closed : defined(options.extrudedHeight) }); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index c6e5c5d0290d..c17c991d08e0 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -332,6 +332,7 @@ define(['../Core/Color', var material = this._material; var appearance = new MaterialAppearance({ material : material, + faceForward : true, translucent : material.isTranslucent(), closed : true }); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 570bc07fb82a..ffdf45163907 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -328,6 +328,7 @@ define(['../Core/Color', var material = this._material; var appearance = new MaterialAppearance({ material : material, + faceForward : true, translucent : material.isTranslucent(), closed : defined(options.extrudedHeight) }); diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index afa42d3ed2e2..7b6005c5a12d 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -251,6 +251,7 @@ define(['../Core/Color', var material = this._material; var appearance = new PolylineMaterialAppearance({ material : material, + faceForward : true, translucent : material.isTranslucent(), closed : false }); diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index e2e2df026c82..0e272591ff39 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -64,6 +64,7 @@ define(['../Core/Color', asynchronous : true, geometryInstances : geometry, appearance : new this.appearanceType({ + faceForward : true, translucent : this.translucent, closed : this.closed }) From 2ac9c79ed1b458a5a07dcb40fc804f9c646a0f96 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 11 Feb 2014 19:28:05 -0500 Subject: [PATCH 38/81] Replace truthy statement with defined. --- Source/DynamicScene/ColorMaterialProperty.js | 2 +- Source/DynamicScene/GridMaterialProperty.js | 2 +- Source/DynamicScene/PolylineOutlineMaterialProperty.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 7bd2f54c5722..f04adde79cfd 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -64,7 +64,7 @@ define(['../Core/Color', }, set : function(value) { if (this._color !== value) { - if (this._colorSubscription) { + if (defined(this._colorSubscription)) { this._colorSubscription(); this._colorSubscription = undefined; } diff --git a/Source/DynamicScene/GridMaterialProperty.js b/Source/DynamicScene/GridMaterialProperty.js index c541c6c279b0..f136c0786b17 100644 --- a/Source/DynamicScene/GridMaterialProperty.js +++ b/Source/DynamicScene/GridMaterialProperty.js @@ -77,7 +77,7 @@ define(['../Core/Cartesian2', }, set : function(value) { if (this._color !== value) { - if (this._colorSubscription) { + if (defined(this._colorSubscription)) { this._colorSubscription(); this._colorSubscription = undefined; } diff --git a/Source/DynamicScene/PolylineOutlineMaterialProperty.js b/Source/DynamicScene/PolylineOutlineMaterialProperty.js index 744e9194e64c..67139816142a 100644 --- a/Source/DynamicScene/PolylineOutlineMaterialProperty.js +++ b/Source/DynamicScene/PolylineOutlineMaterialProperty.js @@ -70,7 +70,7 @@ define(['../Core/Color', }, set : function(value) { if (this._color !== value) { - if (this._colorSubscription) { + if (defined(this._colorSubscription)) { this._colorSubscription(); this._colorSubscription = undefined; } From aa928e0bd2d4748cc895923aabb6af139c5ee172 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 12 Feb 2014 11:11:48 -0500 Subject: [PATCH 39/81] Remove unecessary call to `defaultValue` --- Source/DynamicScene/ConstantPositionProperty.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DynamicScene/ConstantPositionProperty.js b/Source/DynamicScene/ConstantPositionProperty.js index 9019bfdcb11e..6ca1ac4d2854 100644 --- a/Source/DynamicScene/ConstantPositionProperty.js +++ b/Source/DynamicScene/ConstantPositionProperty.js @@ -101,7 +101,7 @@ define(['./PositionProperty', } if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { definitionChanged = true; - this._referenceFrame = defaultValue(this._referenceFrame, referenceFrame); + this._referenceFrame = referenceFrame; } if (definitionChanged) { this._definitionChanged.raiseEvent(this); From 89cbe0ac9d7cff669f8632e9c376b4dc751d3af7 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 12 Feb 2014 14:33:45 -0500 Subject: [PATCH 40/81] Rename Map to AssociativeArray to avoid confusion. --- Source/Core/{Map.js => AssociativeArray.js} | 17 +++++++++-------- Source/DynamicScene/GeometryVisualizer.js | 10 +++++----- Source/DynamicScene/StaticGeometryColorBatch.js | 12 ++++++------ .../StaticGeometryPerMaterialBatch.js | 12 ++++++------ .../DynamicScene/StaticOutlineGeometryBatch.js | 12 ++++++------ 5 files changed, 32 insertions(+), 31 deletions(-) rename Source/Core/{Map.js => AssociativeArray.js} (62%) diff --git a/Source/Core/Map.js b/Source/Core/AssociativeArray.js similarity index 62% rename from Source/Core/Map.js rename to Source/Core/AssociativeArray.js index fde63d834c14..bcba9fb0b2c3 100644 --- a/Source/Core/Map.js +++ b/Source/Core/AssociativeArray.js @@ -5,29 +5,30 @@ define(['./defined', defined, DeveloperError) { "use strict"; - var Map = function() { + var AssociativeArray = function() { this._array = []; this._hash = {}; }; - Map.prototype.set = function(key, value) { + AssociativeArray.prototype.set = function(key, value) { + this.remove(key); this._hash[key] = value; this._array.push(value); }; - Map.prototype.get = function(key) { + AssociativeArray.prototype.get = function(key) { return this._hash[key]; }; - Map.prototype.getCount = function() { + AssociativeArray.prototype.getCount = function() { return this._array.length; }; - Map.prototype.getValues = function() { + AssociativeArray.prototype.getValues = function() { return this._array; }; - Map.prototype.remove = function(key) { + AssociativeArray.prototype.remove = function(key) { var hasValue = defined(this._hash[key]); if (hasValue) { var array = this._array; @@ -37,10 +38,10 @@ define(['./defined', return hasValue; }; - Map.prototype.removeAll = function() { + AssociativeArray.prototype.removeAll = function() { this._hash = {}; this._array.length = 0; }; - return Map; + return AssociativeArray; }); diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 21139814b951..9a879d0911d8 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -2,7 +2,7 @@ define(['../Core/defined', '../Core/DeveloperError', '../Core/destroyObject', - '../Core/Map', + '../Core/AssociativeArray', '../Scene/PerInstanceColorAppearance', '../Scene/PolylineColorAppearance', '../Scene/MaterialAppearance', @@ -16,7 +16,7 @@ define(['../Core/defined', defined, DeveloperError, destroyObject, - Map, + AssociativeArray, PerInstanceColorAppearance, PolylineColorAppearance, MaterialAppearance, @@ -32,7 +32,7 @@ define(['../Core/defined', var DynamicGeometryBatch = function(primitives) { this._primitives = primitives; - this._dynamicUpdaters = new Map(); + this._dynamicUpdaters = new AssociativeArray(); }; DynamicGeometryBatch.prototype.add = function(time, updater) { @@ -113,8 +113,8 @@ define(['../Core/defined', this._batches[GeometryBatchType.MATERIAL_OPEN.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, false); this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); - this._subscriptions = new Map(); - this._updaters = new Map(); + this._subscriptions = new AssociativeArray(); + this._updaters = new AssociativeArray(); this.setDynamicObjectCollection(dynamicObjectCollection); }; diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 0e272591ff39..935fe13b3e48 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -2,7 +2,7 @@ define(['../Core/Color', '../Core/ColorGeometryInstanceAttribute', '../Core/defined', - '../Core/Map', + '../Core/AssociativeArray', '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', '../Scene/PrimitiveState' @@ -10,7 +10,7 @@ define(['../Core/Color', Color, ColorGeometryInstanceAttribute, defined, - Map, + AssociativeArray, ShowGeometryInstanceAttribute, Primitive, PrimitiveState) { @@ -25,10 +25,10 @@ define(['../Core/Color', this.primitives = primitives; this.createPrimitive = false; this.primitive = undefined; - this.geometry = new Map(); - this.updaters = new Map(); - this.updatersWithAttributes = new Map(); - this.attributes = new Map(); + this.geometry = new AssociativeArray(); + this.updaters = new AssociativeArray(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); this.itemsToRemove = []; }; diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 1d48f6db4937..8c5aae52fd70 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -1,6 +1,6 @@ /*global define*/ define(['../Core/defined', - '../Core/Map', + '../Core/AssociativeArray', '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', '../Scene/Material', @@ -8,7 +8,7 @@ define(['../Core/defined', './MaterialProperty' ], function( defined, - Map, + AssociativeArray, ShowGeometryInstanceAttribute, Primitive, Material, @@ -21,13 +21,13 @@ define(['../Core/defined', this.appearanceType = appearanceType; this.materialProperty = materialProperty; this.closed = closed; - this.updaters = new Map(); + this.updaters = new AssociativeArray(); this.createPrimitive = true; this.primitive = undefined; - this.geometry = new Map(); + this.geometry = new AssociativeArray(); this.material = Material.fromType('Color'); - this.updatersWithAttributes = new Map(); - this.attributes = new Map(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); this.invalidated = false; this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); }; diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 84a3f8ec6d9c..8d48d0322225 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -2,7 +2,7 @@ define(['../Core/Color', '../Core/ColorGeometryInstanceAttribute', '../Core/defined', - '../Core/Map', + '../Core/AssociativeArray', '../Core/ShowGeometryInstanceAttribute', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive', @@ -11,7 +11,7 @@ define(['../Core/Color', Color, ColorGeometryInstanceAttribute, defined, - Map, + AssociativeArray, ShowGeometryInstanceAttribute, PerInstanceColorAppearance, Primitive, @@ -24,10 +24,10 @@ define(['../Core/Color', this.primitives = primitives; this.createPrimitive = false; this.primitive = undefined; - this.geometry = new Map(); - this.updaters = new Map(); - this.updatersWithAttributes = new Map(); - this.attributes = new Map(); + this.geometry = new AssociativeArray(); + this.updaters = new AssociativeArray(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); this.itemsToRemove = []; }; From 881d294beb072e07f3f2db9744974db444a46652 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 12 Feb 2014 15:43:53 -0500 Subject: [PATCH 41/81] Doc and specs for AssociativeArray Also switch to readonly properties instead of get functions. --- Source/Core/AssociativeArray.js | 86 +++++++++++++++++-- Source/DynamicScene/GeometryVisualizer.js | 6 +- .../DynamicScene/StaticGeometryColorBatch.js | 4 +- .../StaticGeometryPerMaterialBatch.js | 8 +- .../StaticOutlineGeometryBatch.js | 4 +- Specs/Core/AssociativeArraySpec.js | 72 ++++++++++++++++ 6 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 Specs/Core/AssociativeArraySpec.js diff --git a/Source/Core/AssociativeArray.js b/Source/Core/AssociativeArray.js index bcba9fb0b2c3..844e10cc9c8b 100644 --- a/Source/Core/AssociativeArray.js +++ b/Source/Core/AssociativeArray.js @@ -1,34 +1,98 @@ /*global define*/ define(['./defined', + './defineProperties', './DeveloperError' ], function( - defined, DeveloperError) { + defined, + defineProperties, + DeveloperError) { "use strict"; + /** + * A collection of key-value pairs that is stored as a hash for easy + * lookup but also provides as an array for fast iteration. + * @alias AssociativeArray + * @constructor + */ var AssociativeArray = function() { this._array = []; this._hash = {}; }; + defineProperties(AssociativeArray.prototype, { + /** + * Get the number of items in the collection. + * @memberof AssociativeArray.prototype + * + * @returns {Number} The number of items in the collection. + */ + count : { + get : function() { + return this._array.length; + } + }, + /** + * Get an unordered array of all values in the collection. + * This is a live array that will automatically reflect the values in the collection, + * it should not be modified directly. + * @memberof AssociativeArray.prototype + */ + values : { + get : function() { + return this._array; + } + } + }); + + /** + * Associates the provided key with the provided value. If the key already + * exists in the array, it is overwritten. + * @memberof AssociativeArray + * + * @param {String} key A unique identifier. + * @param {Object} value The value to associate with the provided key. + */ AssociativeArray.prototype.set = function(key, value) { + //>>includeStart('debug', pragmas.debug); + if (typeof key !== 'string') { + throw new DeveloperError('key is required to be a string.'); + } + //>>includeEnd('debug'); + this.remove(key); this._hash[key] = value; this._array.push(value); }; + /** + * Retrieve the value associated with the provided key. + * @memberof AssociativeArray + * + * @param {String} key The key whose value to retrieve. + * @returns {Object} The associated value, or undefined if the key does not exist in the collection. + */ AssociativeArray.prototype.get = function(key) { + //>>includeStart('debug', pragmas.debug); + if (!defined(key)) { + throw new DeveloperError('key is required.'); + } + //>>includeEnd('debug'); return this._hash[key]; }; - AssociativeArray.prototype.getCount = function() { - return this._array.length; - }; - - AssociativeArray.prototype.getValues = function() { - return this._array; - }; - + /** + * Removes a value from the collection. + * @memberof AssociativeArray + * + * @returns {Boolean} True if the value was removed, false if the key was not in the collection. + */ AssociativeArray.prototype.remove = function(key) { + //>>includeStart('debug', pragmas.debug); + if (!defined(key)) { + throw new DeveloperError('key is required.'); + } + //>>includeEnd('debug'); + var hasValue = defined(this._hash[key]); if (hasValue) { var array = this._array; @@ -38,6 +102,10 @@ define(['./defined', return hasValue; }; + /** + * Clears the collection. + * @memberof AssociativeArray + */ AssociativeArray.prototype.removeAll = function() { this._hash = {}; this._array.length = 0; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 9a879d0911d8..429f7976aca1 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -49,14 +49,14 @@ define(['../Core/defined', }; DynamicGeometryBatch.prototype.update = function(time) { - var geometries = this._dynamicUpdaters.getValues(); + var geometries = this._dynamicUpdaters.values; for (var i = 0, len = geometries.length; i < len; i++) { geometries[i].update(time); } }; DynamicGeometryBatch.prototype.removeAllPrimitives = function() { - var geometries = this._dynamicUpdaters.getValues(); + var geometries = this._dynamicUpdaters.values; for (var i = 0, len = geometries.length; i < len; i++) { geometries[i].destroy(); } @@ -263,7 +263,7 @@ define(['../Core/defined', } this._outlineBatch.removeAllPrimitives(); - var subscriptions = this._subscriptions.getValues(); + var subscriptions = this._subscriptions.values; var len = subscriptions.length; for (var i = 0; i < len; i++) { subscriptions[i](); diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 935fe13b3e48..2c63a84d2235 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -58,7 +58,7 @@ define(['../Core/Color', if (defined(primitive)) { primitives.remove(primitive); } - var geometry = this.geometry.getValues(); + var geometry = this.geometry.values; if (geometry.length > 0) { primitive = new Primitive({ asynchronous : true, @@ -75,7 +75,7 @@ define(['../Core/Color', this.primitive = primitive; this.createPrimitive = false; } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ - var updatersWithAttributes = this.updatersWithAttributes.getValues(); + var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 8c5aae52fd70..82bc5dcdcdd3 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -69,7 +69,7 @@ define(['../Core/defined', Batch.prototype.update = function(time) { var primitive = this.primitive; var primitives = this.primitives; - var geometries = this.geometry.getValues(); + var geometries = this.geometry.values; if (this.createPrimitive) { if (defined(primitive)) { primitives.remove(primitive); @@ -93,7 +93,7 @@ define(['../Core/defined', } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ this.primitive.appearance.material = MaterialProperty.getValue(time, this.materialProperty, this.material); - var updatersWithAttributes = this.updatersWithAttributes.getValues(); + var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; @@ -148,7 +148,7 @@ define(['../Core/defined', for (var i = length - 1; i >= 0; i--) { var item = items[i]; if (item.remove(updater)) { - if (item.updaters.getCount() === 0) { + if (item.updaters.count === 0) { items.splice(i, 1); item.destroy(); } @@ -166,7 +166,7 @@ define(['../Core/defined', var item = items[i]; if (item.invalidated) { items.splice(i, 1); - var updaters = item.updaters.getValues(); + var updaters = item.updaters.values; var updatersLength = updaters.length; for (var h = 0; h < updatersLength; i++) { this.add(updaters[h]); diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 8d48d0322225..6c3dda66e690 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -58,7 +58,7 @@ define(['../Core/Color', if (defined(primitive)) { primitives.remove(primitive); } - var geometry = this.geometry.getValues(); + var geometry = this.geometry.values; if (geometry.length > 0) { primitive = new Primitive({ asynchronous : true, @@ -74,7 +74,7 @@ define(['../Core/Color', this.primitive = primitive; this.createPrimitive = false; } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ - var updatersWithAttributes = this.updatersWithAttributes.getValues(); + var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; diff --git a/Specs/Core/AssociativeArraySpec.js b/Specs/Core/AssociativeArraySpec.js new file mode 100644 index 000000000000..a15a7873c567 --- /dev/null +++ b/Specs/Core/AssociativeArraySpec.js @@ -0,0 +1,72 @@ +/*global defineSuite*/ +defineSuite(['Core/AssociativeArray'], function(AssociativeArray) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('constructor has expected default values', function() { + var associativeArray = new AssociativeArray(); + expect(associativeArray.count).toEqual(0); + expect(associativeArray.values).toEqual([]); + }); + + it('can manipulate values', function() { + var associativeArray = new AssociativeArray(); + + associativeArray.set('key1', 1); + associativeArray.set('key2', 2); + associativeArray.set('key3', 3); + + expect(associativeArray.get('key1')).toEqual(1); + expect(associativeArray.get('key2')).toEqual(2); + expect(associativeArray.get('key3')).toEqual(3); + expect(associativeArray.count).toEqual(3); + + var values = associativeArray.values; + expect(values).toContain(1); + expect(values).toContain(2); + expect(values).toContain(3); + expect(values.length).toEqual(3); + + associativeArray.set('key2', 4); + expect(associativeArray.count).toEqual(3); + + expect(values).toContain(1); + expect(values).not.toContain(2); + expect(values).toContain(4); + expect(values).toContain(3); + expect(values.length).toEqual(3); + + expect(associativeArray.remove('key1')).toBe(true); + expect(associativeArray.get('key1')).toBeUndefined(); + expect(values).not.toContain(1); + expect(values).toContain(4); + expect(values).toContain(3); + expect(values.length).toEqual(2); + expect(associativeArray.remove('key1')).toBe(false); + + associativeArray.removeAll(); + expect(associativeArray.count).toEqual(0); + expect(associativeArray.values).toEqual([]); + }); + + it('set throws with undefined key', function() { + var associativeArray = new AssociativeArray(); + expect(function() { + associativeArray.set(undefined, 1); + }).toThrowDeveloperError(); + }); + + it('get throws with undefined key', function() { + var associativeArray = new AssociativeArray(); + expect(function() { + associativeArray.get(undefined); + }).toThrowDeveloperError(); + }); + + it('remove throws with undefined key', function() { + var associativeArray = new AssociativeArray(); + expect(function() { + associativeArray.remove(undefined); + }).toThrowDeveloperError(); + }); +}); From d26103b2bc75505862aa13efe459555980fc08d0 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 12 Feb 2014 17:10:46 -0500 Subject: [PATCH 42/81] Cleanup and specs. --- Source/DynamicScene/ColorMaterialProperty.js | 9 ++++++--- Source/DynamicScene/CompositeMaterialProperty.js | 11 ++++++++--- Source/DynamicScene/CompositePositionProperty.js | 11 ++++++++--- Specs/DynamicScene/ColorMaterialPropertySpec.js | 6 ++++-- Specs/DynamicScene/CompositeMaterialPropertySpec.js | 3 +++ Specs/DynamicScene/CompositePositionPropertySpec.js | 3 +++ 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index f04adde79cfd..27f3ace9c748 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -18,6 +18,9 @@ define(['../Core/Color', /** * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. + * + * @param {Color} [color=Color.WHITE] The material color. + * * @alias ColorMaterialProperty * @constructor */ @@ -115,14 +118,14 @@ define(['../Core/Color', */ ColorMaterialProperty.prototype.equals = function(other) { return this === other || // - (other instanceof ColorMaterialProperty && // - Property.equals(this._color, other._color)); + (other instanceof ColorMaterialProperty && // + Property.equals(this._color, other._color)); }; /** * @private */ - ColorMaterialProperty.prototype._raiseDefinitionChanged = function(){ + ColorMaterialProperty.prototype._raiseDefinitionChanged = function() { this._definitionChanged.raiseEvent(this); }; diff --git a/Source/DynamicScene/CompositeMaterialProperty.js b/Source/DynamicScene/CompositeMaterialProperty.js index 7c9a3d5b8189..92c5bc4424a3 100644 --- a/Source/DynamicScene/CompositeMaterialProperty.js +++ b/Source/DynamicScene/CompositeMaterialProperty.js @@ -23,9 +23,7 @@ define(['../Core/defined', var CompositeMaterialProperty = function() { this._definitionChanged = new Event(); this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); + this._composite.definitionChanged.addEventListener(CompositeMaterialProperty.prototype._raiseDefinitionChanged, this); }; defineProperties(CompositeMaterialProperty.prototype, { @@ -122,5 +120,12 @@ define(['../Core/defined', this._composite.equals(other._composite, Property.equals)); }; + /** + * @private + */ + CompositeMaterialProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + return CompositeMaterialProperty; }); \ No newline at end of file diff --git a/Source/DynamicScene/CompositePositionProperty.js b/Source/DynamicScene/CompositePositionProperty.js index 6d95a56910c2..9793b26e2a15 100644 --- a/Source/DynamicScene/CompositePositionProperty.js +++ b/Source/DynamicScene/CompositePositionProperty.js @@ -28,9 +28,7 @@ define(['../Core/defaultValue', this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); this._definitionChanged = new Event(); this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); + this._composite.definitionChanged.addEventListener(CompositePositionProperty.prototype._raiseDefinitionChanged, this); }; defineProperties(CompositePositionProperty.prototype, { @@ -140,5 +138,12 @@ define(['../Core/defaultValue', this._composite.equals(other._composite, Property.equals)); }; + /** + * @private + */ + CompositePositionProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + return CompositePositionProperty; }); \ No newline at end of file diff --git a/Specs/DynamicScene/ColorMaterialPropertySpec.js b/Specs/DynamicScene/ColorMaterialPropertySpec.js index bf614d19f636..90d50b17e903 100644 --- a/Specs/DynamicScene/ColorMaterialPropertySpec.js +++ b/Specs/DynamicScene/ColorMaterialPropertySpec.js @@ -20,9 +20,11 @@ defineSuite(['DynamicScene/ColorMaterialProperty', expect(property.color).toBeDefined(); expect(property.getType()).toEqual('Color'); expect(property.isConstant).toBe(true); + expect(property.getValue().color).toEqual(Color.WHITE); - var result = property.getValue(); - expect(result.color).toEqual(Color.WHITE); + property = new ColorMaterialProperty(Color.BLACK); + expect(property.color).toBeDefined(); + expect(property.getValue().color).toEqual(Color.BLACK); }); it('works with constant values', function() { diff --git a/Specs/DynamicScene/CompositeMaterialPropertySpec.js b/Specs/DynamicScene/CompositeMaterialPropertySpec.js index 156b5e942a8c..e27a8ff63364 100644 --- a/Specs/DynamicScene/CompositeMaterialPropertySpec.js +++ b/Specs/DynamicScene/CompositeMaterialPropertySpec.js @@ -20,6 +20,7 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', it('default constructor has expected values', function() { var property = new CompositeMaterialProperty(); expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); + expect(property.isConstant).toBe(true); expect(property.getType(new JulianDate())).toBeUndefined(); expect(property.getValue(new JulianDate())).toBeUndefined(); }); @@ -31,6 +32,7 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', var property = new CompositeMaterialProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var result1 = property.getValue(interval1.start); expect(property.getType(interval1.start)).toEqual('Color'); @@ -50,6 +52,7 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', var property = new CompositeMaterialProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var expected = {}; var result1 = property.getValue(interval1.start, expected); diff --git a/Specs/DynamicScene/CompositePositionPropertySpec.js b/Specs/DynamicScene/CompositePositionPropertySpec.js index 925392616bc9..503b8500309b 100644 --- a/Specs/DynamicScene/CompositePositionPropertySpec.js +++ b/Specs/DynamicScene/CompositePositionPropertySpec.js @@ -24,6 +24,7 @@ defineSuite(['DynamicScene/CompositePositionProperty', expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); expect(property.getValue(new JulianDate())).toBeUndefined(); expect(property.referenceFrame).toBe(ReferenceFrame.FIXED); + expect(property.isConstant).toBe(true); }); it('constructor sets expected values', function() { @@ -45,6 +46,7 @@ defineSuite(['DynamicScene/CompositePositionProperty', var property = new CompositePositionProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var result1 = property.getValue(interval1.start); expect(result1).not.toBe(interval1.data.getValue(interval1.start)); @@ -62,6 +64,7 @@ defineSuite(['DynamicScene/CompositePositionProperty', var property = new CompositePositionProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var expected = new Cartesian3(); var result1 = property.getValue(interval1.start, expected); From e2a90bce0a896ebe96784fad045c8938042d6eb9 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 13 Feb 2014 10:40:33 -0500 Subject: [PATCH 43/81] Simplify interval based Property objects Remove the use of `wrapFunction` to add the required features to `TimeIntervalCollection` and add notification support to `TimeIntervalCollection` directly. --- Source/Core/TimeIntervalCollection.js | 24 ++++++++++++- Source/DynamicScene/CompositeProperty.js | 35 ++++++++----------- .../TimeIntervalCollectionPositionProperty.js | 31 +++++++--------- .../TimeIntervalCollectionProperty.js | 31 +++++++--------- Specs/Core/TimeIntervalCollectionSpec.js | 21 +++++++++++ Specs/DynamicScene/GeometryVisualizerSpec.js | 2 +- 6 files changed, 83 insertions(+), 61 deletions(-) diff --git a/Source/Core/TimeIntervalCollection.js b/Source/Core/TimeIntervalCollection.js index d0af394944b9..8985e75a5c08 100644 --- a/Source/Core/TimeIntervalCollection.js +++ b/Source/Core/TimeIntervalCollection.js @@ -2,12 +2,14 @@ define([ './defined', './DeveloperError', + './Event', './binarySearch', './TimeInterval', './JulianDate' ], function( defined, DeveloperError, + Event, binarySearch, TimeInterval, JulianDate) { @@ -28,6 +30,17 @@ define([ */ var TimeIntervalCollection = function() { this._intervals = []; + this._intervalsChanged = new Event(); + }; + + /** + * Gets an event that is raised whenever the collection of intervals change. + * @memberof TimeIntervalCollection + * + * @returns {Event} The event + */ + TimeIntervalCollection.prototype.getChangedEvent = function() { + return this._intervalsChanged; }; /** @@ -117,7 +130,10 @@ define([ * @memberof TimeIntervalCollection */ TimeIntervalCollection.prototype.clear = function() { - this._intervals = []; + if (this._intervals.length > 0) { + this._intervals.length = 0; + this._intervalsChanged.raiseEvent(this); + } }; /** @@ -267,6 +283,7 @@ define([ if (thisIntervals.length === 0 || interval.start.greaterThan(thisIntervals[thisIntervals.length - 1].stop)) { thisIntervals.push(interval); + this._intervalsChanged.raiseEvent(this); return; } @@ -382,6 +399,7 @@ define([ // Add the new interval thisIntervals.splice(index, 0, interval); + this._intervalsChanged.raiseEvent(this); } }; @@ -489,6 +507,10 @@ define([ thisIntervals[index] = new TimeInterval(intervalStop, indexInterval.stop, !intervalIsStopIncluded, indexInterval.isStopIncluded, indexInterval.data); } + if (result) { + this._intervalsChanged.raiseEvent(this); + } + return result; }; diff --git a/Source/DynamicScene/CompositeProperty.js b/Source/DynamicScene/CompositeProperty.js index 48b88f76f0bb..d22143792878 100644 --- a/Source/DynamicScene/CompositeProperty.js +++ b/Source/DynamicScene/CompositeProperty.js @@ -5,8 +5,7 @@ define(['./Property', '../Core/DeveloperError', '../Core/Event', '../Core/EventHelper', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' + '../Core/TimeIntervalCollection' ], function( Property, defined, @@ -14,8 +13,7 @@ define(['./Property', DeveloperError, Event, EventHelper, - TimeIntervalCollection, - wrapFunction) { + TimeIntervalCollection) { "use strict"; function subscribeAll(property, eventHelper, definitionChanged, intervals) { @@ -58,23 +56,10 @@ define(['./Property', * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', false, false, sampledProperty)); */ var CompositeProperty = function() { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var eventHelper = new EventHelper(); - var intervalsChanged = function() { - subscribeAll(that, eventHelper, definitionChanged, intervals); - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, intervalsChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, intervalsChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, intervalsChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; + this._eventHelper = new EventHelper(); + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.getChangedEvent().addEventListener(CompositeProperty.prototype._intervalsChanged, this); }; defineProperties(CompositeProperty.prototype, { @@ -150,5 +135,13 @@ define(['./Property', this._intervals.equals(other._intervals, Property.equals)); }; + /** + * @private + */ + CompositeProperty.prototype._intervalsChanged = function() { + subscribeAll(this, this._eventHelper, this._definitionChanged, this._intervals); + this._definitionChanged.raiseEvent(this); + }; + return CompositeProperty; }); \ No newline at end of file diff --git a/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js b/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js index 32c6adbc5554..aaf964212cef 100644 --- a/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js +++ b/Source/DynamicScene/TimeIntervalCollectionPositionProperty.js @@ -7,8 +7,7 @@ define(['./PositionProperty', '../Core/DeveloperError', '../Core/Event', '../Core/ReferenceFrame', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' + '../Core/TimeIntervalCollection' ], function( PositionProperty, Property, @@ -18,8 +17,7 @@ define(['./PositionProperty', DeveloperError, Event, ReferenceFrame, - TimeIntervalCollection, - wrapFunction) { + TimeIntervalCollection) { "use strict"; /** @@ -31,21 +29,9 @@ define(['./PositionProperty', * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. */ var TimeIntervalCollectionPositionProperty = function(referenceFrame) { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var raiseDefinitionChanged = function() { - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.getChangedEvent().addEventListener(TimeIntervalCollectionPositionProperty.prototype._intervalsChanged, this); this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); }; @@ -149,5 +135,12 @@ define(['./PositionProperty', this._referenceFrame === other._referenceFrame); }; + /** + * @private + */ + TimeIntervalCollectionPositionProperty.prototype._intervalsChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + return TimeIntervalCollectionPositionProperty; }); \ No newline at end of file diff --git a/Source/DynamicScene/TimeIntervalCollectionProperty.js b/Source/DynamicScene/TimeIntervalCollectionProperty.js index cc841ec9d432..92c6de5f0d90 100644 --- a/Source/DynamicScene/TimeIntervalCollectionProperty.js +++ b/Source/DynamicScene/TimeIntervalCollectionProperty.js @@ -5,8 +5,7 @@ define(['./Property', '../Core/DeveloperError', '../Core/Enumeration', '../Core/Event', - '../Core/TimeIntervalCollection', - '../Core/wrapFunction' + '../Core/TimeIntervalCollection' ], function( Property, defined, @@ -14,8 +13,7 @@ define(['./Property', DeveloperError, Enumeration, Event, - TimeIntervalCollection, - wrapFunction) { + TimeIntervalCollection) { "use strict"; /** @@ -56,21 +54,9 @@ define(['./Property', * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601('2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', true, false, myObject2)); */ var TimeIntervalCollectionProperty = function() { - var intervals = new TimeIntervalCollection(); - var definitionChanged = new Event(); - - //For now, we patch our instance of TimeIntervalCollection to raise our definitionChanged event. - //We might want to consider adding events to TimeIntervalCollection itself for us to listen to, - var that = this; - var raiseDefinitionChanged = function() { - definitionChanged.raiseEvent(that); - }; - intervals.addInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.addInterval); - intervals.removeInterval = wrapFunction(intervals, raiseDefinitionChanged, intervals.removeInterval); - intervals.clear = wrapFunction(intervals, raiseDefinitionChanged, intervals.clear); - - this._intervals = intervals; - this._definitionChanged = definitionChanged; + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.getChangedEvent().addEventListener(TimeIntervalCollectionProperty.prototype._intervalsChanged, this); }; defineProperties(TimeIntervalCollectionProperty.prototype, { @@ -148,5 +134,12 @@ define(['./Property', this._intervals.equals(other._intervals, Property.equals)); }; + /** + * @private + */ + TimeIntervalCollectionProperty.prototype._intervalsChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + return TimeIntervalCollectionProperty; }); diff --git a/Specs/Core/TimeIntervalCollectionSpec.js b/Specs/Core/TimeIntervalCollectionSpec.js index 1a5bc3a99b43..a84cc905518f 100644 --- a/Specs/Core/TimeIntervalCollectionSpec.js +++ b/Specs/Core/TimeIntervalCollectionSpec.js @@ -28,6 +28,7 @@ defineSuite([ expect(intervals.getStart()).toBeUndefined(); expect(intervals.getStop()).toBeUndefined(); expect(intervals.isEmpty()).toEqual(true); + expect(intervals.getChangedEvent()).toBeDefined(); }); it('contains works for a simple interval collection.', function() { @@ -567,4 +568,24 @@ defineSuite([ intervals.intersectInterval(undefined); }).toThrowDeveloperError(); }); + + it('changed event is raised as expected', function() { + var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true); + + var intervals = new TimeIntervalCollection(); + var changedEvent = intervals.getChangedEvent(); + spyOn(changedEvent, 'raiseEvent'); + + intervals.addInterval(interval); + expect(changedEvent.raiseEvent).toHaveBeenCalledWith(intervals); + changedEvent.raiseEvent.reset(); + + intervals.removeInterval(interval); + expect(changedEvent.raiseEvent).toHaveBeenCalledWith(intervals); + + intervals.addInterval(interval); + changedEvent.raiseEvent.reset(); + intervals.clear(); + expect(changedEvent.raiseEvent).toHaveBeenCalledWith(intervals); + }); }); diff --git a/Specs/DynamicScene/GeometryVisualizerSpec.js b/Specs/DynamicScene/GeometryVisualizerSpec.js index 15d4dedeabc2..47cdfd51a5b5 100644 --- a/Specs/DynamicScene/GeometryVisualizerSpec.js +++ b/Specs/DynamicScene/GeometryVisualizerSpec.js @@ -147,4 +147,4 @@ defineSuite(['DynamicScene/GeometryVisualizer', return new GeometryVisualizer(EllipseGeometryUpdater, undefined, objects); }).toThrowDeveloperError(); }); -}); \ No newline at end of file +}, 'WebGL'); \ No newline at end of file From 01f0f434eb4fb334f9d9712da9f52e4af714f7b6 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 14 Feb 2014 00:59:02 -0500 Subject: [PATCH 44/81] Simplify createDynamicPropertyDescriptor usage Also, add private variables to object constructors which were being added by createDynamicPropertyDescriptor (thus slowing down performance). --- .../DynamicScene/ConstantPositionProperty.js | 4 +- Source/DynamicScene/DynamicBillboard.js | 46 +++++++++----- Source/DynamicScene/DynamicClock.js | 12 ++-- Source/DynamicScene/DynamicCone.js | 39 ++++++++---- Source/DynamicScene/DynamicEllipse.js | 40 +++++++----- Source/DynamicScene/DynamicEllipsoid.js | 24 +++++--- Source/DynamicScene/DynamicLabel.js | 42 ++++++++----- Source/DynamicScene/DynamicObject.js | 61 ++++++++++++------- Source/DynamicScene/DynamicPath.js | 25 +++++--- Source/DynamicScene/DynamicPoint.js | 18 ++++-- Source/DynamicScene/DynamicPolygon.js | 28 +++++---- Source/DynamicScene/DynamicPolyline.js | 9 ++- Source/DynamicScene/DynamicPyramid.js | 21 ++++--- Source/DynamicScene/DynamicVector.js | 15 +++-- Source/DynamicScene/PropertyArray.js | 1 - .../createDynamicPropertyDescriptor.js | 19 +++--- Specs/DynamicScene/CompositePropertySpec.js | 3 + 17 files changed, 263 insertions(+), 144 deletions(-) diff --git a/Source/DynamicScene/ConstantPositionProperty.js b/Source/DynamicScene/ConstantPositionProperty.js index 6ca1ac4d2854..0ecbee155e9b 100644 --- a/Source/DynamicScene/ConstantPositionProperty.js +++ b/Source/DynamicScene/ConstantPositionProperty.js @@ -40,7 +40,7 @@ define(['./PositionProperty', /** * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. - * @memberof PositionProperty.prototype + * @memberof ConstantPositionProperty.prototype * @type {Boolean} */ isConstant : { @@ -52,7 +52,7 @@ define(['./PositionProperty', * Gets the event that is raised whenever the definition of this property changes. * The definition is considered to have changed if a call to getValue would return * a different result for the same time. - * @memberof PositionProperty.prototype + * @memberof ConstantPositionProperty.prototype * @type {Event} */ definitionChanged : { diff --git a/Source/DynamicScene/DynamicBillboard.js b/Source/DynamicScene/DynamicBillboard.js index 69eb6aa5dc59..957bb5974856 100644 --- a/Source/DynamicScene/DynamicBillboard.js +++ b/Source/DynamicScene/DynamicBillboard.js @@ -22,20 +22,35 @@ define(['../Core/defaultValue', */ var DynamicBillboard = function() { this._image = undefined; + this._imageSubscription = undefined; this._width = undefined; + this._widthSubscription = undefined; this._height = undefined; + this._heightSubscription = undefined; this._scale = undefined; + this._scaleSubscription = undefined; this._rotation = undefined; + this._rotationSubscription = undefined; this._alignedAxis = undefined; + this._alignedAxisSubscription = undefined; this._horizontalOrigin = undefined; + this._horizontalOriginSubscription = undefined; this._verticalOrigin = undefined; + this._verticalOriginSubscription = undefined; this._color = undefined; + this._colorSubscription = undefined; this._eyeOffset = undefined; + this._eyeOffsetSubscription = undefined; this._pixelOffset = undefined; + this._pixelOffsetSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._scaleByDistance = undefined; + this._scaleByDistanceSubscription = undefined; this._translucencyByDistance = undefined; + this._translucencyByDistanceSubscription = undefined; this._pixelOffsetScaleByDistance = undefined; + this._pixelOffsetScaleByDistanceSubscription = undefined; this._definitionChanged = new Event(); }; @@ -56,70 +71,70 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - image : createDynamicPropertyDescriptor('image', '_image'), + image : createDynamicPropertyDescriptor('image'), /** * Gets or sets the numeric {@link Property} specifying the billboard's scale. * @memberof DynamicBillboard.prototype * @type {Property} */ - scale : createDynamicPropertyDescriptor('scale', '_scale'), + scale : createDynamicPropertyDescriptor('scale'), /** * Gets or sets the numeric {@link Property} specifying the billboard's rotation. * @memberof DynamicBillboard.prototype * @type {Property} */ - rotation : createDynamicPropertyDescriptor('rotation', '_rotation'), + rotation : createDynamicPropertyDescriptor('rotation'), /** * Gets or sets the {@link Cartesian3} {@link Property} specifying the billboard rotation's aligned axis. * @memberof DynamicBillboard.prototype * @type {Property} */ - alignedAxis : createDynamicPropertyDescriptor('alignedAxis', '_alignedAxis'), + alignedAxis : createDynamicPropertyDescriptor('alignedAxis'), /** * Gets or sets the {@link HorizontalOrigin} {@link Property} specifying the billboard's horizontal origin. * @memberof DynamicBillboard.prototype * @type {Property} */ - horizontalOrigin : createDynamicPropertyDescriptor('horizontalOrigin', '_horizontalOrigin'), + horizontalOrigin : createDynamicPropertyDescriptor('horizontalOrigin'), /** * Gets or sets the {@link VerticalOrigin} {@link Property} specifying the billboard's vertical origin. * @memberof DynamicBillboard.prototype * @type {Property} */ - verticalOrigin : createDynamicPropertyDescriptor('verticalOrigin', '_verticalOrigin'), + verticalOrigin : createDynamicPropertyDescriptor('verticalOrigin'), /** * Gets or sets the {@link Color} {@link Property} specifying the billboard's color. * @memberof DynamicBillboard.prototype * @type {Property} */ - color : createDynamicPropertyDescriptor('color', '_color'), + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the {@link Cartesian3} {@link Property} specifying the billboard's eye offset. * @memberof DynamicBillboard.prototype * @type {Property} */ - eyeOffset : createDynamicPropertyDescriptor('eyeOffset', '_eyeOffset'), + eyeOffset : createDynamicPropertyDescriptor('eyeOffset'), /** * Gets or sets the {@link Cartesian2} {@link Property} specifying the billboard's pixel offset. * @memberof DynamicBillboard.prototype * @type {Property} */ - pixelOffset : createDynamicPropertyDescriptor('pixelOffset', '_pixelOffset'), + pixelOffset : createDynamicPropertyDescriptor('pixelOffset'), /** * Gets or sets the boolean {@link Property} specifying the billboard's visibility. * @memberof DynamicBillboard.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the numeric {@link Property} specifying the billboard's width in pixels. @@ -127,7 +142,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - width : createDynamicPropertyDescriptor('width', '_width'), + width : createDynamicPropertyDescriptor('width'), /** * Gets or sets the numeric {@link Property} specifying the billboard's height in pixels. @@ -135,7 +150,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - height : createDynamicPropertyDescriptor('height', '_height'), + height : createDynamicPropertyDescriptor('height'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to scale billboards based on distance. @@ -143,7 +158,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - scaleByDistance : createDynamicPropertyDescriptor('scaleByDistance', '_scaleByDistance'), + scaleByDistance : createDynamicPropertyDescriptor('scaleByDistance'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to set translucency based on distance. @@ -151,7 +166,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - translucencyByDistance : createDynamicPropertyDescriptor('translucencyByDistance', '_translucencyByDistance'), + translucencyByDistance : createDynamicPropertyDescriptor('translucencyByDistance'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to set pixel offset scaling based on distance. @@ -159,8 +174,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - pixelOffsetScaleByDistance : createDynamicPropertyDescriptor('pixelOffsetScaleByDistance', '_pixelOffsetScaleByDistance') - + pixelOffsetScaleByDistance : createDynamicPropertyDescriptor('pixelOffsetScaleByDistance') }); /** diff --git a/Source/DynamicScene/DynamicClock.js b/Source/DynamicScene/DynamicClock.js index f403079de4f0..6a0c079c1fda 100644 --- a/Source/DynamicScene/DynamicClock.js +++ b/Source/DynamicScene/DynamicClock.js @@ -51,35 +51,35 @@ define(['../Core/Clock', * @memberof DynamicClock.prototype * @type {JulianDate} */ - startTime : createDynamicPropertyDescriptor('startTime', '_startTime'), + startTime : createDynamicPropertyDescriptor('startTime'), /** * Gets or sets the stop time of the clock to use when looping or clamped. * @memberof DynamicClock.prototype * @type {JulianDate} */ - stopTime : createDynamicPropertyDescriptor('stopTime', '_stopTime'), + stopTime : createDynamicPropertyDescriptor('stopTime'), /** * Gets or sets the initial time to use when switching to this clock. * @memberof DynamicClock.prototype * @type {JulianDate} */ - currentTime : createDynamicPropertyDescriptor('currentTime', '_currentTime'), + currentTime : createDynamicPropertyDescriptor('currentTime'), /** * Gets or sets how the clock should behave when startTime or stopTime is reached. * @memberof DynamicClock.prototype * @type {ClockRange} */ - clockRange : createDynamicPropertyDescriptor('clockRange', '_clockRange'), + clockRange : createDynamicPropertyDescriptor('clockRange'), /** * Gets or sets if clock advancement is frame dependent or system clock dependent. * @memberof DynamicClock.prototype * @type {ClockStep} */ - clockStep : createDynamicPropertyDescriptor('clockStep', '_clockStep'), + clockStep : createDynamicPropertyDescriptor('clockStep'), /** * Gets or sets how much time advances with each tick, negative values allow for advancing backwards. @@ -89,7 +89,7 @@ define(['../Core/Clock', * @memberof DynamicClock.prototype * @type {Number} */ - multiplier : createDynamicPropertyDescriptor('multiplier', '_multiplier') + multiplier : createDynamicPropertyDescriptor('multiplier') }); /** diff --git a/Source/DynamicScene/DynamicCone.js b/Source/DynamicScene/DynamicCone.js index 2a0a9531cb6e..dc346ff945d5 100644 --- a/Source/DynamicScene/DynamicCone.js +++ b/Source/DynamicScene/DynamicCone.js @@ -22,18 +22,31 @@ define(['../Core/defaultValue', */ var DynamicCone = function() { this._minimumClockAngle = undefined; + this._minimumClockAngleSubscription = undefined; this._maximumClockAngle = undefined; + this._maximumClockAngleSubscription = undefined; this._innerHalfAngle = undefined; + this._innerHalfAngleSubscription = undefined; this._outerHalfAngle = undefined; + this._outerHalfAngleSubscription = undefined; this._capMaterial = undefined; + this._capMaterialSubscription = undefined; this._innerMaterial = undefined; + this._innerMaterialSubscription = undefined; this._outerMaterial = undefined; + this._outerMaterialSubscription = undefined; this._silhouetteMaterial = undefined; + this._silhouetteMaterialSubscription = undefined; this._intersectionColor = undefined; + this._intersectionColorSubscription = undefined; this._intersectionWidth = undefined; + this._intersectionWidthSubscription = undefined; this._showIntersection = undefined; + this._showIntersectionSubscription = undefined; this._radius = undefined; + this._radiusSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._definitionChanged = new Event(); }; @@ -54,91 +67,91 @@ define(['../Core/defaultValue', * @memberof DynamicCone.prototype * @type {Property} */ - minimumClockAngle : createDynamicPropertyDescriptor('minimumClockAngle', '_minimumClockAngle'), + minimumClockAngle : createDynamicPropertyDescriptor('minimumClockAngle'), /** * Gets or sets the numeric {@link Property} specifying the the cone's maximum clock angle. * @memberof DynamicCone.prototype * @type {Property} */ - maximumClockAngle : createDynamicPropertyDescriptor('maximumClockAngle', '_maximumClockAngle'), + maximumClockAngle : createDynamicPropertyDescriptor('maximumClockAngle'), /** * Gets or sets the numeric {@link Property} specifying the the cone's inner half-angle. * @memberof DynamicCone.prototype * @type {Property} */ - innerHalfAngle : createDynamicPropertyDescriptor('innerHalfAngle', '_innerHalfAngle'), + innerHalfAngle : createDynamicPropertyDescriptor('innerHalfAngle'), /** * Gets or sets the numeric {@link Property} specifying the the cone's outer half-angle. * @memberof DynamicCone.prototype * @type {Property} */ - outerHalfAngle : createDynamicPropertyDescriptor('outerHalfAngle', '_outerHalfAngle'), + outerHalfAngle : createDynamicPropertyDescriptor('outerHalfAngle'), /** * Gets or sets the {@link MaterialProperty} specifying the the cone's cap material. * @memberof DynamicCone.prototype * @type {MaterialProperty} */ - capMaterial : createDynamicPropertyDescriptor('capMaterial', '_capMaterial'), + capMaterial : createDynamicPropertyDescriptor('capMaterial'), /** * Gets or sets the {@link MaterialProperty} specifying the the cone's inner material. * @memberof DynamicCone.prototype * @type {MaterialProperty} */ - innerMaterial : createDynamicPropertyDescriptor('innerMaterial', '_innerMaterial'), + innerMaterial : createDynamicPropertyDescriptor('innerMaterial'), /** * Gets or sets the {@link MaterialProperty} specifying the the cone's outer material. * @memberof DynamicCone.prototype * @type {MaterialProperty} */ - outerMaterial : createDynamicPropertyDescriptor('outerMaterial', '_outerMaterial'), + outerMaterial : createDynamicPropertyDescriptor('outerMaterial'), /** * Gets or sets the {@link MaterialProperty} specifying the the cone's silhouette material. * @memberof DynamicCone.prototype * @type {MaterialProperty} */ - silhouetteMaterial : createDynamicPropertyDescriptor('silhouetteMaterial', '_silhouetteMaterial'), + silhouetteMaterial : createDynamicPropertyDescriptor('silhouetteMaterial'), /** * Gets or sets the {@link Color} {@link Property} specifying the color of the line formed by the intersection of the cone and other central bodies. * @memberof DynamicCone.prototype * @type {Property} */ - intersectionColor : createDynamicPropertyDescriptor('intersectionColor', '_intersectionColor'), + intersectionColor : createDynamicPropertyDescriptor('intersectionColor'), /** * Gets or sets the numeric {@link Property} specifying the width of the line formed by the intersection of the cone and other central bodies. * @memberof DynamicCone.prototype * @type {Property} */ - intersectionWidth : createDynamicPropertyDescriptor('intersectionWidth', '_intersectionWidth'), + intersectionWidth : createDynamicPropertyDescriptor('intersectionWidth'), /** * Gets or sets the boolean {@link Property} specifying the visibility of the line formed by the intersection of the cone and other central bodies. * @memberof DynamicCone.prototype * @type {Property} */ - showIntersection : createDynamicPropertyDescriptor('showIntersection', '_showIntersection'), + showIntersection : createDynamicPropertyDescriptor('showIntersection'), /** * Gets or sets the numeric {@link Property} specifying the radius of the cone's projection. * @memberof DynamicCone.prototype * @type {Property} */ - radius : createDynamicPropertyDescriptor('radius', '_radius'), + radius : createDynamicPropertyDescriptor('radius'), /** * Gets or sets the boolean {@link Property} specifying the visibility of the cone. * @memberof DynamicCone.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show') + show : createDynamicPropertyDescriptor('show') }); /** diff --git a/Source/DynamicScene/DynamicEllipse.js b/Source/DynamicScene/DynamicEllipse.js index 6e7ad8a93a36..ed257175a50b 100644 --- a/Source/DynamicScene/DynamicEllipse.js +++ b/Source/DynamicScene/DynamicEllipse.js @@ -28,18 +28,30 @@ define(['../Core/Cartesian3', */ var DynamicEllipse = function() { this._semiMajorAxis = undefined; + this._semiMajorAxisSubscription = undefined; this._semiMinorAxis = undefined; + this._semiMinorAxisSubscription = undefined; this._rotation = undefined; + this._rotationSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._material = undefined; + this._materialSubscription = undefined; this._height = undefined; + this._heightSubscription = undefined; this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; this._granularity = undefined; + this._granularitySubscription = undefined; this._stRotation = undefined; - this._definitionChanged = new Event(); + this._stRotationSubscription = undefined; this._outline = undefined; + this._outlineSubscription = undefined; this._outlineColor = undefined; + this._outlineColorSubscription = undefined; this._numberOfVerticalLines = undefined; + this._numberOfVerticalLinesSubscription = undefined; + this._definitionChanged = new Event(); }; defineProperties(DynamicEllipse.prototype, { @@ -59,35 +71,35 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - semiMajorAxis : createDynamicPropertyDescriptor('semiMajorAxis', '_semiMajorAxis'), + semiMajorAxis : createDynamicPropertyDescriptor('semiMajorAxis'), /** * Gets or sets the numeric {@link Property} specifying the ellipse's semi-minor-axis. * @memberof DynamicEllipse.prototype * @type {Property} */ - semiMinorAxis : createDynamicPropertyDescriptor('semiMinorAxis', '_semiMinorAxis'), + semiMinorAxis : createDynamicPropertyDescriptor('semiMinorAxis'), /** * Gets or sets the numeric {@link Property} specifying the ellipse's rotation. * @memberof DynamicEllipse.prototype * @type {Property} */ - rotation : createDynamicPropertyDescriptor('rotation', '_rotation'), + rotation : createDynamicPropertyDescriptor('rotation'), /** * Gets or sets the boolean {@link Property} specifying the polygon's visibility. * @memberof DynamicEllipse.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link MaterialProperty} specifying the appearance of the polygon. * @memberof DynamicEllipse.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material'), + material : createDynamicPropertyDescriptor('material'), /** * Gets or sets the Number {@link Property} specifying the height of the polygon. @@ -95,7 +107,7 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - height : createDynamicPropertyDescriptor('height', '_height'), + height : createDynamicPropertyDescriptor('height'), /** * Gets or sets the Number {@link Property} specifying the extruded height of the polygon. @@ -104,7 +116,7 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight', '_extrudedHeight'), + extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight'), /** * Gets or sets the Number {@link Property} specifying the sampling distance, in radians, @@ -112,7 +124,7 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - granularity : createDynamicPropertyDescriptor('granularity', '_granularity'), + granularity : createDynamicPropertyDescriptor('granularity'), /** * Gets or sets the Number {@link Property} specifying the rotation of the texture coordinates, @@ -120,28 +132,28 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - stRotation : createDynamicPropertyDescriptor('stRotation', '_stRotation'), + stRotation : createDynamicPropertyDescriptor('stRotation'), /** * Gets or sets the Boolean {@link Property} specifying whether the ellipse should be filled. * @memberof DynamicEllipse.prototype * @type {Property} */ - fill : createDynamicPropertyDescriptor('fill', '_fill'), + fill : createDynamicPropertyDescriptor('fill'), /** * Gets or sets the Boolean {@link Property} specifying whether the ellipse should be outlined. * @memberof DynamicEllipse.prototype * @type {Property} */ - outline : createDynamicPropertyDescriptor('outline', '_outline'), + outline : createDynamicPropertyDescriptor('outline'), /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicEllipse.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the Number {@link Property} specifying the number of vertical lines @@ -149,7 +161,7 @@ define(['../Core/Cartesian3', * @memberof DynamicEllipse.prototype * @type {Property} */ - numberOfVerticalLines : createDynamicPropertyDescriptor('numberOfVerticalLines', '_numberOfVerticalLines') + numberOfVerticalLines : createDynamicPropertyDescriptor('numberOfVerticalLines') }); /** diff --git a/Source/DynamicScene/DynamicEllipsoid.js b/Source/DynamicScene/DynamicEllipsoid.js index 668a0b06d922..918dff78b367 100644 --- a/Source/DynamicScene/DynamicEllipsoid.js +++ b/Source/DynamicScene/DynamicEllipsoid.js @@ -22,11 +22,17 @@ define(['../Core/defaultValue', */ var DynamicEllipsoid = function() { this._show = undefined; + this._showSubscription = undefined; this._radii = undefined; + this._radiiSubscription = undefined; this._material = undefined; + this._materialSubscription = undefined; this._stackPartitions = undefined; + this._stackPartitionsSubscription = undefined; this._slicePartitions = undefined; + this._slicePartitionsSubscription = undefined; this._subdivisions = undefined; + this._subdivisionsSubscription = undefined; this._definitionChanged = new Event(); }; @@ -47,63 +53,63 @@ define(['../Core/defaultValue', * @memberof DynamicEllipsoid.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link Cartesian3} {@link Property} specifying the radii of the ellipsoid. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - radii : createDynamicPropertyDescriptor('radii', '_radii'), + radii : createDynamicPropertyDescriptor('radii'), /** * Gets or sets the {@link MaterialProperty} specifying the appearance of the ellipsoid. * @memberof DynamicEllipsoid.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material'), + material : createDynamicPropertyDescriptor('material'), /** * Gets or sets the Boolean {@link Property} specifying whether the ellipsoid should be filled. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - fill : createDynamicPropertyDescriptor('fill', '_fill'), + fill : createDynamicPropertyDescriptor('fill'), /** * Gets or sets the Boolean {@link Property} specifying whether the ellipsoid should be outlined. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - outline : createDynamicPropertyDescriptor('outline', '_outline'), + outline : createDynamicPropertyDescriptor('outline'), /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the Number {@link Property} specifying the number of times to partition the ellipsoid into stacks. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - stackPartitions : createDynamicPropertyDescriptor('stackPartitions', '_stackPartitions'), + stackPartitions : createDynamicPropertyDescriptor('stackPartitions'), /** * Gets or sets the Number {@link Property} specifying the number of times to partition the ellipsoid into radial slices. * @memberof DynamicEllipsoid.prototype * @type {Property} */ - slicePartitions : createDynamicPropertyDescriptor('slicePartitions', '_slicePartitions'), + slicePartitions : createDynamicPropertyDescriptor('slicePartitions'), /** * Gets or sets the Number {@link Property} specifying the number of points per line, determining the granularity of the curvature . * @memberof DynamicEllipsoid.prototype * @type {Property} */ - subdivisions : createDynamicPropertyDescriptor('subdivisions', '_subdivisions') + subdivisions : createDynamicPropertyDescriptor('subdivisions') }); /** diff --git a/Source/DynamicScene/DynamicLabel.js b/Source/DynamicScene/DynamicLabel.js index 34534d7f1084..01b3a1b5c429 100644 --- a/Source/DynamicScene/DynamicLabel.js +++ b/Source/DynamicScene/DynamicLabel.js @@ -21,19 +21,33 @@ define(['../Core/defaultValue', */ var DynamicLabel = function() { this._text = undefined; + this._textSubscription = undefined; this._font = undefined; + this._fontSubscription = undefined; this._style = undefined; + this._styleSubscription = undefined; this._fillColor = undefined; + this._fillColorSubscription = undefined; this._outlineColor = undefined; + this._outlineColorSubscription = undefined; this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; this._horizontalOrigin = undefined; + this._horizontalOriginSubscription = undefined; this._verticalOrigin = undefined; + this._verticalOriginSubscription = undefined; this._eyeOffset = undefined; + this._eyeOffsetSubscription = undefined; this._pixelOffset = undefined; + this._pixelOffsetSubscription = undefined; this._scale = undefined; + this._scaleSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._translucencyByDistance = undefined; + this._translucencyByDistanceSubscription = undefined; this._pixelOffsetScaleByDistance = undefined; + this._pixelOffsetScaleByDistanceSubscription = undefined; this._definitionChanged = new Event(); }; @@ -54,84 +68,84 @@ define(['../Core/defaultValue', * @memberof DynamicLabel.prototype * @type {Property} */ - text : createDynamicPropertyDescriptor('text', '_text'), + text : createDynamicPropertyDescriptor('text'), /** * Gets or sets the string {@link Property} specifying the the label's font. * @memberof DynamicLabel.prototype * @type {Property} */ - font : createDynamicPropertyDescriptor('font', '_font'), + font : createDynamicPropertyDescriptor('font'), /** * Gets or sets the {@link LabelStyle} {@link Property} specifying the the label's style. * @memberof DynamicLabel.prototype * @type {Property} */ - style : createDynamicPropertyDescriptor('style', '_style'), + style : createDynamicPropertyDescriptor('style'), /** * Gets or sets the {@link Color} {@link Property} specifying the the label's fill color. * @memberof DynamicLabel.prototype * @type {Property} */ - fillColor : createDynamicPropertyDescriptor('fillColor', '_fillColor'), + fillColor : createDynamicPropertyDescriptor('fillColor'), /** * Gets or sets the {@link Color} {@link Property} specifying the the label's outline color. * @memberof DynamicLabel.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the numeric {@link Property} specifying the the label outline's width. * @memberof DynamicLabel.prototype * @type {Property} */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + outlineWidth : createDynamicPropertyDescriptor('outlineWidth'), /** * Gets or sets the {@link HorizontalOrigin} {@link Property} specifying the label's horizontal origin. * @memberof DynamicLabel.prototype * @type {Property} */ - horizontalOrigin : createDynamicPropertyDescriptor('horizontalOrigin', '_horizontalOrigin'), + horizontalOrigin : createDynamicPropertyDescriptor('horizontalOrigin'), /** * Gets or sets the {@link VerticalOrigin} {@link Property} specifying the label's vertical origin. * @memberof DynamicLabel.prototype * @type {Property} */ - verticalOrigin : createDynamicPropertyDescriptor('verticalOrigin', '_verticalOrigin'), + verticalOrigin : createDynamicPropertyDescriptor('verticalOrigin'), /** * Gets or sets the {@link Cartesian3} {@link Property} specifying the label's eye offset. * @memberof DynamicLabel.prototype * @type {Property} */ - eyeOffset : createDynamicPropertyDescriptor('eyeOffset', '_eyeOffset'), + eyeOffset : createDynamicPropertyDescriptor('eyeOffset'), /** * Gets or sets the {@link Cartesian2} {@link Property} specifying the label's pixel offset. * @memberof DynamicLabel.prototype * @type {Property} */ - pixelOffset : createDynamicPropertyDescriptor('pixelOffset', '_pixelOffset'), + pixelOffset : createDynamicPropertyDescriptor('pixelOffset'), /** * Gets or sets the numeric {@link Property} specifying the label's scale. * @memberof DynamicLabel.prototype * @type {Property} */ - scale : createDynamicPropertyDescriptor('scale', '_scale'), + scale : createDynamicPropertyDescriptor('scale'), /** * Gets or sets the boolean {@link Property} specifying the label's visibility. * @memberof DynamicLabel.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to set translucency based on distance. @@ -139,7 +153,7 @@ define(['../Core/defaultValue', * @memberof DynamicLabel.prototype * @type {Property} */ - translucencyByDistance : createDynamicPropertyDescriptor('translucencyByDistance', '_translucencyByDistance'), + translucencyByDistance : createDynamicPropertyDescriptor('translucencyByDistance'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to set pixel offset scaling based on distance. @@ -147,7 +161,7 @@ define(['../Core/defaultValue', * @memberof DynamicLabel.prototype * @type {Property} */ - pixelOffsetScaleByDistance : createDynamicPropertyDescriptor('pixelOffsetScaleByDistance', '_pixelOffsetScaleByDistance') + pixelOffsetScaleByDistance : createDynamicPropertyDescriptor('pixelOffsetScaleByDistance') }); diff --git a/Source/DynamicScene/DynamicObject.js b/Source/DynamicScene/DynamicObject.js index a046b16ecb96..af5f769e44c3 100644 --- a/Source/DynamicScene/DynamicObject.js +++ b/Source/DynamicScene/DynamicObject.js @@ -45,26 +45,43 @@ define(['../Core/createGuid', this._id = id; this._availability = undefined; + this._parent = undefined; + this._name = undefined; + this._definitionChanged = new Event(); + this._position = undefined; + this._positionSubscription = undefined; this._orientation = undefined; + this._orientationSubscription = undefined; this._billboard = undefined; + this._billboardSubscription = undefined; this._cone = undefined; + this._coneSubscription = undefined; this._ellipsoid = undefined; + this._ellipsoidSubscription = undefined; this._ellipse = undefined; + this._ellipseSubscription = undefined; this._label = undefined; - this._name = undefined; - this._parent = undefined; + this._labelSubscription = undefined; this._path = undefined; + this._pathSubscription = undefined; this._point = undefined; + this._pointSubscription = undefined; this._polygon = undefined; + this._polygonSubscription = undefined; this._polyline = undefined; + this._polylineSubscription = undefined; this._pyramid = undefined; + this._pyramidSubscription = undefined; this._vertexPositions = undefined; + this._vertexPositionsSubscription = undefined; this._vector = undefined; + this._vectorSubscription = undefined; this._viewFrom = undefined; + this._viewFromSubscription = undefined; this._description = undefined; + this._descriptionSubscription = undefined; - this._definitionChanged = new Event(); this._propertyNames = ['parent', 'position', 'orientation', 'billboard', // 'cone', 'ellipsoid', 'ellipse', 'label', 'path', 'point', 'polygon', // 'polyline', 'pyramid', 'vertexPositions', 'vector', 'viewFrom', 'description']; @@ -129,111 +146,111 @@ define(['../Core/createGuid', * @memberof DynamicObject.prototype * @type {TimeIntervalCollection} */ - availability : createDynamicPropertyDescriptor('availability', '_availability'), + availability : createDynamicPropertyDescriptor('availability'), /** * Gets or sets the position. * @memberof DynamicObject.prototype * @type {PositionProperty} */ - position : createDynamicPropertyDescriptor('position', '_position'), + position : createDynamicPropertyDescriptor('position'), /** * Gets or sets the orientation. * @memberof DynamicObject.prototype * @type {Property} */ - orientation : createDynamicPropertyDescriptor('orientation', '_orientation'), + orientation : createDynamicPropertyDescriptor('orientation'), /** * Gets or sets the suggested initial offset for viewing this object * with the camera. The offset is defined in the east-north-up reference frame. * @memberof DynamicObject.prototype * @type {Cartesian3} */ - viewFrom : createDynamicPropertyDescriptor('viewFrom', '_viewFrom'), + viewFrom : createDynamicPropertyDescriptor('viewFrom'), /** * Gets or sets the billboard. * @memberof DynamicObject.prototype * @type {DynamicBillboard} */ - billboard : createDynamicPropertyDescriptor('billboard', '_billboard'), + billboard : createDynamicPropertyDescriptor('billboard'), /** * Gets or sets the cone. * @memberof DynamicObject.prototype * @type {DynamicCone} */ - cone : createDynamicPropertyDescriptor('cone', '_cone'), + cone : createDynamicPropertyDescriptor('cone'), /** * Gets or sets the ellipsoid. * @memberof DynamicObject.prototype * @type {DynamicEllipsoid} */ - ellipsoid : createDynamicPropertyDescriptor('ellipsoid', '_ellipsoid'), + ellipsoid : createDynamicPropertyDescriptor('ellipsoid'), /** * Gets or sets the ellipse. * @memberof DynamicObject.prototype * @type {DynamicEllipse} */ - ellipse : createDynamicPropertyDescriptor('ellipse', '_ellipse'), + ellipse : createDynamicPropertyDescriptor('ellipse'), /** * Gets or sets the label. * @memberof DynamicObject.prototype * @type {DynamicLabel} */ - label : createDynamicPropertyDescriptor('label', '_label'), + label : createDynamicPropertyDescriptor('label'), /** * Gets or sets the parent object. * @memberof DynamicObject.prototype * @type {DynamicObject} */ - parent : createDynamicPropertyDescriptor('parent', '_parent'), + parent : createDynamicPropertyDescriptor('parent'), /** * Gets or sets the path. * @memberof DynamicObject.prototype * @type {DynamicPath} */ - path : createDynamicPropertyDescriptor('path', '_path'), + path : createDynamicPropertyDescriptor('path'), /** * Gets or sets the point graphic. * @memberof DynamicObject.prototype * @type {DynamicPoint} */ - point : createDynamicPropertyDescriptor('point', '_point'), + point : createDynamicPropertyDescriptor('point'), /** * Gets or sets the polygon. * @memberof DynamicObject.prototype * @type {DynamicPolygon} */ - polygon : createDynamicPropertyDescriptor('polygon', '_polygon'), + polygon : createDynamicPropertyDescriptor('polygon'), /** * Gets or sets the polyline. * @memberof DynamicObject.prototype * @type {DynamicPolyline} */ - polyline : createDynamicPropertyDescriptor('polyline', '_polyline'), + polyline : createDynamicPropertyDescriptor('polyline'), /** * Gets or sets the pyramid. * @memberof DynamicObject.prototype * @type {DynamicPyramid} */ - pyramid : createDynamicPropertyDescriptor('pyramid', '_pyramid'), + pyramid : createDynamicPropertyDescriptor('pyramid'), /** * Gets or sets the vertex positions. * @memberof DynamicObject.prototype * @type {Property} */ - vertexPositions : createDynamicPropertyDescriptor('vertexPositions', '_vertexPositions'), + vertexPositions : createDynamicPropertyDescriptor('vertexPositions'), /** * Gets or sets the vector. * @memberof DynamicObject.prototype * @type {DynamicVector} */ - vector : createDynamicPropertyDescriptor('vector', '_vector'), + vector : createDynamicPropertyDescriptor('vector'), /** * Gets or sets the description. * @memberof DynamicObject.prototype * @type {Property} */ - description : createDynamicPropertyDescriptor('description', '_description') + description : createDynamicPropertyDescriptor('description') }); /** @@ -281,7 +298,7 @@ define(['../Core/createGuid', //>>includeEnd('debug'); propertyNames.push(propertyName); - Object.defineProperty(this, propertyName, createDynamicPropertyDescriptor(propertyName, '_' + propertyName, true)); + Object.defineProperty(this, propertyName, createDynamicPropertyDescriptor(propertyName, true)); }; /** diff --git a/Source/DynamicScene/DynamicPath.js b/Source/DynamicScene/DynamicPath.js index 33259f096da2..8d317e393767 100644 --- a/Source/DynamicScene/DynamicPath.js +++ b/Source/DynamicScene/DynamicPath.js @@ -21,13 +21,22 @@ define(['../Core/defaultValue', */ var DynamicPath = function() { this._color = undefined; + this._colorSubscription = undefined; this._outlineColor = undefined; + this._outlineColorSubscription = undefined; this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._width = undefined; + this._widthSubscription = undefined; this._resolution = undefined; + this._resolutionSubscription = undefined; this._leadTime = undefined; + this._leadTimeSubscription = undefined; this._trailTime = undefined; + this._trailTimeSubscription = undefined; + this._definitionChanged = new Event(); }; @@ -48,56 +57,56 @@ define(['../Core/defaultValue', * @memberof DynamicPath.prototype * @type {Property} */ - color : createDynamicPropertyDescriptor('color', '_color'), + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the {@link Color} {@link Property} specifying the the path's outline color. * @memberof DynamicPath.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the numeric {@link Property} specifying the the path's outline width. * @memberof DynamicPath.prototype * @type {Property} */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + outlineWidth : createDynamicPropertyDescriptor('outlineWidth'), /** * Gets or sets the boolean {@link Property} specifying the path's visibility. * @memberof DynamicPath.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the numeric {@link Property} specifying the the path's width. * @memberof DynamicPath.prototype * @type {Property} */ - width : createDynamicPropertyDescriptor('width', '_width'), + width : createDynamicPropertyDescriptor('width'), /** * Gets or sets the numeric {@link Property} specifying the maximum step size, in seconds, to take when sampling the position. * @memberof DynamicPath.prototype * @type {Property} */ - resolution : createDynamicPropertyDescriptor('resolution', '_resolution'), + resolution : createDynamicPropertyDescriptor('resolution'), /** * Gets or sets the numeric {@link Property} specifying the number of seconds in front of the object to show. * @memberof DynamicPath.prototype * @type {Property} */ - leadTime : createDynamicPropertyDescriptor('leadTime', '_leadTime'), + leadTime : createDynamicPropertyDescriptor('leadTime'), /** * Gets or sets the numeric {@link Property} specifying the number of seconds behind the object to show. * @memberof DynamicPath.prototype * @type {Property} */ - trailTime : createDynamicPropertyDescriptor('trailTime', '_trailTime') + trailTime : createDynamicPropertyDescriptor('trailTime') }); /** diff --git a/Source/DynamicScene/DynamicPoint.js b/Source/DynamicScene/DynamicPoint.js index 77bfc3ba5a99..5753e8e8af9f 100644 --- a/Source/DynamicScene/DynamicPoint.js +++ b/Source/DynamicScene/DynamicPoint.js @@ -21,11 +21,17 @@ define(['../Core/defaultValue', */ var DynamicPoint = function() { this._color = undefined; + this._colorSubscription = undefined; this._pixelSize = undefined; + this._pixelSizeSubscription = undefined; this._outlineColor = undefined; + this._outlineColorSubscription = undefined; this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._scaleByDistance = undefined; + this._scaleByDistanceSubscription = undefined; this._definitionChanged = new Event(); }; @@ -46,35 +52,35 @@ define(['../Core/defaultValue', * @memberof DynamicPoint.prototype * @type {Property} */ - color : createDynamicPropertyDescriptor('color', '_color'), + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the numeric {@link Property} specifying the point's size in pixels. * @memberof DynamicPoint.prototype * @type {Property} */ - pixelSize : createDynamicPropertyDescriptor('pixelSize', '_pixelSize'), + pixelSize : createDynamicPropertyDescriptor('pixelSize'), /** * Gets or sets the {@link Color} {@link Property} specifying the the point's outline color. * @memberof DynamicPoint.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the numeric {@link Property} specifying the the point's outline width. * @memberof DynamicPoint.prototype * @type {Property} */ - outlineWidth : createDynamicPropertyDescriptor('outlineWidth', '_outlineWidth'), + outlineWidth : createDynamicPropertyDescriptor('outlineWidth'), /** * Gets or sets the boolean {@link Property} specifying the point's visibility. * @memberof DynamicPoint.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link NearFarScalar} {@link Property} used to scale billboards based on distance. @@ -82,7 +88,7 @@ define(['../Core/defaultValue', * @memberof DynamicBillboard.prototype * @type {Property} */ - scaleByDistance : createDynamicPropertyDescriptor('scaleByDistance', '_scaleByDistance') + scaleByDistance : createDynamicPropertyDescriptor('scaleByDistance') }); /** diff --git a/Source/DynamicScene/DynamicPolygon.js b/Source/DynamicScene/DynamicPolygon.js index a69c0f7b7bfc..35578b68f0a9 100644 --- a/Source/DynamicScene/DynamicPolygon.js +++ b/Source/DynamicScene/DynamicPolygon.js @@ -22,13 +22,19 @@ define(['../Core/defaultValue', */ var DynamicPolygon = function() { this._show = undefined; + this._showSubscription = undefined; this._material = undefined; + this._materialSubscription = undefined; this._height = undefined; + this._heightSubscription = undefined; this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; this._granularity = undefined; + this._granularitySubscription = undefined; this._stRotation = undefined; + this._stRotationSubscription = undefined; this._perPositionHeight = undefined; - + this._perPositionHeightSubscription = undefined; this._definitionChanged = new Event(); }; @@ -49,14 +55,14 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link MaterialProperty} specifying the appearance of the polygon. * @memberof DynamicPolygon.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material'), + material : createDynamicPropertyDescriptor('material'), /** * Gets or sets the Number {@link Property} specifying the height of the polygon. @@ -64,7 +70,7 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - height : createDynamicPropertyDescriptor('height', '_height'), + height : createDynamicPropertyDescriptor('height'), /** * Gets or sets the Number {@link Property} specifying the extruded height of the polygon. @@ -73,7 +79,7 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight', '_extrudedHeight'), + extrudedHeight : createDynamicPropertyDescriptor('extrudedHeight'), /** * Gets or sets the Number {@link Property} specifying the sampling distance, in radians, @@ -81,7 +87,7 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - granularity : createDynamicPropertyDescriptor('granularity', '_granularity'), + granularity : createDynamicPropertyDescriptor('granularity'), /** * Gets or sets the Number {@link Property} specifying the rotation of the texture coordinates, @@ -89,35 +95,35 @@ define(['../Core/defaultValue', * @memberof DynamicPolygon.prototype * @type {Property} */ - stRotation : createDynamicPropertyDescriptor('stRotation', '_stRotation'), + stRotation : createDynamicPropertyDescriptor('stRotation'), /** * Gets or sets the Boolean {@link Property} specifying whether the polygon should be filled. * @memberof DynamicPolygon.prototype * @type {Property} */ - fill : createDynamicPropertyDescriptor('fill', '_fill'), + fill : createDynamicPropertyDescriptor('fill'), /** * Gets or sets the Boolean {@link Property} specifying whether the polygon should be outlined. * @memberof DynamicPolygon.prototype * @type {Property} */ - outline : createDynamicPropertyDescriptor('outline', '_outline'), + outline : createDynamicPropertyDescriptor('outline'), /** * Gets or sets the Color {@link Property} specifying whether the color of the outline. * @memberof DynamicPolygon.prototype * @type {Property} */ - outlineColor : createDynamicPropertyDescriptor('outlineColor', '_outlineColor'), + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the Boolean {@link Property} specifying whether the polygon uses per-position heights. * @memberof DynamicPolygon.prototype * @type {Property} */ - perPositionHeight : createDynamicPropertyDescriptor('perPositionHeight', '_perPositionHeight') + perPositionHeight : createDynamicPropertyDescriptor('perPositionHeight') }); /** diff --git a/Source/DynamicScene/DynamicPolyline.js b/Source/DynamicScene/DynamicPolyline.js index d3caa004ec6d..ab73c8d16bee 100644 --- a/Source/DynamicScene/DynamicPolyline.js +++ b/Source/DynamicScene/DynamicPolyline.js @@ -21,8 +21,11 @@ define(['../Core/defaultValue', */ var DynamicPolyline = function() { this._show = undefined; + this._showSubscription = undefined; this._material = undefined; + this._materialSubscription = undefined; this._width = undefined; + this._widthSubscription = undefined; this._definitionChanged = new Event(); }; @@ -43,21 +46,21 @@ define(['../Core/defaultValue', * @memberof DynamicPolyline.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the {@link MaterialProperty} specifying the appearance of the polyline. * @memberof DynamicPolyline.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material'), + material : createDynamicPropertyDescriptor('material'), /** * Gets or sets the numeric {@link Property} specifying the the line's width. * @memberof DynamicPolyline.prototype * @type {Property} */ - width : createDynamicPropertyDescriptor('width', '_width') + width : createDynamicPropertyDescriptor('width') }); /** diff --git a/Source/DynamicScene/DynamicPyramid.js b/Source/DynamicScene/DynamicPyramid.js index 5b3a2637ae63..26f24db969df 100644 --- a/Source/DynamicScene/DynamicPyramid.js +++ b/Source/DynamicScene/DynamicPyramid.js @@ -22,12 +22,19 @@ define(['../Core/defaultValue', */ var DynamicPyramid = function() { this._show = undefined; + this._showSubscription = undefined; this._directions = undefined; + this._directionsSubscription = undefined; this._radius = undefined; + this._radiusSubscription = undefined; this._showIntersection = undefined; + this._showIntersectionSubscription = undefined; this._intersectionColor = undefined; + this._intersectionColorSubscription = undefined; this._intersectionWidth = undefined; + this._intersectionWidthSubscription = undefined; this._material = undefined; + this._materialSubscription = undefined; this._definitionChanged = new Event(); }; @@ -48,49 +55,49 @@ define(['../Core/defaultValue', * @memberof DynamicPyramid.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * A {@link Property} which returns an array of {@link Spherical} instances representing the pyramid's projection. * @memberof DynamicPyramid.prototype * @type {Property} */ - directions : createDynamicPropertyDescriptor('directions', '_directions'), + directions : createDynamicPropertyDescriptor('directions'), /** * Gets or sets the numeric {@link Property} specifying the radius of the pyramid's projection. * @memberof DynamicPyramid.prototype * @type {Property} */ - radius : createDynamicPropertyDescriptor('radius', '_radius'), + radius : createDynamicPropertyDescriptor('radius'), /** * Gets or sets the boolean {@link Property} specifying the visibility of the line formed by the intersection of the pyramid and other central bodies. * @memberof DynamicPyramid.prototype * @type {Property} */ - showIntersection : createDynamicPropertyDescriptor('showIntersection', '_showIntersection'), + showIntersection : createDynamicPropertyDescriptor('showIntersection'), /** * Gets or sets the {@link Color} {@link Property} specifying the color of the line formed by the intersection of the pyramid and other central bodies. * @memberof DynamicPyramid.prototype * @type {Property} */ - intersectionColor : createDynamicPropertyDescriptor('intersectionColor', '_intersectionColor'), + intersectionColor : createDynamicPropertyDescriptor('intersectionColor'), /** * Gets or sets the numeric {@link Property} specifying the width of the line formed by the intersection of the pyramid and other central bodies. * @memberof DynamicPyramid.prototype * @type {Property} */ - intersectionWidth : createDynamicPropertyDescriptor('intersectionWidth', '_intersectionWidth'), + intersectionWidth : createDynamicPropertyDescriptor('intersectionWidth'), /** * Gets or sets the {@link MaterialProperty} specifying the the pyramid's appearance. * @memberof DynamicPyramid.prototype * @type {MaterialProperty} */ - material : createDynamicPropertyDescriptor('material', '_material') + material : createDynamicPropertyDescriptor('material') }); /** diff --git a/Source/DynamicScene/DynamicVector.js b/Source/DynamicScene/DynamicVector.js index 956a2f008711..6220ca66b76c 100644 --- a/Source/DynamicScene/DynamicVector.js +++ b/Source/DynamicScene/DynamicVector.js @@ -21,10 +21,15 @@ define(['../Core/defaultValue', */ var DynamicVector = function() { this._color = undefined; + this._colorSubscription = undefined; this._show = undefined; + this._showSubscription = undefined; this._width = undefined; + this._widthSubscription = undefined; this._direction = undefined; + this._directionSubscription = undefined; this._length = undefined; + this._lengthSubscription = undefined; this._definitionChanged = new Event(); }; @@ -45,35 +50,35 @@ define(['../Core/defaultValue', * @memberof DynamicVector.prototype * @type {Property} */ - color : createDynamicPropertyDescriptor('color', '_color'), + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the boolean {@link Property} specifying the vector's visibility. * @memberof DynamicVector.prototype * @type {Property} */ - show : createDynamicPropertyDescriptor('show', '_show'), + show : createDynamicPropertyDescriptor('show'), /** * Gets or sets the numeric {@link Property} specifying the the vector's width. * @memberof DynamicVector.prototype * @type {Property} */ - width : createDynamicPropertyDescriptor('width', '_width'), + width : createDynamicPropertyDescriptor('width'), /** * Gets or sets the {@link Cartesian3} {@link Property} specifying the the vector's direction. * @memberof DynamicVector.prototype * @type {Property} */ - direction : createDynamicPropertyDescriptor('direction', '_direction'), + direction : createDynamicPropertyDescriptor('direction'), /** * Gets or sets the numeric {@link Property} specifying the the vector's graphical length in meters. * @memberof DynamicVector.prototype * @type {Property} */ - length : createDynamicPropertyDescriptor('length', '_length') + length : createDynamicPropertyDescriptor('length') }); /** diff --git a/Source/DynamicScene/PropertyArray.js b/Source/DynamicScene/PropertyArray.js index ec22152aae3a..652651825491 100644 --- a/Source/DynamicScene/PropertyArray.js +++ b/Source/DynamicScene/PropertyArray.js @@ -100,7 +100,6 @@ define(['../Core/defaultValue', /** * Sets the value of the property. - * If the value is an object, the object must provide clone and equals functions. * @memberof PropertyArray * * @param {Array} value An array of Property instances. diff --git a/Source/DynamicScene/createDynamicPropertyDescriptor.js b/Source/DynamicScene/createDynamicPropertyDescriptor.js index 720985cac5d9..7303a66b8705 100644 --- a/Source/DynamicScene/createDynamicPropertyDescriptor.js +++ b/Source/DynamicScene/createDynamicPropertyDescriptor.js @@ -6,14 +6,9 @@ define(['../Core/defaultValue', defined) { "use strict"; - /** - * Used to consistently define all DynamicScene graphics objects. - * @private - */ - function createDynamicPropertyDescriptor(name, privateName, configurable) { - var subscriptionName = privateName + 'Subsription'; + function createProperty(name, privateName, subscriptionName, configurable) { return { - configurable : defaultValue(configurable, false), + configurable : configurable, get : function() { return this[privateName]; }, @@ -37,5 +32,15 @@ define(['../Core/defaultValue', }; } + /** + * Used to consistently define all DynamicScene graphics objects. + * This is broken into two functions because the Chrome profiler does a better + * job of optimizing lookups if it notices that the string is constant throughout the function. + * @private + */ + function createDynamicPropertyDescriptor(name, configurable) { + return createProperty(name, '_' + name, '_' + name + 'Subscription', defaultValue(configurable, false)); + } + return createDynamicPropertyDescriptor; }); \ No newline at end of file diff --git a/Specs/DynamicScene/CompositePropertySpec.js b/Specs/DynamicScene/CompositePropertySpec.js index d192cec4a712..add45bba8792 100644 --- a/Specs/DynamicScene/CompositePropertySpec.js +++ b/Specs/DynamicScene/CompositePropertySpec.js @@ -19,6 +19,7 @@ defineSuite(['DynamicScene/CompositeProperty', var property = new CompositeProperty(); expect(property.intervals).toBeInstanceOf(TimeIntervalCollection); expect(property.getValue(new JulianDate())).toBeUndefined(); + expect(property.isConstant).toBe(true); }); it('works without a result parameter', function() { @@ -28,6 +29,7 @@ defineSuite(['DynamicScene/CompositeProperty', var property = new CompositeProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var result1 = property.getValue(interval1.start); expect(result1).not.toBe(interval1.data.getValue(interval1.start)); @@ -45,6 +47,7 @@ defineSuite(['DynamicScene/CompositeProperty', var property = new CompositeProperty(); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); + expect(property.isConstant).toBe(false); var expected = new Cartesian3(); var result1 = property.getValue(interval1.start, expected); From 0762685a51fda48663a7a632a39e7c3f96890bb1 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 14 Feb 2014 11:59:08 -0500 Subject: [PATCH 45/81] Minor cleanup. --- Source/Core/AssociativeArray.js | 6 +++--- Source/DynamicScene/GeoJsonDataSource.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/AssociativeArray.js b/Source/Core/AssociativeArray.js index 844e10cc9c8b..15dd1cc55e49 100644 --- a/Source/Core/AssociativeArray.js +++ b/Source/Core/AssociativeArray.js @@ -49,13 +49,13 @@ define(['./defined', * exists in the array, it is overwritten. * @memberof AssociativeArray * - * @param {String} key A unique identifier. + * @param {String|Number} key A unique identifier. * @param {Object} value The value to associate with the provided key. */ AssociativeArray.prototype.set = function(key, value) { //>>includeStart('debug', pragmas.debug); - if (typeof key !== 'string') { - throw new DeveloperError('key is required to be a string.'); + if (typeof key !== 'string' && typeof key !== 'number') { + throw new DeveloperError('key is required to be a string or number.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/GeoJsonDataSource.js b/Source/DynamicScene/GeoJsonDataSource.js index 5a0950462212..1150c0bbc512 100644 --- a/Source/DynamicScene/GeoJsonDataSource.js +++ b/Source/DynamicScene/GeoJsonDataSource.js @@ -302,7 +302,7 @@ define([ defaultPolygon.polygon = polygon; material = new ColorMaterialProperty(); - material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.25)); + material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.1)); polygon.material = material; this._changed = new Event(); From 4462534f201f2b872bc330ae6c9623ca49d363b0 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 14 Feb 2014 14:27:10 -0500 Subject: [PATCH 46/81] Start defining the GeometryUpdater base interface. This has exposed some cruft that can now be cleaned up. --- Source/DynamicScene/EllipseGeometryUpdater.js | 14 +-- .../DynamicScene/EllipsoidGeometryUpdater.js | 14 +-- Source/DynamicScene/GeometryUpdater.js | 93 +++++++++++++++++++ Source/DynamicScene/GeometryVisualizer.js | 4 +- Source/DynamicScene/PolygonGeometryUpdater.js | 14 +-- .../DynamicScene/PolylineGeometryUpdater.js | 14 +-- .../DynamicScene/StaticGeometryColorBatch.js | 6 +- .../StaticGeometryPerMaterialBatch.js | 6 +- .../StaticOutlineGeometryBatch.js | 8 +- 9 files changed, 121 insertions(+), 52 deletions(-) create mode 100644 Source/DynamicScene/GeometryUpdater.js diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index bf03113aa1e0..106866b33fb8 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -67,7 +67,6 @@ define(['../Core/Color', throw new DeveloperError('dynamicObject is required'); } - this._id = dynamicObject.id; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._geometryType = GeometryBatchType.NONE; @@ -87,11 +86,6 @@ define(['../Core/Color', EllipseGeometryUpdater.MaterialAppearanceType = MaterialAppearance; defineProperties(EllipseGeometryUpdater.prototype, { - id : { - get : function() { - return this._id; - } - }, dynamicObject :{ get : function() { return this._dynamicObject; @@ -288,10 +282,10 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - return new DynamicGeometryBatchItem(primitives, this); + return new DynamicGeometryUpdater(primitives, this); }; - var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; @@ -299,7 +293,7 @@ define(['../Core/Color', this._options = new GeometryOptions(geometryUpdater._dynamicObject); }; - DynamicGeometryBatchItem.prototype.update = function(time) { + DynamicGeometryUpdater.prototype.update = function(time) { var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -384,7 +378,7 @@ define(['../Core/Color', } }; - DynamicGeometryBatchItem.prototype.destroy = function() { + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); } diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index c17c991d08e0..313efa6150de 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -69,7 +69,6 @@ define(['../Core/Color', throw new DeveloperError('dynamicObject is required'); } - this._id = dynamicObject.id; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._geometryType = GeometryBatchType.NONE; @@ -90,11 +89,6 @@ define(['../Core/Color', EllipsoidGeometryUpdater.MaterialAppearanceType = MaterialAppearance; defineProperties(EllipsoidGeometryUpdater.prototype, { - id : { - get : function() { - return this._id; - } - }, dynamicObject :{ get : function() { return this._dynamicObject; @@ -280,10 +274,10 @@ define(['../Core/Color', }; EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - return new DynamicGeometryBatchItem(primitives, this); + return new DynamicGeometryUpdater(primitives, this); }; - var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; @@ -291,7 +285,7 @@ define(['../Core/Color', this._options = new GeometryOptions(geometryUpdater._dynamicObject); }; - DynamicGeometryBatchItem.prototype.update = function(time) { + DynamicGeometryUpdater.prototype.update = function(time) { var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -373,7 +367,7 @@ define(['../Core/Color', } }; - DynamicGeometryBatchItem.prototype.destroy = function() { + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); } diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js new file mode 100644 index 000000000000..cdbbc7a64c98 --- /dev/null +++ b/Source/DynamicScene/GeometryUpdater.js @@ -0,0 +1,93 @@ +/*global define*/ +define(['../Core/defineProperties', '../Core/DeveloperError'], function(defineProperties, DeveloperError) { + "use strict"; + + var GeometryUpdater = function(dynamicObject) { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.PerInstanceColorAppearanceType = undefined; + + GeometryUpdater.MaterialAppearanceType = undefined; + + defineProperties(GeometryUpdater.prototype, { + dynamicObject : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + geometryType : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + geometryChanged : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + fillMaterialProperty : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + outlineEnabled : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + hasConstantFill : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + hasConstantOutline : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + outlineColorProperty : { + get : function() { + DeveloperError.throwInstantiationError(); + } + } + }); + + GeometryUpdater.prototype.isOutlineVisible = function(time) { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.prototype.isFilled = function(time) { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.prototype.createGeometryInstance = function(time) { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.prototype.destroy = function() { + DeveloperError.throwInstantiationError(); + }; + + GeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + DeveloperError.throwInstantiationError(); + }; + + var DynamicGeometryUpdater = function(primitives, geometryUpdater) { + DeveloperError.throwInstantiationError(); + }; + + DynamicGeometryUpdater.prototype.update = function(time) { + DeveloperError.throwInstantiationError(); + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + DeveloperError.throwInstantiationError(); + }; + + return GeometryUpdater; +}); \ No newline at end of file diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 429f7976aca1..e4f1067158e9 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -36,11 +36,11 @@ define(['../Core/defined', }; DynamicGeometryBatch.prototype.add = function(time, updater) { - this._dynamicUpdaters.set(updater.id, updater.createDynamicUpdater(this._primitives)); + this._dynamicUpdaters.set(updater.dynamicObject.id, updater.createDynamicUpdater(this._primitives)); }; DynamicGeometryBatch.prototype.remove = function(updater) { - var id = updater.id; + var id = updater.dynamicObject.id; var dynamicUpdater = this._dynamicUpdaters.get(id); if (defined(dynamicUpdater)) { this._dynamicUpdaters.remove(id); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index ffdf45163907..f26ec300931d 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -66,7 +66,6 @@ define(['../Core/Color', throw new DeveloperError('dynamicObject is required'); } - this._id = dynamicObject.id; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._geometryType = GeometryBatchType.NONE; @@ -86,11 +85,6 @@ define(['../Core/Color', PolygonGeometryUpdater.MaterialAppearanceType = MaterialAppearance; defineProperties(PolygonGeometryUpdater.prototype, { - id : { - get : function() { - return this._id; - } - }, dynamicObject :{ get : function() { return this._dynamicObject; @@ -278,10 +272,10 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - return new DynamicGeometryBatchItem(primitives, this); + return new DynamicGeometryUpdater(primitives, this); }; - var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; @@ -289,7 +283,7 @@ define(['../Core/Color', this._options = new GeometryOptions(geometryUpdater._dynamicObject); }; - DynamicGeometryBatchItem.prototype.update = function(time) { + DynamicGeometryUpdater.prototype.update = function(time) { var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -367,7 +361,7 @@ define(['../Core/Color', } }; - DynamicGeometryBatchItem.prototype.destroy = function() { + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); } diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 7b6005c5a12d..153605959dcd 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -56,7 +56,6 @@ define(['../Core/Color', throw new DeveloperError('dynamicObject is required'); } - this._id = dynamicObject.id; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._geometryType = GeometryBatchType.NONE; @@ -72,11 +71,6 @@ define(['../Core/Color', PolylineGeometryUpdater.MaterialAppearanceType = PolylineMaterialAppearance; defineProperties(PolylineGeometryUpdater.prototype, { - id : { - get : function() { - return this._id; - } - }, dynamicObject :{ get : function() { return this._dynamicObject; @@ -215,17 +209,17 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - return new DynamicGeometryBatchItem(primitives, this); + return new DynamicGeometryUpdater(primitives, this); }; - var DynamicGeometryBatchItem = function(primitives, geometryUpdater) { + var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; this._geometryUpdater = geometryUpdater; this._options = new GeometryOptions(geometryUpdater._dynamicObject); }; - DynamicGeometryBatchItem.prototype.update = function(time) { + DynamicGeometryUpdater.prototype.update = function(time) { var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -268,7 +262,7 @@ define(['../Core/Color', this._primitives.add(this._primitive); }; - DynamicGeometryBatchItem.prototype.destroy = function() { + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); } diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 2c63a84d2235..1a3780efe7ed 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -33,7 +33,7 @@ define(['../Core/Color', }; Batch.prototype.add = function(updater, instance) { - var id = updater.id; + var id = updater.dynamicObject.id; this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); @@ -43,7 +43,7 @@ define(['../Core/Color', }; Batch.prototype.remove = function(updater) { - var id = updater.id; + var id = updater.dynamicObject.id; this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; this.updaters.remove(id); this.updatersWithAttributes.remove(id); @@ -79,7 +79,7 @@ define(['../Core/Color', var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.id); + var instance = this.geometry.get(updater.dynamicObject.id); var attributes = this.attributes.get(instance.id.id); if (!defined(attributes)) { diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 82bc5dcdcdd3..37ac8530fd90 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -49,7 +49,7 @@ define(['../Core/defined', }; Batch.prototype.add = function(time, updater) { - var id = updater.id; + var id = updater.dynamicObject.id; this.updaters.set(id, updater); this.geometry.set(id, updater.createGeometryInstance(time)); if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) { @@ -59,7 +59,7 @@ define(['../Core/defined', }; Batch.prototype.remove = function(updater) { - var id = updater.id; + var id = updater.dynamicObject.id; this.createPrimitive = this.updaters.remove(id); this.geometry.remove(id); this.updatersWithAttributes.remove(id); @@ -97,7 +97,7 @@ define(['../Core/defined', var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.id); + var instance = this.geometry.get(updater.dynamicObject.id); var attributes = this.attributes.get(instance.id.id); if (!defined(attributes)) { diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 6c3dda66e690..e548355e175c 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -32,7 +32,7 @@ define(['../Core/Color', }; Batch.prototype.add = function(updater, instance) { - var id = updater.id; + var id = updater.dynamicObject.id; this.createPrimitive = true; this.geometry.set(id, instance); this.updaters.set(id, updater); @@ -42,7 +42,7 @@ define(['../Core/Color', }; Batch.prototype.remove = function(updater) { - var id = updater.id; + var id = updater.dynamicObject.id; this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; this.updaters.remove(id); this.updatersWithAttributes.remove(id); @@ -73,12 +73,12 @@ define(['../Core/Color', } this.primitive = primitive; this.createPrimitive = false; - } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){ + } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE) { var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; for (var i = 0; i < length; i++) { var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.id); + var instance = this.geometry.get(updater.dynamicObject.id); var attributes = this.attributes.get(instance.id.id); if (!defined(attributes)) { From 90ca6bff32c833552fe8a4c35f50c7fbc0081796 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 10:33:47 -0500 Subject: [PATCH 47/81] Remove GeometryBatchType GeometryBatchType was originally a way for GeometryUpdaters to inform the visualizer as to what batch they would ultimately belong in. Unfortunately, there are just too many potential batches that could be created due to the various combination of properties. For this reason, the enum was removed and replaced with individual properties on the updater that are used by the visualizer to determine type. --- Source/DynamicScene/EllipseGeometryUpdater.js | 127 +++++++++++----- .../DynamicScene/EllipsoidGeometryUpdater.js | 135 ++++++++++++----- Source/DynamicScene/GeometryBatchType.js | 15 -- Source/DynamicScene/GeometryUpdater.js | 28 +++- Source/DynamicScene/GeometryVisualizer.js | 108 +++++++------- Source/DynamicScene/PolygonGeometryUpdater.js | 139 +++++++++++++----- .../DynamicScene/PolylineGeometryUpdater.js | 109 ++++++++++---- 7 files changed, 451 insertions(+), 210 deletions(-) delete mode 100644 Source/DynamicScene/GeometryBatchType.js diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 106866b33fb8..acf5ff60969a 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -14,7 +14,6 @@ define(['../Core/Color', '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', - '../DynamicScene/GeometryBatchType', '../DynamicScene/MaterialProperty', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', @@ -35,7 +34,6 @@ define(['../Core/Color', ShowGeometryInstanceAttribute, ColorMaterialProperty, ConstantProperty, - GeometryBatchType, MaterialProperty, MaterialAppearance, PerInstanceColorAppearance, @@ -69,11 +67,13 @@ define(['../Core/Color', this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); - this._geometryType = GeometryBatchType.NONE; + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; this._geometryChanged = new Event(); this._showProperty = undefined; this._materialProperty = undefined; - this._outlineEnabled = false; this._hasConstantOutline = true; this._showOutlineProperty = undefined; this._outlineColorProperty = undefined; @@ -91,14 +91,17 @@ define(['../Core/Color', return this._dynamicObject; } }, - geometryType : { + fillEnabled : { get : function() { - return this._geometryType; + return this._fillEnabled; } }, - geometryChanged : { + hasConstantFill : { get : function() { - return this._geometryChanged; + return !this._fillEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, fillMaterialProperty : { @@ -111,34 +114,55 @@ define(['../Core/Color', return this._outlineEnabled; } }, - hasConstantFill : { - get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; - } - }, hasConstantOutline : { get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; + return !this._outlineEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, outlineColorProperty : { get : function() { return this._outlineColorProperty; } + }, + isDynamic : { + get : function() { + return this._dynamic; + } + }, + isClosed : { + get : function() { + return this._isClosed; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } } }); EllipseGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; EllipseGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._fillEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -146,8 +170,11 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR_OPEN || this._geometryType === GeometryBatchType.COLOR_CLOSED) { - var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { show : show, @@ -167,6 +194,14 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._outlineEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -180,6 +215,10 @@ define(['../Core/Color', }); }; + EllipseGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + EllipseGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -193,16 +232,16 @@ define(['../Core/Color', var ellipse = this._dynamicObject.ellipse; if (!defined(ellipse)) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; } var fillProperty = ellipse.fill; - var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; var outlineProperty = ellipse.outline; var outlineEnabled = defined(outlineProperty); @@ -210,7 +249,12 @@ define(['../Core/Color', outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - if (!isFilled && !outlineEnabled) { + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } return; } @@ -221,9 +265,9 @@ define(['../Core/Color', var show = ellipse.show; if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; @@ -235,7 +279,7 @@ define(['../Core/Color', this._fillProperty = defaultValue(fillProperty, defaultFill); this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); - this._outlineColorProperty = defaultValue(ellipse.outlineColor, defaultOutlineColor); + this._outlineColorProperty = outlineEnabled ? defaultValue(ellipse.outlineColor, defaultOutlineColor) : undefined; var rotation = ellipse.rotation; var height = ellipse.height; @@ -244,6 +288,10 @@ define(['../Core/Color', var stRotation = ellipse.stRotation; var numberOfVerticalLines = ellipse.numberOfVerticalLines; + this._isClosed = defined(extrudedHeight); + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; + if (!position.isConstant || // !semiMajorAxis.isConstant || // !semiMinorAxis.isConstant || // @@ -253,8 +301,8 @@ define(['../Core/Color', defined(granularity) && !granularity.isConstant || // defined(stRotation) && !stRotation.isConstant || // defined(numberOfVerticalLines) && !numberOfVerticalLines.isConstant) { - if (this._geometryType !== GeometryBatchType.DYNAMIC) { - this._geometryType = GeometryBatchType.DYNAMIC; + if (!this._dynamic) { + this._dynamic = true; this._geometryChanged.raiseEvent(this); } } else { @@ -269,19 +317,20 @@ define(['../Core/Color', options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; - - var isClosed = defined(options.extrudedHeight); - if (isClosed) { - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; - } else { - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; - } - this._outlineEnabled = outlineEnabled; + this._dynamic = false; this._geometryChanged.raiseEvent(this); } }; EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError(); + } + + if (!defined(primitives)) { + throw new DeveloperError(); + } + return new DynamicGeometryUpdater(primitives, this); }; @@ -294,6 +343,10 @@ define(['../Core/Color', }; DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -378,6 +431,10 @@ define(['../Core/Color', } }; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 313efa6150de..f824121f51a7 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -16,7 +16,6 @@ define(['../Core/Color', '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', - '../DynamicScene/GeometryBatchType', '../DynamicScene/MaterialProperty', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', @@ -39,7 +38,6 @@ define(['../Core/Color', ShowGeometryInstanceAttribute, ColorMaterialProperty, ConstantProperty, - GeometryBatchType, MaterialProperty, MaterialAppearance, PerInstanceColorAppearance, @@ -71,17 +69,17 @@ define(['../Core/Color', this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); - this._geometryType = GeometryBatchType.NONE; + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; this._geometryChanged = new Event(); this._showProperty = undefined; this._materialProperty = undefined; - this._outlineEnabled = false; this._hasConstantOutline = true; this._showOutlineProperty = undefined; this._outlineColorProperty = undefined; this._options = new GeometryOptions(dynamicObject); this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipsoid', dynamicObject.ellipsoid, undefined); - this._modelMatrix = undefined; }; EllipsoidGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; @@ -94,14 +92,17 @@ define(['../Core/Color', return this._dynamicObject; } }, - geometryType : { + fillEnabled : { get : function() { - return this._geometryType; + return this._fillEnabled; } }, - geometryChanged : { + hasConstantFill : { get : function() { - return this._geometryChanged; + return !this._fillEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, fillMaterialProperty : { @@ -114,34 +115,55 @@ define(['../Core/Color', return this._outlineEnabled; } }, - hasConstantFill : { - get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; - } - }, hasConstantOutline : { get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; + return !this._outlineEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, outlineColorProperty : { get : function() { return this._outlineColorProperty; } + }, + isDynamic : { + get : function() { + return this._dynamic; + } + }, + isClosed : { + get : function() { + return true; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } } }); EllipsoidGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; EllipsoidGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; EllipsoidGeometryUpdater.prototype.createGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._fillEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -149,8 +171,11 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR_CLOSED) { - var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { show : show, @@ -162,22 +187,36 @@ define(['../Core/Color', }; } + positionScratch = dynamicObject.position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); + orientationScratch = dynamicObject.orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); + return new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidGeometry(this._options), - attributes : attributes, - modelMatrix : this._modelMatrix + modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch), + attributes : attributes }); }; EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._outlineEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); + positionScratch = dynamicObject.position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); + orientationScratch = dynamicObject.orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); + return new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidOutlineGeometry(this._options), - modelMatrix : this._modelMatrix, + modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch), attributes : { show : new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) @@ -185,6 +224,10 @@ define(['../Core/Color', }); }; + EllipsoidGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + EllipsoidGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -198,16 +241,16 @@ define(['../Core/Color', var ellipsoid = this._dynamicObject.ellipsoid; if (!defined(ellipsoid)) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; } var fillProperty = ellipsoid.fill; - var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; var outlineProperty = ellipsoid.outline; var outlineEnabled = defined(outlineProperty); @@ -215,7 +258,12 @@ define(['../Core/Color', outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - if (!isFilled && !outlineEnabled) { + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } return; } @@ -226,9 +274,9 @@ define(['../Core/Color', var show = ellipsoid.show; if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // (!defined(position) || !defined(orientation) || !defined(radii))) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; @@ -240,7 +288,9 @@ define(['../Core/Color', this._fillProperty = defaultValue(fillProperty, defaultFill); this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(ellipsoid.outline, defaultOutline); - this._outlineColorProperty = defaultValue(ellipsoid.outlineColor, defaultOutlineColor); + this._outlineColorProperty = outlineEnabled ? defaultValue(ellipsoid.outlineColor, defaultOutlineColor) : undefined; + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; var stackPartitions = ellipsoid.stackPartitions; var slicePartitions = ellipsoid.slicePartitions; @@ -252,8 +302,8 @@ define(['../Core/Color', defined(stackPartitions) && !stackPartitions.isConstant || // defined(slicePartitions) && !slicePartitions.isConstant || // defined(subdivisions) && !subdivisions.isConstant) { - if (this._geometryType !== GeometryBatchType.DYNAMIC) { - this._geometryType = GeometryBatchType.DYNAMIC; + if (!this._dynamic) { + this._dynamic = true; this._geometryChanged.raiseEvent(this); } } else { @@ -263,17 +313,20 @@ define(['../Core/Color', options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.subdivisions = defined(subdivisions) ? subdivisions.getValue(Iso8601.MINIMUM_VALUE) : undefined; - - positionScratch = position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); - orientationScratch = orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); - this._modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch); - this._outlineEnabled = outlineEnabled; - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; + this._dynamic = false; this._geometryChanged.raiseEvent(this); } }; EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError(); + } + + if (!defined(primitives)) { + throw new DeveloperError(); + } + return new DynamicGeometryUpdater(primitives, this); }; @@ -286,6 +339,10 @@ define(['../Core/Color', }; DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -367,6 +424,10 @@ define(['../Core/Color', } }; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); diff --git a/Source/DynamicScene/GeometryBatchType.js b/Source/DynamicScene/GeometryBatchType.js deleted file mode 100644 index f0069ee0e7c9..000000000000 --- a/Source/DynamicScene/GeometryBatchType.js +++ /dev/null @@ -1,15 +0,0 @@ -/*global define*/ -define(['../Core/Enumeration'], function(Enumeration) { - "use strict"; - - var GeometryBatchType = { - COLOR_CLOSED : new Enumeration(0, 'COLOR_CLOSED'), - MATERIAL_CLOSED : new Enumeration(1, 'MATERIAL_CLOSED'), - COLOR_OPEN : new Enumeration(2, 'COLOR_OPEN'), - MATERIAL_OPEN : new Enumeration(3, 'MATERIAL_OPEN'), - DYNAMIC : new Enumeration(4, 'DYNAMIC'), - NONE : new Enumeration(5, 'NONE') - }; - - return GeometryBatchType; -}); diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js index cdbbc7a64c98..9bfecc6585c9 100644 --- a/Source/DynamicScene/GeometryUpdater.js +++ b/Source/DynamicScene/GeometryUpdater.js @@ -16,12 +16,12 @@ define(['../Core/defineProperties', '../Core/DeveloperError'], function(definePr DeveloperError.throwInstantiationError(); } }, - geometryType : { + fillEnabled : { get : function() { DeveloperError.throwInstantiationError(); } }, - geometryChanged : { + hasConstantFill : { get : function() { DeveloperError.throwInstantiationError(); } @@ -36,17 +36,27 @@ define(['../Core/defineProperties', '../Core/DeveloperError'], function(definePr DeveloperError.throwInstantiationError(); } }, - hasConstantFill : { + hasConstantOutline : { get : function() { DeveloperError.throwInstantiationError(); } }, - hasConstantOutline : { + outlineColorProperty : { get : function() { DeveloperError.throwInstantiationError(); } }, - outlineColorProperty : { + isDynamic : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + isClosed : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + geometryChanged : { get : function() { DeveloperError.throwInstantiationError(); } @@ -69,6 +79,10 @@ define(['../Core/defineProperties', '../Core/DeveloperError'], function(definePr DeveloperError.throwInstantiationError(); }; + GeometryUpdater.prototype.isDestroyed = function() { + DeveloperError.throwInstantiationError(); + }; + GeometryUpdater.prototype.destroy = function() { DeveloperError.throwInstantiationError(); }; @@ -85,6 +99,10 @@ define(['../Core/defineProperties', '../Core/DeveloperError'], function(definePr DeveloperError.throwInstantiationError(); }; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + DeveloperError.throwInstantiationError(); + }; + DynamicGeometryUpdater.prototype.destroy = function() { DeveloperError.throwInstantiationError(); }; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 1554b603d945..93c351a4e048 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -7,8 +7,8 @@ define(['../Core/defined', '../Scene/PolylineColorAppearance', '../Scene/MaterialAppearance', '../Scene/PolylineMaterialAppearance', + './ColorMaterialProperty', './DynamicObjectCollection', - './GeometryBatchType', './StaticGeometryColorBatch', './StaticGeometryPerMaterialBatch', './StaticOutlineGeometryBatch' @@ -21,8 +21,8 @@ define(['../Core/defined', PolylineColorAppearance, MaterialAppearance, PolylineMaterialAppearance, + ColorMaterialProperty, DynamicObjectCollection, - GeometryBatchType, StaticGeometryColorBatch, StaticGeometryPerMaterialBatch, StaticOutlineGeometryBatch) { @@ -105,13 +105,11 @@ define(['../Core/defined', this._changedObjects = new DynamicObjectCollection(); this._outlineBatch = new StaticOutlineGeometryBatch(primitives); - - this._batches = []; - this._batches[GeometryBatchType.COLOR_CLOSED.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, true); - this._batches[GeometryBatchType.MATERIAL_CLOSED.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, true); - this._batches[GeometryBatchType.COLOR_OPEN.value] = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, false); - this._batches[GeometryBatchType.MATERIAL_OPEN.value] = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, false); - this._batches[GeometryBatchType.DYNAMIC.value] = new DynamicGeometryBatch(primitives); + this._closedColorBatch = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, true); + this._closedMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, true); + this._openColorBatch = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, false); + this._openMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, false); + this._dynamicBatch = new DynamicGeometryBatch(primitives); this._subscriptions = new AssociativeArray(); this._updaters = new AssociativeArray(); @@ -157,6 +155,43 @@ define(['../Core/defined', } }; + function removeUpdater(that, updater) { + //We don't keep track of which batch an updater is in, so just remove it from all of them. + that._outlineBatch.remove(updater); + that._closedColorBatch.remove(updater); + that._closedMaterialBatch.remove(updater); + that._openColorBatch.remove(updater); + that._openMaterialBatch.remove(updater); + that._dynamicBatch.remove(updater); + } + + function insertUpdaterIntoBatch(that, time, updater) { + if (updater.isDynamic) { + that._dynamicBatch.add(time, updater); + return; + } + + if (updater.outlineEnabled) { + that._outlineBatch.add(time, updater); + } + + if (updater.fillEnabled) { + if (updater.isClosed) { + if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { + that._closedColorBatch.add(time, updater); + } else { + that._closedMaterialBatch.add(time, updater); + } + } else { + if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { + that._openColorBatch.add(time, updater); + } else { + that._openMaterialBatch.add(time, updater); + } + } + } + } + /** * Updates all of the primitives created by this visualizer to match their * DynamicObject counterpart at the given time. @@ -181,20 +216,12 @@ define(['../Core/defined', var id; var updater; var batch; - var batches = this._batches; - var batchesLength = batches.length; for (i = removed.length - 1; i > -1; i--) { dynamicObject = removed[i]; id = dynamicObject.id; updater = this._updaters.get(id); - batch = batches[updater.geometryType.value]; - if (defined(batch)) { - batch.remove(updater); - } - - this._outlineBatch.remove(updater); - + removeUpdater(this, updater); updater.destroy(); this._updaters.remove(id); this._subscriptions.get(id)(); @@ -206,15 +233,7 @@ define(['../Core/defined', id = dynamicObject.id; updater = new this._type(dynamicObject); this._updaters.set(id, updater); - - batch = batches[updater.geometryType.value]; - if (defined(batch)) { - batch.add(time, updater); - } - - if (updater.outlineEnabled) { - this._outlineBatch.add(time, updater); - } + insertUpdaterIntoBatch(this, time, updater); this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometyChanged, this)); } @@ -222,31 +241,20 @@ define(['../Core/defined', dynamicObject = changed[i]; id = dynamicObject.id; updater = this._updaters.get(id); - for (g = 0; g < batchesLength; g++) { - if (batches[g].remove(updater)) { - break; - } - } - this._outlineBatch.remove(updater); - - batch = batches[updater.geometryType.value]; - if (defined(batch)) { - batch.add(time, updater); - } - - if (updater.outlineEnabled) { - this._outlineBatch.add(time, updater); - } + removeUpdater(this, updater); + insertUpdaterIntoBatch(this, time, updater); } addedObjects.removeAll(); removedObjects.removeAll(); changedObjects.removeAll(); - for (g = 0; g < batches.length; g++) { - batches[g].update(time); - } this._outlineBatch.update(time); + this._closedColorBatch.update(time); + this._closedMaterialBatch.update(time); + this._openColorBatch.update(time); + this._openMaterialBatch.update(time); + this._dynamicBatch.update(time); }; /** @@ -256,12 +264,12 @@ define(['../Core/defined', this._addedObjects.removeAll(); this._removedObjects.removeAll(); - var batches = this._batches; - var batchesLength = batches.length; - for (var g = 0; g < batchesLength; g++) { - batches[g].removeAllPrimitives(); - } this._outlineBatch.removeAllPrimitives(); + this._closedColorBatch.removeAllPrimitives(); + this._closedMaterialBatch.removeAllPrimitives(); + this._openColorBatch.removeAllPrimitives(); + this._openMaterialBatch.removeAllPrimitives(); + this._dynamicBatch.removeAllPrimitives(); var subscriptions = this._subscriptions.values; var len = subscriptions.length; diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index f26ec300931d..932875e8f34f 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -14,7 +14,6 @@ define(['../Core/Color', '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', - '../DynamicScene/GeometryBatchType', '../DynamicScene/MaterialProperty', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', @@ -35,7 +34,6 @@ define(['../Core/Color', ShowGeometryInstanceAttribute, ColorMaterialProperty, ConstantProperty, - GeometryBatchType, MaterialProperty, MaterialAppearance, PerInstanceColorAppearance, @@ -68,11 +66,13 @@ define(['../Core/Color', this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); - this._geometryType = GeometryBatchType.NONE; + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; this._geometryChanged = new Event(); this._showProperty = undefined; this._materialProperty = undefined; - this._outlineEnabled = false; this._hasConstantOutline = true; this._showOutlineProperty = undefined; this._outlineColorProperty = undefined; @@ -90,14 +90,17 @@ define(['../Core/Color', return this._dynamicObject; } }, - geometryType : { + fillEnabled : { get : function() { - return this._geometryType; + return this._fillEnabled; } }, - geometryChanged : { + hasConstantFill : { get : function() { - return this._geometryChanged; + return !this._fillEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, fillMaterialProperty : { @@ -110,34 +113,55 @@ define(['../Core/Color', return this._outlineEnabled; } }, - hasConstantFill : { - get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._fillProperty.isConstant; - } - }, hasConstantOutline : { get : function() { - return !defined(this._dynamicObject.availability) && this._showProperty.isConstant && this._showOutlineProperty.isConstant; + return !this._outlineEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant) && + (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, outlineColorProperty : { get : function() { return this._outlineColorProperty; } + }, + isDynamic : { + get : function() { + return this._dynamic; + } + }, + isClosed : { + get : function() { + return this._isClosed; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } } }); PolygonGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; PolygonGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; - return dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; PolygonGeometryUpdater.prototype.createGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._fillEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -145,8 +169,11 @@ define(['../Core/Color', var color; var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR_OPEN || this._geometryType === GeometryBatchType.COLOR_CLOSED) { - var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { show : show, @@ -166,6 +193,14 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._outlineEnabled) { + throw new DeveloperError(); + } + var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -179,6 +214,10 @@ define(['../Core/Color', }); }; + PolygonGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + PolygonGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -192,16 +231,16 @@ define(['../Core/Color', var polygon = this._dynamicObject.polygon; if (!defined(polygon)) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; } var fillProperty = polygon.fill; - var isFilled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; var outlineProperty = polygon.outline; var outlineEnabled = defined(outlineProperty); @@ -209,7 +248,12 @@ define(['../Core/Color', outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - if (!isFilled && !outlineEnabled) { + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } return; } @@ -218,9 +262,9 @@ define(['../Core/Color', var show = polygon.show; if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // (!defined(vertexPositions))) { - if (this._geometryType !== GeometryBatchType.NONE || this._outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; this._outlineEnabled = false; - this._geometryType = GeometryBatchType.NONE; this._geometryChanged.raiseEvent(this); } return; @@ -232,46 +276,51 @@ define(['../Core/Color', this._fillProperty = defaultValue(fillProperty, defaultFill); this._showProperty = defaultValue(show, defaultShow); this._showOutlineProperty = defaultValue(polygon.outline, defaultOutline); - this._outlineColorProperty = defaultValue(polygon.outlineColor, defaultOutlineColor); + this._outlineColorProperty = outlineEnabled ? defaultValue(polygon.outlineColor, defaultOutlineColor) : undefined; - var perPositionHeight = polygon.perPositionHeight; var height = polygon.height; var extrudedHeight = polygon.extrudedHeight; var granularity = polygon.granularity; var stRotation = polygon.stRotation; + var perPositionHeight = polygon.perPositionHeight; + + this._isClosed = defined(extrudedHeight); + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; if (!vertexPositions.isConstant || // - defined(perPositionHeight) && !perPositionHeight.isConstant || // defined(height) && !height.isConstant || // defined(extrudedHeight) && !extrudedHeight.isConstant || // defined(granularity) && !granularity.isConstant || // - defined(stRotation) && !stRotation.isConstant) { - if (this._geometryType !== GeometryBatchType.DYNAMIC) { - this._geometryType = GeometryBatchType.DYNAMIC; + defined(stRotation) && !stRotation.isConstant || // + defined(perPositionHeight) && !perPositionHeight.isConstant) { + if (!this._dynamic) { + this._dynamic = true; this._geometryChanged.raiseEvent(this); } } else { var options = this._options; options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.VERTEX_FORMAT; options.polygonHierarchy.positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.polygonHierarchy.positions); - options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; - - var isClosed = defined(options.extrudedHeight); - if (isClosed) { - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_CLOSED : GeometryBatchType.MATERIAL_CLOSED; - } else { - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; - } - this._outlineEnabled = outlineEnabled; + options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._dynamic = false; this._geometryChanged.raiseEvent(this); } }; PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError(); + } + + if (!defined(primitives)) { + throw new DeveloperError(); + } + return new DynamicGeometryUpdater(primitives, this); }; @@ -284,6 +333,10 @@ define(['../Core/Color', }; DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + var geometryUpdater = this._geometryUpdater; if (defined(this._primitive)) { @@ -303,6 +356,7 @@ define(['../Core/Color', } var options = this._options; + var vertexPositions = dynamicObject.vertexPositions; var perPositionHeight = polygon.perPositionHeight; var height = polygon.height; @@ -311,13 +365,14 @@ define(['../Core/Color', var stRotation = polygon.stRotation; options.polygonHierarchy.positions = vertexPositions.getValue(time, options.polygonHierarchy.positions); - options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(time) : undefined; options.height = defined(height) ? height.getValue(time, options) : undefined; options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(time, options) : undefined; options.granularity = defined(granularity) ? granularity.getValue(time) : undefined; options.stRotation = defined(stRotation) ? stRotation.getValue(time) : undefined; if (!defined(polygon.fill) || polygon.fill.getValue(time)) { + options.perPositionHeight = defined(perPositionHeight) ? perPositionHeight.getValue(time) : undefined; + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); var material = this._material; var appearance = new MaterialAppearance({ @@ -361,6 +416,10 @@ define(['../Core/Color', } }; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 153605959dcd..4fed08d92073 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -13,7 +13,6 @@ define(['../Core/Color', '../Core/ShowGeometryInstanceAttribute', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', - '../DynamicScene/GeometryBatchType', '../DynamicScene/MaterialProperty', '../Scene/PolylineMaterialAppearance', '../Scene/PolylineColorAppearance', @@ -33,7 +32,6 @@ define(['../Core/Color', ShowGeometryInstanceAttribute, ColorMaterialProperty, ConstantProperty, - GeometryBatchType, MaterialProperty, PolylineMaterialAppearance, PolylineColorAppearance, @@ -58,7 +56,8 @@ define(['../Core/Color', this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); - this._geometryType = GeometryBatchType.NONE; + this._fillEnabled = false; + this._dynamic = false; this._geometryChanged = new Event(); this._showProperty = undefined; this._materialProperty = undefined; @@ -76,14 +75,16 @@ define(['../Core/Color', return this._dynamicObject; } }, - geometryType : { + fillEnabled : { get : function() { - return this._geometryType; + return this._fillEnabled; } }, - geometryChanged : { + hasConstantFill : { get : function() { - return this._geometryChanged; + return !this._fillEnabled || + (!defined(this._dynamicObject.availability) && + (!defined(this._showProperty) || this._showProperty.isConstant)); } }, fillMaterialProperty : { @@ -96,11 +97,6 @@ define(['../Core/Color', return false; } }, - hasConstantFill : { - get : function() { - return true; - } - }, hasConstantOutline : { get : function() { return true; @@ -110,6 +106,21 @@ define(['../Core/Color', get : function() { return undefined; } + }, + isDynamic : { + get : function() { + return this._dynamic; + } + }, + isClosed : { + get : function() { + return false; + } + }, + geometryChanged : { + get : function() { + return this._geometryChanged; + } } }); @@ -118,18 +129,30 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.isFilled = function(time) { - return true; + var dynamicObject = this._dynamicObject; + return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time); }; PolylineGeometryUpdater.prototype.createGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError(); + } + + if (!this._fillEnabled) { + throw new DeveloperError(); + } + var color; var attributes; var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time)); - if (this._geometryType === GeometryBatchType.COLOR_OPEN) { - var currentColor = (isAvailable && defined(this._materialProperty.color)) ? this._materialProperty.color.getValue(time) : Color.WHTE; + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } color = ColorGeometryInstanceAttribute.fromColor(currentColor); attributes = { show : show, @@ -152,6 +175,10 @@ define(['../Core/Color', throw new DeveloperError(); }; + PolylineGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + PolylineGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -165,8 +192,8 @@ define(['../Core/Color', var polyline = this._dynamicObject.polyline; if (!defined(polyline)) { - if (this._geometryType !== GeometryBatchType.NONE) { - this._geometryType = GeometryBatchType.NONE; + if (this._fillEnabled) { + this._fillEnabled = false; this._geometryChanged.raiseEvent(this); } return; @@ -177,8 +204,8 @@ define(['../Core/Color', var show = polyline.show; if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // (!defined(vertexPositions))) { - if (this._geometryType !== GeometryBatchType.NONE) { - this._geometryType = GeometryBatchType.NONE; + if (this._fillEnabled) { + this._fillEnabled = false; this._geometryChanged.raiseEvent(this); } return; @@ -188,27 +215,45 @@ define(['../Core/Color', var isColorMaterial = material instanceof ColorMaterialProperty; this._materialProperty = material; this._showProperty = defaultValue(show, defaultShow); + this._fillEnabled = true; var width = polyline.width; - if (!vertexPositions.isConstant || // - defined(width) && !width.isConstant) { - if (this._geometryType !== GeometryBatchType.DYNAMIC) { - this._geometryType = GeometryBatchType.DYNAMIC; + if (!vertexPositions.isConstant || (defined(width) && !width.isConstant)) { + if (!this._dynamic) { + this._dynamic = true; this._geometryChanged.raiseEvent(this); } } else { var options = this._options; + var positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.positions); + + //Because of the way we currently handle reference properties, + //we can't automatically assume the positions are always valid. + if (!defined(positions) || positions.length < 2) { + if (this._fillEnabled) { + this._fillEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + options.vertexFormat = isColorMaterial ? PolylineColorAppearance.VERTEX_FORMAT : PolylineMaterialAppearance.VERTEX_FORMAT; - options.positions = vertexPositions.getValue(Iso8601.MINIMUM_VALUE, options.positions); + options.positions = positions; options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; - - this._geometryType = isColorMaterial ? GeometryBatchType.COLOR_OPEN : GeometryBatchType.MATERIAL_OPEN; + this._dynamic = false; this._geometryChanged.raiseEvent(this); } }; PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError(); + } + + if (!defined(primitives)) { + throw new DeveloperError(); + } return new DynamicGeometryUpdater(primitives, this); }; @@ -236,9 +281,17 @@ define(['../Core/Color', var options = this._options; var vertexPositions = dynamicObject.vertexPositions; - var width = polyline.width; - options.positions = vertexPositions.getValue(time, options.positions); + var positions = vertexPositions.getValue(time, options.positions); + //Because of the way we currently handle reference properties, + //we can't automatically assume the positions are always valid. + if (!defined(positions) || positions.length < 2) { + return; + } + + options.positions = positions; + + var width = polyline.width; options.width = defined(width) ? width.getValue(time) : undefined; this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); From 78740a30db8c95f6e000e2961c06bc227cd0b9ac Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 10:35:07 -0500 Subject: [PATCH 48/81] Start adding updater specs Add specs for EllipseGeoemtryUpdater and EllipsoidGeometryUpdater. Coverage is good, but lots of cases are probably still untested. Dynamic geometry specs are also incomplete. --- Source/DynamicScene/DataSourceDisplay.js | 8 +- Source/DynamicScene/PositionPropertyArray.js | 15 +- Source/DynamicScene/PropertyArray.js | 21 +- .../EllipseGeometryUpdaterSpec.js | 537 +++++++++++++++--- .../EllipsoidGeometryUpdaterSpec.js | 435 ++++++++++++++ ...pertyArraySepc.js => PropertyArraySpec.js} | 4 +- 6 files changed, 927 insertions(+), 93 deletions(-) create mode 100644 Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js rename Specs/DynamicScene/{PropertyArraySepc.js => PropertyArraySpec.js} (96%) diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index ff6f6d88aa61..6e2a0e8a4aca 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -45,16 +45,16 @@ define([ return new GeometryVisualizer(EllipseGeometryUpdater, scene); }, function(scene) { return new GeometryVisualizer(EllipsoidGeometryUpdater, scene); + }, function(scene) { + return new GeometryVisualizer(PolygonGeometryUpdater, scene); + }, function(scene) { + return new GeometryVisualizer(PolylineGeometryUpdater, scene); }, function(scene) { return new DynamicConeVisualizerUsingCustomSensor(scene); }, function(scene) { return new DynamicLabelVisualizer(scene); }, function(scene) { return new DynamicPointVisualizer(scene); - }, function(scene) { - return new GeometryVisualizer(PolygonGeometryUpdater, scene); - }, function(scene) { - return new GeometryVisualizer(PolylineGeometryUpdater, scene); }, function(scene) { return new DynamicVectorVisualizer(scene); }, function(scene) { diff --git a/Source/DynamicScene/PositionPropertyArray.js b/Source/DynamicScene/PositionPropertyArray.js index f0eccba10817..c9fcaa5604ed 100644 --- a/Source/DynamicScene/PositionPropertyArray.js +++ b/Source/DynamicScene/PositionPropertyArray.js @@ -122,15 +122,18 @@ define(['../Core/defaultValue', if (!defined(result)) { result = new Array(length); } - for (var i = 0; i < length; i++) { + var i = 0; + var x = 0; + while (i < length) { var property = this._value[i]; - if (defined(property)) { - result[i] = property.getValueInReferenceFrame(time, referenceFrame, result[i]); - } else { - result[i] = undefined; + var value = property.getValueInReferenceFrame(time, referenceFrame, result[i]); + if (defined(value)) { + result[x] = value; + x++; } + i++; } - result.length = length; + result.length = x; return result; }; diff --git a/Source/DynamicScene/PropertyArray.js b/Source/DynamicScene/PropertyArray.js index 652651825491..df9548f42eec 100644 --- a/Source/DynamicScene/PropertyArray.js +++ b/Source/DynamicScene/PropertyArray.js @@ -78,6 +78,12 @@ define(['../Core/defaultValue', * @returns {Array} The modified result parameter or a new instance if the result parameter was not supplied. */ PropertyArray.prototype.getValue = function(time, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + //>>includeEnd('debug'); + if (!defined(this._value)) { return undefined; } @@ -86,15 +92,18 @@ define(['../Core/defaultValue', if (!defined(result)) { result = new Array(length); } - for (var i = 0; i < length; i++) { + var i = 0; + var x = 0; + while (i < length) { var property = this._value[i]; - if (defined(property)) { - result[i] = property.getValue(time, result[i]); - } else { - result[i] = undefined; + var value = property.getValue(time, result[i]); + if (defined(value)) { + result[x] = value; + x++; } + i++; } - result.length = length; + result.length = x; return result; }; diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 6175fe887c06..26c03a81e683 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -5,12 +5,18 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', 'Core/Cartesian3', 'Core/Color', 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection', + 'Core/ColorGeometryInstanceAttribute', + 'Core/ShowGeometryInstanceAttribute', + 'DynamicScene/ColorMaterialProperty', 'DynamicScene/ConstantProperty', 'DynamicScene/ConstantPositionProperty', - 'DynamicScene/GeometryBatchType', 'DynamicScene/GridMaterialProperty', 'DynamicScene/SampledProperty', - 'DynamicScene/SampledPositionProperty' + 'DynamicScene/SampledPositionProperty', + 'DynamicScene/TimeIntervalCollectionProperty', + 'Scene/CompositePrimitive' ], function( EllipseGeometryUpdater, DynamicObject, @@ -18,99 +24,480 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', Cartesian3, Color, JulianDate, + TimeInterval, + TimeIntervalCollection, + ColorGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, ConstantProperty, ConstantPositionProperty, - GeometryBatchType, GridMaterialProperty, SampledProperty, - SampledPositionProperty) { + SampledPositionProperty, + TimeIntervalCollectionProperty, + CompositePrimitive) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - it('GeometryBatchType is always set correctly', function() { - //Undefined position && ellipse + var time = new JulianDate(); + + function createBasicEllipse() { + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(Cartesian3.ZERO); + dynamicObject.ellipse = ellipse; + return dynamicObject; + } + + it('Constructor sets expected defaults', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipseGeometryUpdater(dynamicObject); + + expect(updater.isDestroyed()).toBe(false); + expect(updater.dynamicObject).toBe(dynamicObject); + expect(updater.isClosed).toBe(false); + expect(updater.fillEnabled).toBe(false); + expect(updater.fillMaterialProperty).toBe(undefined); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + expect(updater.isOutlineVisible(time)).toBe(false); + expect(updater.isFilled(time)).toBe(false); + updater.destroy(); + expect(updater.isDestroyed()).toBe(true); + }); + + it('No geometry available when ellipse is undefined ', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse = undefined; + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('No geometry available when semiMajorAxis is undefined', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.semiMajorAxis = undefined; + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('No geometry available when semiMinorAxis is undefined', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.semiMinorAxis = undefined; + + 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 dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.fill = new ConstantProperty(false); + dynamicObject.ellipse.outline = new ConstantProperty(false); + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('Values correct when using default graphics', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + + expect(updater.isClosed).toBe(false); + 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.isDynamic).toBe(false); + }); + + it('Ellipse material is correctly exposed.', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipse.material); + }); + + it('Settings extrudedHeight causes geometry to be closed.', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.extrudedHeight = new ConstantProperty(1000); + expect(updater.isClosed).toBe(true); + }); + + it('Ellipse material is correctly exposed.', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipse.material); + }); + + it('A time-varying position causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.position = new SampledPositionProperty(); + dynamicObject.position.addSample(time, Cartesian3.ZERO); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying semiMinorAxis causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.semiMinorAxis = new SampledProperty(Number); + dynamicObject.ellipse.semiMinorAxis.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying semiMajorAxis causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.semiMajorAxis = new SampledProperty(Number); + dynamicObject.ellipse.semiMajorAxis.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying rotation causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.rotation = new SampledProperty(Number); + dynamicObject.ellipse.rotation.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying height causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.height = new SampledProperty(Number); + dynamicObject.ellipse.height.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying extrudedHeight causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.extrudedHeight = new SampledProperty(Number); + dynamicObject.ellipse.extrudedHeight.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying granularity causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.granularity = new SampledProperty(Number); + dynamicObject.ellipse.granularity.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying stRotation causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.stRotation = new SampledProperty(Number); + dynamicObject.ellipse.stRotation.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying numberOfVerticalLines causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + dynamicObject.ellipse.numberOfVerticalLines = new SampledProperty(Number); + dynamicObject.ellipse.numberOfVerticalLines.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + function validateGeometryInstance(options) { var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(options.center); + + var ellipse = new DynamicEllipse(); + ellipse.show = new ConstantProperty(options.show); + ellipse.fill = new ConstantProperty(options.fill); + ellipse.material = options.material; + ellipse.outline = new ConstantProperty(options.outline); + ellipse.outlineColor = new ConstantProperty(options.outlineColor); + ellipse.numberOfVerticalLines = new ConstantProperty(options.numberOfVerticalLines); + + ellipse.semiMajorAxis = new ConstantProperty(options.semiMajorAxis); + ellipse.semiMinorAxis = new ConstantProperty(options.semiMinorAxis); + ellipse.rotation = new ConstantProperty(options.rotation); + ellipse.stRotation = new ConstantProperty(options.stRotation); + ellipse.height = new ConstantProperty(options.height); + ellipse.extrudedHeight = new ConstantProperty(options.extrudedHeight); + ellipse.granularity = new ConstantProperty(options.granularity); + dynamicObject.ellipse = ellipse; + + var updater = new EllipseGeometryUpdater(dynamicObject); + + var instance; + var geometry; + var attributes; + if (options.fill) { + instance = updater.createGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._center).toEqual(options.center); + expect(geometry._semiMajorAxis).toEqual(options.semiMajorAxis); + expect(geometry._semiMinorAxis).toEqual(options.semiMinorAxis); + expect(geometry._rotation).toEqual(options.rotation); + expect(geometry._stRotation).toEqual(options.stRotation); + expect(geometry._height).toEqual(options.height); + expect(geometry._granularity).toEqual(options.granularity); + expect(geometry._extrudedHeight).toEqual(options.extrudedHeight); + + 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(options.fill)); + } + + if (options.outline) { + instance = updater.createOutlineGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._center).toEqual(options.center); + expect(geometry._semiMajorAxis).toEqual(options.semiMajorAxis); + expect(geometry._semiMinorAxis).toEqual(options.semiMinorAxis); + expect(geometry._rotation).toEqual(options.rotation); + expect(geometry._height).toEqual(options.height); + expect(geometry._granularity).toEqual(options.granularity); + expect(geometry._extrudedHeight).toEqual(options.extrudedHeight); + expect(geometry._numberOfVerticalLines).toEqual(options.numberOfVerticalLines); + + attributes = instance.attributes; + expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.outlineColor)); + expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(options.fill)); + } + } + + it('Creates expected per-color geometry', function() { + validateGeometryInstance({ + center : new Cartesian3(4, 5, 6), + rotation : 1, + semiMajorAxis : 3, + semiMinorAxis : 2, + show : true, + material : new ColorMaterialProperty(Color.RED), + height : 123, + extrudedHeight : 431, + granularity : 0.97, + stRotation : 12, + fill : true, + outline : true, + outlineColor : Color.BLUE, + numberOfVerticalLines : 15 + }); + }); + + it('Creates expected per-material geometry', function() { + validateGeometryInstance({ + center : new Cartesian3(4, 5, 6), + rotation : 1, + semiMajorAxis : 3, + semiMinorAxis : 2, + show : true, + material : new GridMaterialProperty(), + height : 123, + extrudedHeight : 431, + granularity : 0.97, + stRotation : 12, + fill : true, + outline : true, + outlineColor : Color.BLUE, + numberOfVerticalLines : 15 + }); + }); + + 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(time1, time2, true, true, false)); + fill.intervals.addInterval(new TimeInterval(time2, time3, false, true, 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(time1, time2, true, true, false)); + outline.intervals.addInterval(new TimeInterval(time2, time3, false, true, true)); + + var outlineColor = new SampledProperty(Color); + outlineColor.addSample(time, Color.BLUE); + outlineColor.addSample(time2, Color.RED); + outlineColor.addSample(time3, Color.YELLOW); + + var dynamicObject = createBasicEllipse(); + dynamicObject.ellipse.fill = fill; + dynamicObject.ellipse.material = colorMaterial; + dynamicObject.ellipse.outline = outline; + dynamicObject.ellipse.outlineColor = outlineColor; + var updater = new EllipseGeometryUpdater(dynamicObject); - expect(updater.geometryType).toBe(GeometryBatchType.NONE); - //Undefined ellipse - dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); - expect(updater.geometryType).toBe(GeometryBatchType.NONE); + var instance = updater.createGeometryInstance(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('dynamic updater sets properties', function() { + //Finish this test + var time1 = new JulianDate(0, 0); + var time2 = new JulianDate(1, 0); + var time3 = new JulianDate(2, 0); + + function makeProperty(value1, value2) { + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(new TimeInterval(time1, time2, true, false, value1)); + property.intervals.addInterval(new TimeInterval(time2, time3, true, false, value2)); + return property; + } - //Undefined ellipse.semiMajorAxis && ellipse.semiMinorAxis var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = makeProperty(2, 12); + ellipse.semiMinorAxis = makeProperty(1, 11); + ellipse.outline = makeProperty(true, false); + ellipse.fill = makeProperty(false, true); + + var dynamicObject = new DynamicObject(); + dynamicObject.availability = new TimeIntervalCollection(); + dynamicObject.availability.addInterval(new TimeInterval(time1, time3, true, false)); + dynamicObject.position = makeProperty(Cartesian3.UNIT_Z, Cartesian3.UNIT_Y); dynamicObject.ellipse = ellipse; - expect(updater.geometryType).toBe(GeometryBatchType.NONE); + var updater = new EllipseGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(dynamicUpdater.isDestroyed()).toBe(false); + + dynamicUpdater.update(time1); + dynamicUpdater.update(time2); + dynamicUpdater.update(time3); - //Undefined ellipse.semiMinorAxis - ellipse.semiMajorAxis = new ConstantProperty(1); - expect(updater.geometryType).toBe(GeometryBatchType.NONE); + dynamicUpdater.destroy(); + updater.destroy(); + }); - //Undefined ellipse.semiMajorAxis - ellipse.semiMajorAxis = undefined; - ellipse.semiMinorAxis = new ConstantProperty(2); - expect(updater.geometryType).toBe(GeometryBatchType.NONE); + it('geometryChanged event is raised when expected', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + var geometryChanged = updater.geometryChanged; + spyOn(geometryChanged, 'raiseEvent'); - //Default color - ellipse.semiMajorAxis = new ConstantProperty(1); - ellipse.semiMinorAxis = new ConstantProperty(2); - expect(updater.geometryType).toBe(GeometryBatchType.COLOR_OPEN); + dynamicObject.position = new ConstantPositionProperty(Cartesian3.UNIT_Z); + expect(geometryChanged.raiseEvent.callCount).toEqual(1); - //Non-color material - ellipse.material = new GridMaterialProperty(); - expect(updater.geometryType).toBe(GeometryBatchType.MATERIAL_OPEN); + dynamicObject.ellipse.semiMajorAxis = new ConstantProperty(82); + expect(geometryChanged.raiseEvent.callCount).toEqual(2); - //Dynamic position - dynamicObject.position = new SampledPositionProperty(); - dynamicObject.position.addSample(new JulianDate(), new Cartesian3()); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + dynamicObject.availability = new TimeIntervalCollection(); + expect(geometryChanged.raiseEvent.callCount).toEqual(3); - //Dynamic semiMinorAxis - dynamicObject.position = new ConstantPositionProperty(new Cartesian3()); - ellipse.semiMinorAxis = new SampledProperty(Number); - ellipse.semiMinorAxis.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); + dynamicObject.ellipse.semiMajorAxis = undefined; + expect(geometryChanged.raiseEvent.callCount).toEqual(4); - //Dynamic semiMajorAxis - ellipse.semiMinorAxis = new ConstantProperty(1); - ellipse.semiMajorAxis = new SampledProperty(Number); - ellipse.semiMajorAxis.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - - //Dynamic rotation - ellipse.semiMajorAxis = new ConstantProperty(1); - ellipse.rotation = new SampledProperty(Number); - ellipse.rotation.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - - //Dynamic height - ellipse.rotation = new ConstantProperty(1); - ellipse.height = new SampledProperty(Number); - ellipse.height.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - - //Dynamic extrudedHeight - ellipse.height = new ConstantProperty(1); - ellipse.extrudedHeight = new SampledProperty(Number); - ellipse.extrudedHeight.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - - //Dynamic granularity - ellipse.extrudedHeight = new ConstantProperty(1); - ellipse.granularity = new SampledProperty(Number); - ellipse.granularity.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - - //Dynamic stRotation - ellipse.granularity = new ConstantProperty(1); - ellipse.stRotation = new SampledProperty(Number); - ellipse.stRotation.addSample(new JulianDate(), 1); - expect(updater.geometryType).toBe(GeometryBatchType.DYNAMIC); - }); - - it('Throws if DynamicObject supplied', function() { + //Since there's no valid geometry, changing another property should not raise the event. + dynamicObject.ellipse.semiMinorAxis = undefined; + + //Modifying an unrelated property should not have any effect. + dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); + expect(geometryChanged.raiseEvent.callCount).toEqual(4); + + dynamicObject.ellipse.semiMajorAxis = new SampledProperty(Number); + dynamicObject.ellipse.semiMinorAxis = new SampledProperty(Number); + expect(geometryChanged.raiseEvent.callCount).toEqual(5); + }); + + it('createGeometryInstance throws if object is not filled', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(function() { + return updater.createGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(function() { + return updater.createGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if object is not outlined', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicEllipse(); + dynamicObject.ellipse.outline = new ConstantProperty(true); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if not dynamic', function() { + var dynamicObject = createBasicEllipse(); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(function() { + return updater.createDynamicUpdater(new CompositePrimitive()); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if primitives undefined', function() { + var dynamicObject = createBasicEllipse(); + dynamicObject.ellipse.semiMajorAxis = new SampledProperty(Number); + dynamicObject.ellipse.semiMajorAxis.addSample(time, 4); + var updater = new EllipseGeometryUpdater(dynamicObject); + expect(updater.isDynamic).toBe(true); + expect(function() { + return updater.createDynamicUpdater(undefined); + }).toThrowDeveloperError(); + }); + + it('dynamicUpdater.update throws if no time specified', function() { + var dynamicObject = createBasicEllipse(); + dynamicObject.ellipse.semiMajorAxis = new SampledProperty(Number); + dynamicObject.ellipse.semiMajorAxis.addSample(time, 4); + var updater = new EllipseGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(function() { + dynamicUpdater.update(undefined); + }).toThrowDeveloperError(); + }); + + it('Constructor throws if no DynamicObject supplied', function() { expect(function() { - return new EllipseGeometryUpdater(); - }).toThrow(); + return new EllipseGeometryUpdater(undefined); + }).toThrowDeveloperError(); }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js new file mode 100644 index 000000000000..5223c255f332 --- /dev/null +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -0,0 +1,435 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/EllipsoidGeometryUpdater', + 'DynamicScene/DynamicObject', + 'DynamicScene/DynamicEllipsoid', + 'Core/Cartesian3', + 'Core/Color', + 'Core/JulianDate', + 'Core/Quaternion', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection', + 'Core/ColorGeometryInstanceAttribute', + 'Core/ShowGeometryInstanceAttribute', + 'DynamicScene/ColorMaterialProperty', + 'DynamicScene/ConstantProperty', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/GridMaterialProperty', + 'DynamicScene/SampledProperty', + 'DynamicScene/SampledPositionProperty', + 'DynamicScene/TimeIntervalCollectionProperty', + 'Scene/CompositePrimitive' + ], function( + EllipsoidGeometryUpdater, + DynamicObject, + DynamicEllipsoid, + Cartesian3, + Color, + JulianDate, + Quaternion, + TimeInterval, + TimeIntervalCollection, + ColorGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + ConstantPositionProperty, + GridMaterialProperty, + SampledProperty, + SampledPositionProperty, + TimeIntervalCollectionProperty, + CompositePrimitive) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + function createBasicEllipsoid() { + var ellipsoid = new DynamicEllipsoid(); + ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(Cartesian3.ZERO); + dynamicObject.orientation = new ConstantProperty(Quaternion.IDENTITY); + dynamicObject.ellipsoid = ellipsoid; + return dynamicObject; + } + + it('Constructor sets expected defaults', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + + expect(updater.isDestroyed()).toBe(false); + expect(updater.dynamicObject).toBe(dynamicObject); + expect(updater.isClosed).toBe(true); + expect(updater.fillEnabled).toBe(false); + expect(updater.fillMaterialProperty).toBe(undefined); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + expect(updater.isOutlineVisible(time)).toBe(false); + expect(updater.isFilled(time)).toBe(false); + updater.destroy(); + expect(updater.isDestroyed()).toBe(true); + }); + + it('No geometry available when ellipsoid is undefined ', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid = undefined; + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('No geometry available when radii is undefined', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.radii = undefined; + + 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 dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.fill = new ConstantProperty(false); + dynamicObject.ellipsoid.outline = new ConstantProperty(false); + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('Values correct when using default graphics', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + + 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.isDynamic).toBe(false); + }); + + it('Ellipsoid material is correctly exposed.', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); + }); + + it('Ellipsoid material is correctly exposed.', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); + }); + + it('A time-varying position causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.position = new SampledPositionProperty(); + dynamicObject.position.addSample(time, Cartesian3.ZERO); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying radii causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.radii = new SampledProperty(Cartesian3); + dynamicObject.ellipsoid.radii.addSample(time, new Cartesian3(1, 2, 3)); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying stackPartitions causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.stackPartitions = new SampledProperty(Number); + dynamicObject.ellipsoid.stackPartitions.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying slicePartitions causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.slicePartitions = new SampledProperty(Number); + dynamicObject.ellipsoid.slicePartitions.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying subdivisions causes geometry to be dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + dynamicObject.ellipsoid.subdivisions = new SampledProperty(Number); + dynamicObject.ellipsoid.subdivisions.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + function validateGeometryInstance(options) { + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(options.position); + dynamicObject.orientation = new ConstantProperty(options.orientation); + + var ellipsoid = new DynamicEllipsoid(); + ellipsoid.show = new ConstantProperty(options.show); + ellipsoid.fill = new ConstantProperty(options.fill); + ellipsoid.material = options.material; + ellipsoid.outline = new ConstantProperty(options.outline); + ellipsoid.outlineColor = new ConstantProperty(options.outlineColor); + ellipsoid.numberOfVerticalLines = new ConstantProperty(options.numberOfVerticalLines); + ellipsoid.radii = new ConstantProperty(options.radii); + ellipsoid.stackPartitions = new ConstantProperty(options.stackPartitions); + ellipsoid.slicePartitions = new ConstantProperty(options.slicePartitions); + ellipsoid.subdivisions = new ConstantProperty(options.subdivisions); + dynamicObject.ellipsoid = ellipsoid; + + var updater = new EllipsoidGeometryUpdater(dynamicObject); + + var instance; + var geometry; + var attributes; + if (options.fill) { + instance = updater.createGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._center).toEqual(options.center); + expect(geometry._radii).toEqual(options.radii); + expect(geometry._stackPartitions).toEqual(options.stackPartitions); + expect(geometry._slicePartitions).toEqual(options.slicePartitions); + + 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(options.fill)); + } + + if (options.outline) { + instance = updater.createOutlineGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._center).toEqual(options.center); + expect(geometry._radii).toEqual(options.radii); + expect(geometry._stackPartitions).toEqual(options.stackPartitions); + expect(geometry._slicePartitions).toEqual(options.slicePartitions); + expect(geometry._subdivisions).toEqual(options.subdivisions); + + attributes = instance.attributes; + expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.outlineColor)); + expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(options.fill)); + } + } + + it('Creates expected per-color geometry', function() { + validateGeometryInstance({ + position : new Cartesian3(4, 5, 6), + orientation : Quaternion.IDENTITY, + radii : new Cartesian3(1, 2, 3), + show : true, + material : new ColorMaterialProperty(Color.RED), + fill : true, + outline : true, + outlineColor : Color.BLUE, + stackPartitions : 32, + slicePartitions : 64, + subdivisions : 15 + }); + }); + + it('Creates expected per-material geometry', function() { + validateGeometryInstance({ + position : new Cartesian3(4, 5, 6), + orientation : Quaternion.IDENTITY, + radii : new Cartesian3(1, 2, 3), + show : true, + material : new GridMaterialProperty(), + fill : true, + outline : true, + outlineColor : Color.BLUE, + stackPartitions : 32, + slicePartitions : 64, + subdivisions : 15 + }); + }); + + 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(time1, time2, true, true, false)); + fill.intervals.addInterval(new TimeInterval(time2, time3, false, true, 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(time1, time2, true, true, false)); + outline.intervals.addInterval(new TimeInterval(time2, time3, false, true, true)); + + var outlineColor = new SampledProperty(Color); + outlineColor.addSample(time, Color.BLUE); + outlineColor.addSample(time2, Color.RED); + outlineColor.addSample(time3, Color.YELLOW); + + var dynamicObject = createBasicEllipsoid(); + dynamicObject.ellipsoid.fill = fill; + dynamicObject.ellipsoid.material = colorMaterial; + dynamicObject.ellipsoid.outline = outline; + dynamicObject.ellipsoid.outlineColor = outlineColor; + + var updater = new EllipsoidGeometryUpdater(dynamicObject); + + var instance = updater.createGeometryInstance(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('dynamic updater sets properties', function() { + //Finish this test + var time1 = new JulianDate(0, 0); + var time2 = new JulianDate(1, 0); + var time3 = new JulianDate(2, 0); + + function makeProperty(value1, value2) { + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(new TimeInterval(time1, time2, true, false, value1)); + property.intervals.addInterval(new TimeInterval(time2, time3, true, false, value2)); + return property; + } + + var ellipsoid = new DynamicEllipsoid(); + ellipsoid.radii = makeProperty(new Cartesian3(1, 2, 3), new Cartesian3(4, 5, 6)); + ellipsoid.outline = makeProperty(true, false); + ellipsoid.fill = makeProperty(false, true); + + var dynamicObject = new DynamicObject(); + dynamicObject.availability = new TimeIntervalCollection(); + dynamicObject.availability.addInterval(new TimeInterval(time1, time3, true, false)); + dynamicObject.position = makeProperty(Cartesian3.UNIT_Z, Cartesian3.UNIT_Y); + dynamicObject.orientation = makeProperty(Quaternion.IDENTITY, new Quaternion(0, 1, 0, 0)); + dynamicObject.ellipsoid = ellipsoid; + var updater = new EllipsoidGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(dynamicUpdater.isDestroyed()).toBe(false); + + dynamicUpdater.update(time1); + dynamicUpdater.update(time2); + dynamicUpdater.update(time3); + + dynamicUpdater.destroy(); + updater.destroy(); + }); + + it('geometryChanged event is raised when expected', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + var geometryChanged = updater.geometryChanged; + spyOn(geometryChanged, 'raiseEvent'); + + dynamicObject.position = new ConstantPositionProperty(Cartesian3.UNIT_Z); + expect(geometryChanged.raiseEvent.callCount).toEqual(1); + + dynamicObject.ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); + expect(geometryChanged.raiseEvent.callCount).toEqual(2); + + dynamicObject.availability = new TimeIntervalCollection(); + expect(geometryChanged.raiseEvent.callCount).toEqual(3); + + dynamicObject.ellipsoid.radii = undefined; + expect(geometryChanged.raiseEvent.callCount).toEqual(4); + + //Modifying an unrelated property should not have any effect. + dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); + expect(geometryChanged.raiseEvent.callCount).toEqual(4); + + dynamicObject.ellipsoid.radii = new SampledProperty(Cartesian3); + expect(geometryChanged.raiseEvent.callCount).toEqual(5); + }); + + it('createGeometryInstance throws if object is not filled', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(function() { + return updater.createGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(function() { + return updater.createGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if object is not outlined', function() { + var dynamicObject = new DynamicObject(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicEllipsoid(); + dynamicObject.ellipsoid.outline = new ConstantProperty(true); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if not dynamic', function() { + var dynamicObject = createBasicEllipsoid(); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(function() { + return updater.createDynamicUpdater(new CompositePrimitive()); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if primitives undefined', function() { + var dynamicObject = createBasicEllipsoid(); + dynamicObject.ellipsoid.radii = new SampledProperty(Number); + dynamicObject.ellipsoid.radii.addSample(time, 4); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + expect(updater.isDynamic).toBe(true); + expect(function() { + return updater.createDynamicUpdater(undefined); + }).toThrowDeveloperError(); + }); + + it('dynamicUpdater.update throws if no time specified', function() { + var dynamicObject = createBasicEllipsoid(); + dynamicObject.ellipsoid.radii = new SampledProperty(Number); + dynamicObject.ellipsoid.radii.addSample(time, 4); + var updater = new EllipsoidGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(function() { + dynamicUpdater.update(undefined); + }).toThrowDeveloperError(); + }); + + it('Constructor throws if no DynamicObject supplied', function() { + expect(function() { + return new EllipsoidGeometryUpdater(undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file diff --git a/Specs/DynamicScene/PropertyArraySepc.js b/Specs/DynamicScene/PropertyArraySpec.js similarity index 96% rename from Specs/DynamicScene/PropertyArraySepc.js rename to Specs/DynamicScene/PropertyArraySpec.js index 4864a87d0753..5d774a841049 100644 --- a/Specs/DynamicScene/PropertyArraySepc.js +++ b/Specs/DynamicScene/PropertyArraySpec.js @@ -60,10 +60,10 @@ defineSuite(['DynamicScene/PropertyArray', expect(property.getValue()).toBeUndefined(); }); - it('works with undefined propertyvalue', function() { + it('ignores undefined property values', function() { var property = new PropertyArray(); property.setValue([new ConstantProperty()]); - expect(property.getValue()).toEqual([undefined]); + expect(property.getValue()).toEqual([]); }); it('works with empty array', function() { From 147f5db635e10b6d2cd5cc0a79f6c5ba8feae33c Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 15:44:55 -0500 Subject: [PATCH 49/81] First pass at documenting GeometryUpdater & DynamicGeoemtryUpdater. --- Source/DynamicScene/DynamicGeometryUpdater.js | 54 ++++++ Source/DynamicScene/EllipseGeometryUpdater.js | 11 +- .../DynamicScene/EllipsoidGeometryUpdater.js | 11 +- Source/DynamicScene/GeometryUpdater.js | 174 +++++++++++++++--- Source/DynamicScene/PolygonGeometryUpdater.js | 11 +- .../DynamicScene/PolylineGeometryUpdater.js | 12 +- .../DynamicScene/StaticGeometryColorBatch.js | 6 +- .../StaticGeometryPerMaterialBatch.js | 2 +- .../EllipseGeometryUpdaterSpec.js | 12 +- .../EllipsoidGeometryUpdaterSpec.js | 12 +- 10 files changed, 252 insertions(+), 53 deletions(-) create mode 100644 Source/DynamicScene/DynamicGeometryUpdater.js diff --git a/Source/DynamicScene/DynamicGeometryUpdater.js b/Source/DynamicScene/DynamicGeometryUpdater.js new file mode 100644 index 000000000000..641bb7615bdb --- /dev/null +++ b/Source/DynamicScene/DynamicGeometryUpdater.js @@ -0,0 +1,54 @@ +/*global define*/ +define(['../Core/DeveloperError' + ], function( + DeveloperError) { + "use strict"; + + /** + * Defines the interface for a dynamic geometry updater. A DynamicGeometryUpdater + * is responsible for handling visualization of a specific type of geometry + * that needs to be recomputed based on simulation time. + * This classes is never used directly by client code, but is instead created by + * {@link GeometryUpdater} implementations which contain dynamic geometry. + * + * This type defines an interface and cannot be instantiated directly. + * + * @alias DynamicGeometryUpdater + * @constructor + */ + var DynamicGeometryUpdater = function() { + DeveloperError.throwInstantiationError(); + }; + + /** + * Updates the geometry to the specified time. + * @memberof DynamicGeometryUpdater + * + * @param {JulianDate} time The current time. + */ + DynamicGeometryUpdater.prototype.update = function(time) { + DeveloperError.throwInstantiationError(); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof DynamicGeometryUpdater + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + DynamicGeometryUpdater.prototype.isDestroyed = function() { + DeveloperError.throwInstantiationError(); + }; + + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof DynamicGeometryUpdater + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + DynamicGeometryUpdater.prototype.destroy = function() { + DeveloperError.throwInstantiationError(); + }; + + return DynamicGeometryUpdater; +}); \ No newline at end of file diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index acf5ff60969a..a09d267747ce 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -154,7 +154,7 @@ define(['../Core/Color', return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; - EllipseGeometryUpdater.prototype.createGeometryInstance = function(time) { + EllipseGeometryUpdater.prototype.createFillGeometryInstance = function(time) { if (!defined(time)) { throw new DeveloperError(); } @@ -323,17 +323,20 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError(); + if (this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } if (!defined(primitives)) { - throw new DeveloperError(); + throw new DeveloperError('primitives is required.'); } return new DynamicGeometryUpdater(primitives, this); }; + /** + * @private + */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index f824121f51a7..82ee69fc4a68 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -155,7 +155,7 @@ define(['../Core/Color', return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; - EllipsoidGeometryUpdater.prototype.createGeometryInstance = function(time) { + EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function(time) { if (!defined(time)) { throw new DeveloperError(); } @@ -319,17 +319,20 @@ define(['../Core/Color', }; EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError(); + if (this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } if (!defined(primitives)) { - throw new DeveloperError(); + throw new DeveloperError('primitives is required.'); } return new DynamicGeometryUpdater(primitives, this); }; + /** + * @private + */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js index 9bfecc6585c9..42ecd45f23aa 100644 --- a/Source/DynamicScene/GeometryUpdater.js +++ b/Source/DynamicScene/GeometryUpdater.js @@ -1,61 +1,156 @@ /*global define*/ -define(['../Core/defineProperties', '../Core/DeveloperError'], function(defineProperties, DeveloperError) { +define(['../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defineProperties, + DeveloperError) { "use strict"; + /** + * Defines the interface for a geometry updater. A GeometryUpdater maps + * geometry defined as part of a {@link DynamicObject} into {@link Geometry} + * and {@link Appearance} instances. These instances are then visualized by + * {@link GeometryVisualizer}. + * + * This type defines an interface and cannot be instantiated directly. + * + * @alias GeometryUpdater + * @constructor + * + * @param {DynamicObject} dynamicObject The instance containing the geometry to be visualized. + * + * @see EllipseGeometryUpdater + * @see EllipsoidGeometryUpdater + * @see PolygonGeometryUpdater + * @see PolylineGeometryUpdater + */ var GeometryUpdater = function(dynamicObject) { DeveloperError.throwInstantiationError(); }; - GeometryUpdater.PerInstanceColorAppearanceType = undefined; - - GeometryUpdater.MaterialAppearanceType = undefined; + defineProperties(GeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based material geometry. + * @memberof GeometryUpdater + * @type {Appearance} + */ + PerInstanceColorAppearanceType : { + get : function() { + DeveloperError.throwInstantiationError(); + } + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof GeometryUpdater + * @type {Appearance} + */ + MaterialAppearanceType : { + get : function() { + DeveloperError.throwInstantiationError(); + } + } + }); defineProperties(GeometryUpdater.prototype, { + /** + * Gets the object associated with this geometry. + * @memberof GeometryUpdater.prototype + * @type {DynamicObject} + */ dynamicObject : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ fillEnabled : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ hasConstantFill : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets the material property used to fill the geometry. + * @memberof GeometryUpdater.prototype + * @type {MaterialProperty} + */ fillMaterialProperty : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ outlineEnabled : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ hasConstantOutline : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof GeometryUpdater.prototype + * @type {Property} + */ outlineColorProperty : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ isDynamic : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets a value indicating if the geometry is closed. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ isClosed : { get : function() { DeveloperError.throwInstantiationError(); } }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof GeometryUpdater.prototype + * @type {Boolean} + */ geometryChanged : { get : function() { DeveloperError.throwInstantiationError(); @@ -63,49 +158,86 @@ define(['../Core/defineProperties', '../Core/DeveloperError'], function(definePr } }); + /** + * Checks if the geometry is outlined at the provided time. + * @memberof GeometryUpdater + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ GeometryUpdater.prototype.isOutlineVisible = function(time) { DeveloperError.throwInstantiationError(); }; + /** + * Checks if the geometry is filled at the provided time. + * @memberof GeometryUpdater + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ GeometryUpdater.prototype.isFilled = function(time) { DeveloperError.throwInstantiationError(); }; - GeometryUpdater.prototype.createGeometryInstance = function(time) { + /** + * Creates the geometry instance which represents the fill of the geometry. + * @memberof GeometryUpdater + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + GeometryUpdater.prototype.createFillGeometryInstance = function(time) { DeveloperError.throwInstantiationError(); }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * @memberof GeometryUpdater + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ GeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { DeveloperError.throwInstantiationError(); }; + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof GeometryUpdater + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ GeometryUpdater.prototype.isDestroyed = function() { DeveloperError.throwInstantiationError(); }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof GeometryUpdater + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ GeometryUpdater.prototype.destroy = function() { DeveloperError.throwInstantiationError(); }; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @memberof GeometryUpdater + * + * @param {CompositePrimitive} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ GeometryUpdater.prototype.createDynamicUpdater = function(primitives) { DeveloperError.throwInstantiationError(); }; - var DynamicGeometryUpdater = function(primitives, geometryUpdater) { - DeveloperError.throwInstantiationError(); - }; - - DynamicGeometryUpdater.prototype.update = function(time) { - DeveloperError.throwInstantiationError(); - }; - - DynamicGeometryUpdater.prototype.isDestroyed = function() { - DeveloperError.throwInstantiationError(); - }; - - DynamicGeometryUpdater.prototype.destroy = function() { - DeveloperError.throwInstantiationError(); - }; - return GeometryUpdater; }); \ No newline at end of file diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 932875e8f34f..f002db48409b 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -153,7 +153,7 @@ define(['../Core/Color', return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; - PolygonGeometryUpdater.prototype.createGeometryInstance = function(time) { + PolygonGeometryUpdater.prototype.createFillGeometryInstance = function(time) { if (!defined(time)) { throw new DeveloperError(); } @@ -313,17 +313,20 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError(); + if (this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } if (!defined(primitives)) { - throw new DeveloperError(); + throw new DeveloperError('primitives is required.'); } return new DynamicGeometryUpdater(primitives, this); }; + /** + * @private + */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 4fed08d92073..71ffc369135a 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -133,7 +133,7 @@ define(['../Core/Color', return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time); }; - PolylineGeometryUpdater.prototype.createGeometryInstance = function(time) { + PolylineGeometryUpdater.prototype.createFillGeometryInstance = function(time) { if (!defined(time)) { throw new DeveloperError(); } @@ -247,16 +247,20 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError(); + if (this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } if (!defined(primitives)) { - throw new DeveloperError(); + throw new DeveloperError('primitives is required.'); } + return new DynamicGeometryUpdater(primitives, this); }; + /** + * @private + */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { this._primitives = primitives; this._primitive = undefined; diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 1a3780efe7ed..6d657bf08716 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -120,7 +120,7 @@ define(['../Core/Color', }; StaticGeometryColorBatch.prototype.add = function(time, updater) { - var instance = updater.createGeometryInstance(time); + var instance = updater.createFillGeometryInstance(time); if (instance.attributes.color.value[3] === 255) { this._solidBatch.add(updater, instance); } else { @@ -150,7 +150,7 @@ define(['../Core/Color', for (i = 0; i < solidsToMoveLength; i++) { updater = itemsToRemove[i]; this._solidBatch.remove(updater); - this._translucentBatch.add(updater, updater.createGeometryInstance(time)); + this._translucentBatch.add(updater, updater.createFillGeometryInstance(time)); } } @@ -161,7 +161,7 @@ define(['../Core/Color', for (i = 0; i < translucentToMoveLength; i++) { updater = itemsToRemove[i]; this._translucentBatch.remove(updater); - this._solidBatch.add(updater, updater.createGeometryInstance(time)); + this._solidBatch.add(updater, updater.createFillGeometryInstance(time)); } } diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 37ac8530fd90..37e14fd6a4b9 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -51,7 +51,7 @@ define(['../Core/defined', Batch.prototype.add = function(time, updater) { var id = updater.dynamicObject.id; this.updaters.set(id, updater); - this.geometry.set(id, updater.createGeometryInstance(time)); + this.geometry.set(id, updater.createFillGeometryInstance(time)); if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) { this.updatersWithAttributes.set(id, updater); } diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 26c03a81e683..4475919e1abb 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -247,7 +247,7 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', var geometry; var attributes; if (options.fill) { - instance = updater.createGeometryInstance(time); + instance = updater.createFillGeometryInstance(time); geometry = instance.geometry; expect(geometry._center).toEqual(options.center); expect(geometry._semiMajorAxis).toEqual(options.semiMajorAxis); @@ -355,7 +355,7 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', var updater = new EllipseGeometryUpdater(dynamicObject); - var instance = updater.createGeometryInstance(time2); + 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))); @@ -432,19 +432,19 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', expect(geometryChanged.raiseEvent.callCount).toEqual(5); }); - it('createGeometryInstance throws if object is not filled', function() { + it('createFillGeometryInstance throws if object is not filled', function() { var dynamicObject = new DynamicObject(); var updater = new EllipseGeometryUpdater(dynamicObject); expect(function() { - return updater.createGeometryInstance(time); + return updater.createFillGeometryInstance(time); }).toThrowDeveloperError(); }); - it('createGeometryInstance throws if no time provided', function() { + it('createFillGeometryInstance throws if no time provided', function() { var dynamicObject = createBasicEllipse(); var updater = new EllipseGeometryUpdater(dynamicObject); expect(function() { - return updater.createGeometryInstance(undefined); + return updater.createFillGeometryInstance(undefined); }).toThrowDeveloperError(); }); diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index 5223c255f332..7dfe3e41bd4d 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -196,7 +196,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', var geometry; var attributes; if (options.fill) { - instance = updater.createGeometryInstance(time); + instance = updater.createFillGeometryInstance(time); geometry = instance.geometry; expect(geometry._center).toEqual(options.center); expect(geometry._radii).toEqual(options.radii); @@ -291,7 +291,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', var updater = new EllipsoidGeometryUpdater(dynamicObject); - var instance = updater.createGeometryInstance(time2); + 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))); @@ -364,19 +364,19 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', expect(geometryChanged.raiseEvent.callCount).toEqual(5); }); - it('createGeometryInstance throws if object is not filled', function() { + it('createFillGeometryInstance throws if object is not filled', function() { var dynamicObject = new DynamicObject(); var updater = new EllipsoidGeometryUpdater(dynamicObject); expect(function() { - return updater.createGeometryInstance(time); + return updater.createFillGeometryInstance(time); }).toThrowDeveloperError(); }); - it('createGeometryInstance throws if no time provided', function() { + it('createFillGeometryInstance throws if no time provided', function() { var dynamicObject = createBasicEllipsoid(); var updater = new EllipsoidGeometryUpdater(dynamicObject); expect(function() { - return updater.createGeometryInstance(undefined); + return updater.createFillGeometryInstance(undefined); }).toThrowDeveloperError(); }); From 6863e5bca5de6cd9344ed7f34514c8f0e1594544 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 16:28:12 -0500 Subject: [PATCH 50/81] Documentation fixes. --- Source/Core/AssociativeArray.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/Core/AssociativeArray.js b/Source/Core/AssociativeArray.js index 15dd1cc55e49..0e3cff3f0ef5 100644 --- a/Source/Core/AssociativeArray.js +++ b/Source/Core/AssociativeArray.js @@ -21,10 +21,10 @@ define(['./defined', defineProperties(AssociativeArray.prototype, { /** - * Get the number of items in the collection. + * Gets the number of items in the collection. * @memberof AssociativeArray.prototype * - * @returns {Number} The number of items in the collection. + * @type {Number} */ count : { get : function() { @@ -32,10 +32,12 @@ define(['./defined', } }, /** - * Get an unordered array of all values in the collection. + * Gets an unordered array of all values in the collection. * This is a live array that will automatically reflect the values in the collection, * it should not be modified directly. * @memberof AssociativeArray.prototype + * + * @type {Array} */ values : { get : function() { @@ -46,7 +48,7 @@ define(['./defined', /** * Associates the provided key with the provided value. If the key already - * exists in the array, it is overwritten. + * exists, it is overwritten with the new value. * @memberof AssociativeArray * * @param {String|Number} key A unique identifier. From 4dcd5256b6d4101f4e94b14f46a581f57852b4db Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 18:01:24 -0500 Subject: [PATCH 51/81] Fix some specs I accidentally broke. --- Source/DynamicScene/EllipseGeometryUpdater.js | 2 +- Source/DynamicScene/EllipsoidGeometryUpdater.js | 2 +- Source/DynamicScene/PolygonGeometryUpdater.js | 2 +- Source/DynamicScene/PolylineGeometryUpdater.js | 2 +- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 2 +- Specs/DynamicScene/PositionPropertyArraySepc.js | 2 +- Specs/DynamicScene/PropertyArraySpec.js | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index a09d267747ce..67166c42fcd0 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -323,7 +323,7 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (this._dynamic) { + if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 82ee69fc4a68..d077a0530ba5 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -319,7 +319,7 @@ define(['../Core/Color', }; EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (this._dynamic) { + if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index f002db48409b..df8c89e2e61b 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -313,7 +313,7 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (this._dynamic) { + if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 71ffc369135a..2b2e9ed01099 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -247,7 +247,7 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (this._dynamic) { + if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 37e14fd6a4b9..7458a23041d0 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -148,7 +148,7 @@ define(['../Core/defined', for (var i = length - 1; i >= 0; i--) { var item = items[i]; if (item.remove(updater)) { - if (item.updaters.count === 0) { + if (item.updaters.length === 0) { items.splice(i, 1); item.destroy(); } diff --git a/Specs/DynamicScene/PositionPropertyArraySepc.js b/Specs/DynamicScene/PositionPropertyArraySepc.js index f10d3ac2973c..9895d7588290 100644 --- a/Specs/DynamicScene/PositionPropertyArraySepc.js +++ b/Specs/DynamicScene/PositionPropertyArraySepc.js @@ -73,7 +73,7 @@ defineSuite(['DynamicScene/PositionPropertyArray', it('works with undefined propertyvalue', function() { var property = new PositionPropertyArray(); property.setValue([new ConstantPositionProperty()]); - expect(property.getValue(time)).toEqual([undefined]); + expect(property.getValue(time)).toEqual([]); }); it('works with empty array', function() { diff --git a/Specs/DynamicScene/PropertyArraySpec.js b/Specs/DynamicScene/PropertyArraySpec.js index 5d774a841049..bea2e9b8495b 100644 --- a/Specs/DynamicScene/PropertyArraySpec.js +++ b/Specs/DynamicScene/PropertyArraySpec.js @@ -57,19 +57,19 @@ defineSuite(['DynamicScene/PropertyArray', it('works with undefined value', function() { var property = new PropertyArray(); property.setValue(undefined); - expect(property.getValue()).toBeUndefined(); + expect(property.getValue(time)).toBeUndefined(); }); it('ignores undefined property values', function() { var property = new PropertyArray(); property.setValue([new ConstantProperty()]); - expect(property.getValue()).toEqual([]); + expect(property.getValue(time)).toEqual([]); }); it('works with empty array', function() { var property = new PropertyArray(); property.setValue([]); - expect(property.getValue()).toEqual([]); + expect(property.getValue(time)).toEqual([]); }); it('equals works', function() { From 4eeac6877e8f1f2028eb8bb13789fb20087cbdd6 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 22:02:54 -0500 Subject: [PATCH 52/81] Prefer jasmine.createSpy to spyOn --- .../DynamicScene/ColorMaterialPropertySpec.js | 14 +++--- .../CompositeMaterialPropertySpec.js | 30 ++++++------ .../CompositePositionPropertySpec.js | 30 ++++++------ Specs/DynamicScene/CompositePropertySpec.js | 30 ++++++------ .../ConstantPositionPropertySpec.js | 15 +++--- Specs/DynamicScene/ConstantPropertySpec.js | 10 ++-- Specs/DynamicScene/DynamicObjectSpec.js | 5 +- .../EllipseGeometryUpdaterSpec.js | 16 +++--- .../EllipsoidGeometryUpdaterSpec.js | 17 ++++--- .../DynamicScene/GridMaterialPropertySpec.js | 49 ++++++++++--------- .../DynamicScene/ImageMaterialPropertySpec.js | 25 +++++----- .../PolylineOutlineMaterialPropertySpec.js | 35 ++++++------- .../DynamicScene/PositionPropertyArraySepc.js | 10 ++-- Specs/DynamicScene/PropertyArraySpec.js | 10 ++-- Specs/DynamicScene/SampledPropertySpec.js | 30 +++++++----- ...eIntervalCollectionPositionPropertySpec.js | 13 ++--- .../TimeIntervalCollectionPropertySpec.js | 13 ++--- 17 files changed, 190 insertions(+), 162 deletions(-) diff --git a/Specs/DynamicScene/ColorMaterialPropertySpec.js b/Specs/DynamicScene/ColorMaterialPropertySpec.js index 90d50b17e903..cacaa74c1db9 100644 --- a/Specs/DynamicScene/ColorMaterialPropertySpec.js +++ b/Specs/DynamicScene/ColorMaterialPropertySpec.js @@ -84,17 +84,19 @@ defineSuite(['DynamicScene/ColorMaterialProperty', it('raises definitionChanged when a color property is assigned or modified', function() { var property = new ColorMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.color = new ConstantProperty(Color.WHITE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color.setValue(Color.BLACK); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + expect(listener.callCount).toEqual(0); }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/CompositeMaterialPropertySpec.js b/Specs/DynamicScene/CompositeMaterialPropertySpec.js index e27a8ff63364..22e4c4ad3557 100644 --- a/Specs/DynamicScene/CompositeMaterialPropertySpec.js +++ b/Specs/DynamicScene/CompositeMaterialPropertySpec.js @@ -86,27 +86,28 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); var property = new CompositeMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); interval1.data.color.setValue(Color.BLUE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); }); it('does not raise definitionChanged for an overwritten interval', function() { @@ -114,15 +115,16 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); var property = new CompositeMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); //interval2 overwrites interval1, so callCount should not increase. interval1.data.color.setValue(Color.BLUE); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); }); it('getValue throws with no time parameter', function() { diff --git a/Specs/DynamicScene/CompositePositionPropertySpec.js b/Specs/DynamicScene/CompositePositionPropertySpec.js index 503b8500309b..ea5149fa2286 100644 --- a/Specs/DynamicScene/CompositePositionPropertySpec.js +++ b/Specs/DynamicScene/CompositePositionPropertySpec.js @@ -181,27 +181,28 @@ defineSuite(['DynamicScene/CompositePositionProperty', var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); var property = new CompositePositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); }); it('does not raise definitionChanged for an overwritten interval', function() { @@ -209,14 +210,15 @@ defineSuite(['DynamicScene/CompositePositionProperty', var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantPositionProperty(new Cartesian3(4, 5, 6))); var property = new CompositePositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); //interval2 overwrites interval1, so callCount should not increase. interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/CompositePropertySpec.js b/Specs/DynamicScene/CompositePropertySpec.js index add45bba8792..7a3dbda34b28 100644 --- a/Specs/DynamicScene/CompositePropertySpec.js +++ b/Specs/DynamicScene/CompositePropertySpec.js @@ -80,27 +80,28 @@ defineSuite(['DynamicScene/CompositeProperty', var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); var property = new CompositeProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.removeInterval(interval2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); }); it('does not raise definitionChanged for an overwritten interval', function() { @@ -108,15 +109,16 @@ defineSuite(['DynamicScene/CompositeProperty', var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ConstantProperty(new Cartesian3(4, 5, 6))); var property = new CompositeProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval1); property.intervals.addInterval(interval2); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); //interval2 overwrites interval1, so callCount should not increase. interval1.data.setValue(new Cartesian3()); - expect(property.definitionChanged.raiseEvent.callCount).toBe(2); + expect(listener.callCount).toBe(2); }); it('getValue throws with no time parameter', function() { diff --git a/Specs/DynamicScene/ConstantPositionPropertySpec.js b/Specs/DynamicScene/ConstantPositionPropertySpec.js index 17987a9864a3..38bb8bf395c3 100644 --- a/Specs/DynamicScene/ConstantPositionPropertySpec.js +++ b/Specs/DynamicScene/ConstantPositionPropertySpec.js @@ -82,23 +82,26 @@ defineSuite(['DynamicScene/ConstantPositionProperty', it('setValue rasies definitionChanged event', function() { var property = new ConstantPositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue(new Cartesian3(1, 2, 3)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('setValue does not raise definitionChanged event with equal data', function() { var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0)); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue(new Cartesian3(0, 0, 0)); - expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + expect(listener.callCount).toBe(0); }); it('setValue raises definitionChanged when referenceFrame changes', function() { var property = new ConstantPositionProperty(new Cartesian3(0, 0, 0), ReferenceFrame.FIXED); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue(new Cartesian3(0, 0, 0), ReferenceFrame.INERTIAL); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('equals works', function() { diff --git a/Specs/DynamicScene/ConstantPropertySpec.js b/Specs/DynamicScene/ConstantPropertySpec.js index 08e17ff73ffd..9a63e0ef34c2 100644 --- a/Specs/DynamicScene/ConstantPropertySpec.js +++ b/Specs/DynamicScene/ConstantPropertySpec.js @@ -28,16 +28,18 @@ defineSuite(['DynamicScene/ConstantProperty', it('setValue rasies definitionChanged event', function() { var property = new ConstantProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue(5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('setValue does not raise definitionChanged event with equal data', function() { var property = new ConstantProperty(new Cartesian3(0, 0, 0)); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue(new Cartesian3(0, 0, 0)); - expect(property.definitionChanged.raiseEvent.callCount).toBe(0); + expect(listener.callCount).toBe(0); }); it('works with objects with result parameter', function() { diff --git a/Specs/DynamicScene/DynamicObjectSpec.js b/Specs/DynamicScene/DynamicObjectSpec.js index f190dcc964f9..1dd239f9f0ad 100644 --- a/Specs/DynamicScene/DynamicObjectSpec.js +++ b/Specs/DynamicScene/DynamicObjectSpec.js @@ -57,7 +57,8 @@ defineSuite([ var propertyNames = dynamicObject.propertyNames; var propertyNamesLength = propertyNames.length; - spyOn(dynamicObject.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + dynamicObject.definitionChanged.addEventListener(listener); var i; var name; @@ -70,7 +71,7 @@ defineSuite([ newValue = new ConstantProperty(1); oldValue = dynamicObject[propertyNames[i]]; dynamicObject[name] = newValue; - expect(dynamicObject.definitionChanged.raiseEvent).toHaveBeenCalledWith(dynamicObject, name, newValue, oldValue); + expect(listener).toHaveBeenCalledWith(dynamicObject, name, newValue, oldValue); } } }); diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 4475919e1abb..ea90512c6f01 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -405,31 +405,31 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', it('geometryChanged event is raised when expected', function() { var dynamicObject = createBasicEllipse(); var updater = new EllipseGeometryUpdater(dynamicObject); - var geometryChanged = updater.geometryChanged; - spyOn(geometryChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + updater.geometryChanged.addEventListener(listener); dynamicObject.position = new ConstantPositionProperty(Cartesian3.UNIT_Z); - expect(geometryChanged.raiseEvent.callCount).toEqual(1); + expect(listener.callCount).toEqual(1); dynamicObject.ellipse.semiMajorAxis = new ConstantProperty(82); - expect(geometryChanged.raiseEvent.callCount).toEqual(2); + expect(listener.callCount).toEqual(2); dynamicObject.availability = new TimeIntervalCollection(); - expect(geometryChanged.raiseEvent.callCount).toEqual(3); + expect(listener.callCount).toEqual(3); dynamicObject.ellipse.semiMajorAxis = undefined; - expect(geometryChanged.raiseEvent.callCount).toEqual(4); + expect(listener.callCount).toEqual(4); //Since there's no valid geometry, changing another property should not raise the event. dynamicObject.ellipse.semiMinorAxis = undefined; //Modifying an unrelated property should not have any effect. dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); - expect(geometryChanged.raiseEvent.callCount).toEqual(4); + expect(listener.callCount).toEqual(4); dynamicObject.ellipse.semiMajorAxis = new SampledProperty(Number); dynamicObject.ellipse.semiMinorAxis = new SampledProperty(Number); - expect(geometryChanged.raiseEvent.callCount).toEqual(5); + expect(listener.callCount).toEqual(5); }); it('createFillGeometryInstance throws if object is not filled', function() { diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index 7dfe3e41bd4d..0887c88b7062 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -341,27 +341,28 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('geometryChanged event is raised when expected', function() { var dynamicObject = createBasicEllipsoid(); var updater = new EllipsoidGeometryUpdater(dynamicObject); - var geometryChanged = updater.geometryChanged; - spyOn(geometryChanged, 'raiseEvent'); + + var listener = jasmine.createSpy('listener'); + updater.geometryChanged.addEventListener(listener); dynamicObject.position = new ConstantPositionProperty(Cartesian3.UNIT_Z); - expect(geometryChanged.raiseEvent.callCount).toEqual(1); + expect(listener.callCount).toEqual(1); dynamicObject.ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); - expect(geometryChanged.raiseEvent.callCount).toEqual(2); + expect(listener.callCount).toEqual(2); dynamicObject.availability = new TimeIntervalCollection(); - expect(geometryChanged.raiseEvent.callCount).toEqual(3); + expect(listener.callCount).toEqual(3); dynamicObject.ellipsoid.radii = undefined; - expect(geometryChanged.raiseEvent.callCount).toEqual(4); + expect(listener.callCount).toEqual(4); //Modifying an unrelated property should not have any effect. dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); - expect(geometryChanged.raiseEvent.callCount).toEqual(4); + expect(listener.callCount).toEqual(4); dynamicObject.ellipsoid.radii = new SampledProperty(Cartesian3); - expect(geometryChanged.raiseEvent.callCount).toEqual(5); + expect(listener.callCount).toEqual(5); }); it('createFillGeometryInstance throws if object is not filled', function() { diff --git a/Specs/DynamicScene/GridMaterialPropertySpec.js b/Specs/DynamicScene/GridMaterialPropertySpec.js index 7041f12442fc..bb55ec192b79 100644 --- a/Specs/DynamicScene/GridMaterialPropertySpec.js +++ b/Specs/DynamicScene/GridMaterialPropertySpec.js @@ -140,54 +140,55 @@ defineSuite(['DynamicScene/GridMaterialProperty', it('raises definitionChanged when a property is assigned or modified', function() { var property = new GridMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.color = new ConstantProperty(Color.WHITE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color.setValue(Color.BLACK); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); + expect(listener.callCount).toEqual(0); + listener.reset(); property.cellAlpha = new ConstantProperty(0.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.cellAlpha.setValue(1.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.cellAlpha = property.cellAlpha; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); + expect(listener.callCount).toEqual(0); + listener.reset(); property.lineCount = new ConstantProperty(5.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.lineCount.setValue(10.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.lineCount = property.lineCount; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); + expect(listener.callCount).toEqual(0); + listener.reset(); property.lineThickness = new ConstantProperty(5.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.lineThickness.setValue(10.0); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.lineThickness = property.lineThickness; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + expect(listener.callCount).toEqual(0); }); it('isConstant is only true when all properties are constant or undefined', function() { diff --git a/Specs/DynamicScene/ImageMaterialPropertySpec.js b/Specs/DynamicScene/ImageMaterialPropertySpec.js index e12993d4ebea..daae72415ac7 100644 --- a/Specs/DynamicScene/ImageMaterialPropertySpec.js +++ b/Specs/DynamicScene/ImageMaterialPropertySpec.js @@ -98,30 +98,31 @@ defineSuite([ it('raises definitionChanged when a property is assigned or modified', function() { var property = new ImageMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.image = new ConstantProperty('http://test.invalid/image.png'); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.image.setValue('http://test.invalid/image2.png'); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.image = property.image; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); + expect(listener.callCount).toEqual(0); + listener.reset(); property.repeat = new ConstantProperty(new Cartesian2(1.5, 1.5)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.repeat.setValue(new Cartesian2(1.0, 1.0)); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.repeat = property.repeat; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + expect(listener.callCount).toEqual(0); }); it('isConstant is only true when all properties are constant or undefined', function() { diff --git a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js index de8a3d4b2b32..9ccb767040e9 100644 --- a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js +++ b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js @@ -103,41 +103,42 @@ defineSuite(['DynamicScene/PolylineOutlineMaterialProperty', it('raises definitionChanged when a property is assigned or modified', function() { var property = new PolylineOutlineMaterialProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.color = new ConstantProperty(Color.RED); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color.setValue(Color.YELLOW); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.color = property.color; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); - property.definitionChanged.raiseEvent.reset(); + expect(listener.callCount).toEqual(0); + listener.reset(); property.outlineColor = new ConstantProperty(Color.BLUE); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.outlineColor.setValue(Color.GREEN); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.outlineColor = property.outlineColor; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + expect(listener.callCount).toEqual(0); property.outlineWidth = new ConstantProperty(2.5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.outlineWidth.setValue(1.5); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.outlineWidth = property.outlineWidth; - expect(property.definitionChanged.raiseEvent.callCount).toEqual(0); + expect(listener.callCount).toEqual(0); }); it('isConstant is only true when all properties are constant or undefined', function() { diff --git a/Specs/DynamicScene/PositionPropertyArraySepc.js b/Specs/DynamicScene/PositionPropertyArraySepc.js index 9895d7588290..39d6ec1ca810 100644 --- a/Specs/DynamicScene/PositionPropertyArraySepc.js +++ b/Specs/DynamicScene/PositionPropertyArraySepc.js @@ -32,18 +32,20 @@ defineSuite(['DynamicScene/PositionPropertyArray', it('setValue rasies definitionChanged event', function() { var property = new PositionPropertyArray(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue([]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('changing array member raises definitionChanged event', function() { var property = new PositionPropertyArray(); var item = new ConstantPositionProperty(Cartesian3.UNIT_X); property.setValue([item]); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); item.setValue(Cartesian3.UNIT_Z); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('works with result parameter', function() { diff --git a/Specs/DynamicScene/PropertyArraySpec.js b/Specs/DynamicScene/PropertyArraySpec.js index bea2e9b8495b..f880f56b55df 100644 --- a/Specs/DynamicScene/PropertyArraySpec.js +++ b/Specs/DynamicScene/PropertyArraySpec.js @@ -30,18 +30,20 @@ defineSuite(['DynamicScene/PropertyArray', it('setValue rasies definitionChanged event', function() { var property = new PropertyArray(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.setValue([]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('changing array member raises definitionChanged event', function() { var property = new PropertyArray(); var item = new ConstantProperty(1); property.setValue([item]); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); item.setValue(2); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); it('works with result parameter', function() { diff --git a/Specs/DynamicScene/SampledPropertySpec.js b/Specs/DynamicScene/SampledPropertySpec.js index aa9630c207d0..93363aa22981 100644 --- a/Specs/DynamicScene/SampledPropertySpec.js +++ b/Specs/DynamicScene/SampledPropertySpec.js @@ -32,11 +32,12 @@ defineSuite(['DynamicScene/SampledProperty', var epoch = new JulianDate(0, 0); var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.addSamplesPackedArray(data, epoch); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); expect(property.getValue(epoch)).toEqual(7); expect(property.getValue(new JulianDate(0, 0.5))).toEqual(7.5); }); @@ -46,19 +47,20 @@ defineSuite(['DynamicScene/SampledProperty', var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.addSample(times[0], values[0]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.addSample(times[1], values[1]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.addSample(times[2], values[2]); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); expect(property.getValue(times[0])).toEqual(values[0]); expect(property.getValue(times[1])).toEqual(values[1]); @@ -71,10 +73,11 @@ defineSuite(['DynamicScene/SampledProperty', var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)]; var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.addSamples(times, values); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); expect(property.getValue(times[0])).toEqual(values[0]); expect(property.getValue(times[1])).toEqual(values[1]); expect(property.getValue(times[2])).toEqual(values[2]); @@ -160,7 +163,8 @@ defineSuite(['DynamicScene/SampledProperty', }; var property = new SampledProperty(Number); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.addSamplesPackedArray(data, epoch); @@ -172,7 +176,7 @@ defineSuite(['DynamicScene/SampledProperty', interpolationDegree : 2 }); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); expect(property.getValue(epoch)).toEqual(7); expect(property.getValue(new JulianDate(0, 3))).toEqual(2); diff --git a/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js b/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js index 0ae994904073..9cc48d9e8677 100644 --- a/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js +++ b/Specs/DynamicScene/TimeIntervalCollectionPositionPropertySpec.js @@ -163,18 +163,19 @@ defineSuite(['DynamicScene/TimeIntervalCollectionPositionProperty', var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); var property = new TimeIntervalCollectionPositionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.removeInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); property.intervals.addInterval(interval); - property.definitionChanged.raiseEvent.reset(); + listener.reset(); property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); }); \ No newline at end of file diff --git a/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js b/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js index 51f677b43d05..40a8dd7c0654 100644 --- a/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js +++ b/Specs/DynamicScene/TimeIntervalCollectionPropertySpec.js @@ -111,18 +111,19 @@ defineSuite(['DynamicScene/TimeIntervalCollectionProperty', var interval = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new Cartesian3(1, 2, 3)); var property = new TimeIntervalCollectionProperty(); - spyOn(property.definitionChanged, 'raiseEvent'); + var listener = jasmine.createSpy('listener'); + property.definitionChanged.addEventListener(listener); property.intervals.addInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); - property.definitionChanged.raiseEvent.reset(); + expect(listener).toHaveBeenCalledWith(property); + listener.reset(); property.intervals.removeInterval(interval); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); property.intervals.addInterval(interval); - property.definitionChanged.raiseEvent.reset(); + listener.reset(); property.intervals.clear(); - expect(property.definitionChanged.raiseEvent).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property); }); }); \ No newline at end of file From 46c9ecc6d4b04ec6d90ef27b8ced61e198d3d605 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 17 Feb 2014 22:40:22 -0500 Subject: [PATCH 53/81] More doc updates --- Source/DynamicScene/GeometryVisualizer.js | 41 +++++++------------ .../DynamicScene/StaticGeometryColorBatch.js | 3 ++ .../StaticGeometryPerMaterialBatch.js | 3 ++ .../StaticOutlineGeometryBatch.js | 3 ++ 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 93c351a4e048..600e0dd1e198 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -64,26 +64,13 @@ define(['../Core/defined', }; /** - * A DynamicObject visualizer which maps the DynamicPolygon instance - * in DynamicObject.polygon to a Polygon primitive. + * A general purpose visualizer for all graphics which can be represented by {@link Primitive} instances. * @alias GeometryVisualizer * @constructor * + * @param {GeometryUpdater} type The updater to be used for creating the geometry. * @param {Scene} scene The scene the primitives will be rendered in. * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. - * - * @see DynamicPolygon - * @see Scene - * @see DynamicObject - * @see DynamicObjectCollection - * @see CompositeDynamicObjectCollection - * @see VisualizerCollection - * @see DynamicBillboardVisualizer - * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr - * @see DynamicLabelVisualizer - * @see DynamicPointVisualizer - * @see DynamicPyramidVisualizer */ var GeometryVisualizer = function(type, scene, dynamicObjectCollection) { if (!defined(type)) { @@ -118,6 +105,7 @@ define(['../Core/defined', /** * Returns the scene being used by this visualizer. + * @memberof GeometryVisualizer * * @returns {Scene} The scene being used by this visualizer. */ @@ -127,6 +115,7 @@ define(['../Core/defined', /** * Gets the DynamicObjectCollection being visualized. + * @memberof GeometryVisualizer * * @returns {DynamicObjectCollection} The DynamicObjectCollection being visualized. */ @@ -136,8 +125,9 @@ define(['../Core/defined', /** * Sets the DynamicObjectCollection to visualize. + * @memberof GeometryVisualizer * - * @param dynamicObjectCollection The DynamicObjectCollection to visualizer. + * @param {DynamicObjectCollection} dynamicObjectCollection The DynamicObjectCollection to visualizer. */ GeometryVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { var oldCollection = this._dynamicObjectCollection; @@ -195,6 +185,7 @@ define(['../Core/defined', /** * Updates all of the primitives created by this visualizer to match their * DynamicObject counterpart at the given time. + * @memberof GeometryVisualizer * * @param {JulianDate} time The time to update to. */ @@ -259,6 +250,7 @@ define(['../Core/defined', /** * Removes all primitives from the scene. + * @memberof GeometryVisualizer */ GeometryVisualizer.prototype.removeAllPrimitives = function() { this._addedObjects.removeAll(); @@ -284,12 +276,9 @@ define(['../Core/defined', *

* If this object was destroyed, it should not be used; calling any function other than * isDestroyed will result in a {@link DeveloperError} exception. - * * @memberof GeometryVisualizer * * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see GeometryVisualizer#destroy */ GeometryVisualizer.prototype.isDestroyed = function() { return false; @@ -302,23 +291,18 @@ define(['../Core/defined', * Once an object is destroyed, it should not be used; calling any function other than * isDestroyed will result in a {@link DeveloperError} exception. Therefore, * assign the return value (undefined) to the object as done in the example. - * * @memberof GeometryVisualizer * - * @returns {undefined} - * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see GeometryVisualizer#isDestroyed - * - * @example - * visualizer = visualizer && visualizer.destroy(); */ GeometryVisualizer.prototype.destroy = function() { this.removeAllPrimitives(); return destroyObject(this); }; + /** + * @private + */ GeometryVisualizer._onGeometyChanged = function(updater) { var removedObjects = this._removedObjects; var changedObjects = this._changedObjects; @@ -331,6 +315,9 @@ define(['../Core/defined', } }; + /** + * @private + */ GeometryVisualizer.prototype._onCollectionChanged = function(dynamicObjectCollection, added, removed) { var addedObjects = this._addedObjects; var removedObjects = this._removedObjects; diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 6d657bf08716..48c3b76c763d 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -114,6 +114,9 @@ define(['../Core/Color', } }; + /** + * @private + */ var StaticGeometryColorBatch = function(primitives, appearanceType, closed) { this._solidBatch = new Batch(primitives, false, appearanceType, closed); this._translucentBatch = new Batch(primitives, true, appearanceType, closed); diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 7458a23041d0..93868dbe9403 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -121,6 +121,9 @@ define(['../Core/defined', this.removeMaterialSubscription(); }; + /** + * @private + */ var StaticGeometryPerMaterialBatch = function(primitives, appearanceType) { this._items = []; this._primitives = primitives; diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index e548355e175c..9d227257bb0f 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -108,6 +108,9 @@ define(['../Core/Color', } }; + /** + * @private + */ var StaticOutlineGeometryBatch = function(primitives, appearanceType) { this._solidBatch = new Batch(primitives, false, appearanceType); this._translucentBatch = new Batch(primitives, true, appearanceType); From c2ad052b28d9d6ac705b7dab0dbba4b6f118d6ad Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 10:15:24 -0500 Subject: [PATCH 54/81] Ongoing cleanup 1. Don't default `ColorMaterialProperty` to an arbitrary value. 2. Improve `ColorMaterialProperty` constructor. 3. Clean up `viewerDynamicObjectMixin` after integrate from master. 4. Tweak GeoJsonDataSource default polygon fill 5. Clean up some doc. --- Source/DynamicScene/ConstantPositionProperty.js | 1 - Source/DynamicScene/ConstantProperty.js | 8 ++++---- Source/DynamicScene/CzmlDataSource.js | 2 +- Source/DynamicScene/EllipseGeometryUpdater.js | 2 +- Source/DynamicScene/EllipsoidGeometryUpdater.js | 2 +- Source/DynamicScene/GeoJsonDataSource.js | 2 +- Source/DynamicScene/PolygonGeometryUpdater.js | 2 +- Source/DynamicScene/PolylineGeometryUpdater.js | 2 +- .../Widgets/Viewer/viewerDynamicObjectMixin.js | 15 ++++++++++++--- Specs/DynamicScene/ColorMaterialPropertySpec.js | 16 ++++++++++------ .../CompositeMaterialPropertySpec.js | 8 ++++---- Specs/DynamicScene/EllipseGeometryUpdaterSpec.js | 4 ++-- .../DynamicScene/EllipsoidGeometryUpdaterSpec.js | 4 ++-- 13 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Source/DynamicScene/ConstantPositionProperty.js b/Source/DynamicScene/ConstantPositionProperty.js index 0ecbee155e9b..80a7432f7da3 100644 --- a/Source/DynamicScene/ConstantPositionProperty.js +++ b/Source/DynamicScene/ConstantPositionProperty.js @@ -87,7 +87,6 @@ define(['./PositionProperty', /** * Sets the value of the property. - * If the value is an object, the object must provide clone and equals functions. * @memberof ConstantPositionProperty * * @param {Cartesian3} value The property value. diff --git a/Source/DynamicScene/ConstantProperty.js b/Source/DynamicScene/ConstantProperty.js index 87152edf801e..ce02ebfea1a3 100644 --- a/Source/DynamicScene/ConstantProperty.js +++ b/Source/DynamicScene/ConstantProperty.js @@ -16,12 +16,12 @@ define(['../Core/defaultValue', /** * A {@link Property} whose value does not change with respect to simulation time. - * If the value is an object, the object must provide clone and equals functions. + * If the value is a non-basic type, then it must provide clone and equals functions. * * @alias ConstantProperty * @constructor * - * @param {Object|Number|String|Boolean} [value] The property value. + * @param {Object} [value] The property value. * * @see ConstantPositionProperty * @@ -75,10 +75,10 @@ define(['../Core/defaultValue', /** * Sets the value of the property. - * If the value is an object, the object must provide clone and equals functions. + * If the value is a non-basic type, then it must provide clone and equals functions. * @memberof ConstantProperty * - * @param {Object|Number|String|Boolean} value The property value. + * @param {Object} value The property value. * * @exception {DeveloperError} value.clone is a required function. * @exception {DeveloperError} value.equals is a required function. diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index e2f44369d538..35b2614b99a8 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -768,7 +768,7 @@ define(['../Core/Cartesian2', } if (defined(existingInterval)) { - existingInterval.data = existingMaterial; + existingInterval.data = existingMaterial; } else { object[propertyName] = existingMaterial; } diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 67166c42fcd0..c7458896105b 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -40,7 +40,7 @@ define(['../Core/Color', Primitive) { "use strict"; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); var defaultOutline = new ConstantProperty(false); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index d077a0530ba5..0bff875de088 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -44,7 +44,7 @@ define(['../Core/Color', Primitive) { "use strict"; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); var defaultOutline = new ConstantProperty(false); diff --git a/Source/DynamicScene/GeoJsonDataSource.js b/Source/DynamicScene/GeoJsonDataSource.js index 1150c0bbc512..94948b718ebb 100644 --- a/Source/DynamicScene/GeoJsonDataSource.js +++ b/Source/DynamicScene/GeoJsonDataSource.js @@ -302,7 +302,7 @@ define([ defaultPolygon.polygon = polygon; material = new ColorMaterialProperty(); - material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.1)); + material.color = new ConstantProperty(new Color(1.0, 1.0, 0.0, 0.2)); polygon.material = material; this._changed = new Event(); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index df8c89e2e61b..fe19f757ec6e 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -40,7 +40,7 @@ define(['../Core/Color', Primitive) { "use strict"; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); var defaultOutline = new ConstantProperty(false); diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 2b2e9ed01099..579eb0fc6d42 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -38,7 +38,7 @@ define(['../Core/Color', Primitive) { "use strict"; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); var defaultShow = new ConstantProperty(true); var defaultFill = new ConstantProperty(true); diff --git a/Source/Widgets/Viewer/viewerDynamicObjectMixin.js b/Source/Widgets/Viewer/viewerDynamicObjectMixin.js index 8c176af1ca71..19fe1da6dbd2 100644 --- a/Source/Widgets/Viewer/viewerDynamicObjectMixin.js +++ b/Source/Widgets/Viewer/viewerDynamicObjectMixin.js @@ -6,9 +6,9 @@ define(['../../Core/BoundingSphere', '../../Core/EventHelper', '../../Core/ScreenSpaceEventType', '../../Core/wrapFunction', + '../../DynamicScene/DynamicObject', '../../Scene/SceneMode', '../subscribeAndEvaluate', - '../../DynamicScene/DynamicObject', '../../DynamicScene/DynamicObjectView', '../../ThirdParty/knockout' ], function( @@ -19,9 +19,9 @@ define(['../../Core/BoundingSphere', EventHelper, ScreenSpaceEventType, wrapFunction, + DynamicObject, SceneMode, subscribeAndEvaluate, - DynamicObject, DynamicObjectView, knockout) { "use strict"; @@ -162,8 +162,17 @@ define(['../../Core/BoundingSphere', } } + function trackObject(dynamicObject) { + if (defined(dynamicObject) && defined(dynamicObject.position)) { + viewer.trackedObject = dynamicObject; + } + } + function pickAndTrackObject(e) { - viewer.trackedObject = defaultValue(pickDynamicObject(e), viewer.trackedObject); + var dynamicObject = pickDynamicObject(e); + if (defined(dynamicObject)) { + trackObject(dynamicObject); + } } function pickAndSelectObject(e) { diff --git a/Specs/DynamicScene/ColorMaterialPropertySpec.js b/Specs/DynamicScene/ColorMaterialPropertySpec.js index cacaa74c1db9..058353ea13e2 100644 --- a/Specs/DynamicScene/ColorMaterialPropertySpec.js +++ b/Specs/DynamicScene/ColorMaterialPropertySpec.js @@ -17,14 +17,18 @@ defineSuite(['DynamicScene/ColorMaterialProperty', it('constructor provides the expected defaults', function() { var property = new ColorMaterialProperty(); - expect(property.color).toBeDefined(); + expect(property.color).toBeUndefined(); expect(property.getType()).toEqual('Color'); expect(property.isConstant).toBe(true); - expect(property.getValue().color).toEqual(Color.WHITE); - property = new ColorMaterialProperty(Color.BLACK); - expect(property.color).toBeDefined(); - expect(property.getValue().color).toEqual(Color.BLACK); + var colorProperty = new ConstantProperty(Color.BLUE); + property = new ColorMaterialProperty(colorProperty); + expect(property.color).toBe(colorProperty); + expect(property.getType()).toEqual('Color'); + expect(property.isConstant).toBe(true); + + property = ColorMaterialProperty.fromColor(Color.BLUE); + expect(property.color).toEqual(colorProperty); }); it('works with constant values', function() { @@ -37,7 +41,7 @@ defineSuite(['DynamicScene/ColorMaterialProperty', it('works with undefined values', function() { var property = new ColorMaterialProperty(); - property.color.setValue(undefined); + property.color = new ConstantProperty(); var result = property.getValue(); expect(result.hasOwnProperty('color')).toEqual(true); diff --git a/Specs/DynamicScene/CompositeMaterialPropertySpec.js b/Specs/DynamicScene/CompositeMaterialPropertySpec.js index 22e4c4ad3557..ba77e739be17 100644 --- a/Specs/DynamicScene/CompositeMaterialPropertySpec.js +++ b/Specs/DynamicScene/CompositeMaterialPropertySpec.js @@ -82,8 +82,8 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', }); it('raises definitionChanged event in all cases', function() { - var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + var interval1 = new TimeInterval(new JulianDate(10, 0), new JulianDate(12, 0), true, true, ColorMaterialProperty.fromColor(Color.RED)); + var interval2 = new TimeInterval(new JulianDate(12, 0), new JulianDate(14, 0), false, true, ColorMaterialProperty.fromColor(Color.YELLOW)); var property = new CompositeMaterialProperty(); var listener = jasmine.createSpy('listener'); @@ -111,8 +111,8 @@ defineSuite(['DynamicScene/CompositeMaterialProperty', }); it('does not raise definitionChanged for an overwritten interval', function() { - var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, new ColorMaterialProperty()); - var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, new ColorMaterialProperty()); + var interval1 = new TimeInterval(new JulianDate(11, 0), new JulianDate(13, 0), true, true, ColorMaterialProperty.fromColor(Color.RED)); + var interval2 = new TimeInterval(new JulianDate(10, 0), new JulianDate(14, 0), false, true, ColorMaterialProperty.fromColor(Color.YELLOW)); var property = new CompositeMaterialProperty(); var listener = jasmine.createSpy('listener'); diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index ea90512c6f01..819e7490a62f 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -119,7 +119,7 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', expect(updater.isClosed).toBe(false); expect(updater.fillEnabled).toBe(true); - expect(updater.fillMaterialProperty).toEqual(new ColorMaterialProperty(Color.WHITE)); + expect(updater.fillMaterialProperty).toEqual(ColorMaterialProperty.fromColor(Color.WHITE)); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); @@ -292,7 +292,7 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', semiMajorAxis : 3, semiMinorAxis : 2, show : true, - material : new ColorMaterialProperty(Color.RED), + material : ColorMaterialProperty.fromColor(Color.RED), height : 123, extrudedHeight : 431, granularity : 0.97, diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index 0887c88b7062..bd3f49639670 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -110,7 +110,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', var updater = new EllipsoidGeometryUpdater(dynamicObject); expect(updater.fillEnabled).toBe(true); - expect(updater.fillMaterialProperty).toEqual(new ColorMaterialProperty(Color.WHITE)); + expect(updater.fillMaterialProperty).toEqual(ColorMaterialProperty.fromColor(Color.WHITE)); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); @@ -233,7 +233,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', orientation : Quaternion.IDENTITY, radii : new Cartesian3(1, 2, 3), show : true, - material : new ColorMaterialProperty(Color.RED), + material : ColorMaterialProperty.fromColor(Color.RED), fill : true, outline : true, outlineColor : Color.BLUE, From a32e6905e5435fe7b7950592f0ac3ff1eb806d36 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 10:25:45 -0500 Subject: [PATCH 55/81] Delete VisualizerCollection It has been superceded by DataSourceDisplay and is no longer needed. --- Source/DynamicScene/ColorMaterialProperty.js | 24 ++- Source/DynamicScene/DataSourceDisplay.js | 103 +++++------- .../DynamicBillboardVisualizer.js | 1 - .../DynamicConeVisualizerUsingCustomSensor.js | 1 - Source/DynamicScene/DynamicLabelVisualizer.js | 1 - Source/DynamicScene/DynamicPathVisualizer.js | 1 - Source/DynamicScene/DynamicPointVisualizer.js | 1 - .../DynamicScene/DynamicPyramidVisualizer.js | 1 - .../DynamicScene/DynamicVectorVisualizer.js | 1 - Source/DynamicScene/VisualizerCollection.js | 157 ------------------ Specs/DynamicScene/DataSourceDisplaySpec.js | 19 +-- .../DynamicScene/VisualizerCollectionSpec.js | 139 ---------------- 12 files changed, 74 insertions(+), 375 deletions(-) delete mode 100644 Source/DynamicScene/VisualizerCollection.js delete mode 100644 Specs/DynamicScene/VisualizerCollectionSpec.js diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 27f3ace9c748..e2d285886686 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -3,6 +3,7 @@ define(['../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/DeveloperError', '../Core/Event', './ConstantProperty', './Property' @@ -11,6 +12,7 @@ define(['../Core/Color', defaultValue, defined, defineProperties, + DeveloperError, Event, ConstantProperty, Property) { @@ -19,16 +21,31 @@ define(['../Core/Color', /** * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. * - * @param {Color} [color=Color.WHITE] The material color. + * @param {Property} [color] The {@link Color} property to be used. * * @alias ColorMaterialProperty * @constructor */ - var ColorMaterialProperty = function(color) { + var ColorMaterialProperty = function(colorProperty) { this._definitionChanged = new Event(); this._color = undefined; this._colorSubscription = undefined; - this.color = new ConstantProperty(defaultValue(color, Color.WHITE)); + this.color = colorProperty; + }; + + /** + * Creates a new instance that represents a constant color. + * + * @param {Color} color The color. + * @returns {ColorMaterialProperty} A new instance configured to represent the provided color. + */ + ColorMaterialProperty.fromColor = function(color) { + //>>includeStart('debug', pragmas.debug); + if (!defined(color)) { + throw new DeveloperError('color is required'); + } + //>>includeEnd('debug'); + return new ColorMaterialProperty(new ConstantProperty(color)); }; defineProperties(ColorMaterialProperty.prototype, { @@ -59,7 +76,6 @@ define(['../Core/Color', * A {@link Color} {@link Property} which determines the material's color. * @memberof ColorMaterialProperty.prototype * @type {Property} - * @default new ConstantProperty(Color.WHITE) */ color : { get : function() { diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 6e2a0e8a4aca..29c870d3ad78 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -16,8 +16,7 @@ define([ './PolylineGeometryUpdater', './DynamicPyramidVisualizer', './DynamicVectorVisualizer', - './GeometryVisualizer', - './VisualizerCollection' + './GeometryVisualizer' ], function( defaultValue, defined, @@ -35,33 +34,23 @@ define([ PolylineGeometryUpdater, DynamicPyramidVisualizer, DynamicVectorVisualizer, - GeometryVisualizer, - VisualizerCollection) { + GeometryVisualizer) { "use strict"; - var defaultVisualizerTypes = [function(scene) { - return new DynamicBillboardVisualizer(scene); - }, function(scene) { - return new GeometryVisualizer(EllipseGeometryUpdater, scene); - }, function(scene) { - return new GeometryVisualizer(EllipsoidGeometryUpdater, scene); - }, function(scene) { - return new GeometryVisualizer(PolygonGeometryUpdater, scene); - }, function(scene) { - return new GeometryVisualizer(PolylineGeometryUpdater, scene); - }, function(scene) { - return new DynamicConeVisualizerUsingCustomSensor(scene); - }, function(scene) { - return new DynamicLabelVisualizer(scene); - }, function(scene) { - return new DynamicPointVisualizer(scene); - }, function(scene) { - return new DynamicVectorVisualizer(scene); - }, function(scene) { - return new DynamicPyramidVisualizer(scene); - }, function(scene) { - return new DynamicPathVisualizer(scene); - }]; + var createDefaultVisualizers = function(scene, dataSource) { + var dynamicObjects = dataSource.getDynamicObjectCollection(); + return [new DynamicBillboardVisualizer(scene, dynamicObjects), + new GeometryVisualizer(EllipseGeometryUpdater, scene, dynamicObjects), + new GeometryVisualizer(EllipsoidGeometryUpdater, scene, dynamicObjects), + new GeometryVisualizer(PolygonGeometryUpdater, scene, dynamicObjects), + new GeometryVisualizer(PolylineGeometryUpdater, scene, dynamicObjects), + new DynamicConeVisualizerUsingCustomSensor(scene, dynamicObjects), + new DynamicLabelVisualizer(scene, dynamicObjects), + new DynamicPointVisualizer(scene, dynamicObjects), + new DynamicVectorVisualizer(scene, dynamicObjects), + new DynamicPyramidVisualizer(scene, dynamicObjects), + new DynamicPathVisualizer(scene, dynamicObjects)]; + }; /** * Visualizes a collection of {@link DataSource} instances. @@ -70,9 +59,9 @@ define([ * * @param {Scene} scene The scene in which to display the data. * @param {DataSourceCollection} dataSourceCollection The data sources to display. - * @param {Array} [visualizerTypes] The array of visualizer constructor functions that will be created for each data source. If undefined, All standard visualizers will be used. + * @param {Array} [visualizersCallback] A function which takes a scene and returns the array of visualizers to be used for the display. */ - var DataSourceDisplay = function(scene, dataSourceCollection, visualizerTypes) { + var DataSourceDisplay = function(scene, dataSourceCollection, visualizersCallback) { //>>includeStart('debug', pragmas.debug); if (!defined(scene)) { throw new DeveloperError('scene is required.'); @@ -90,9 +79,9 @@ define([ this._scene = scene; this._timeVaryingSources = []; this._staticSourcesToUpdate = []; - this._visualizersTypes = defaultValue(visualizerTypes, defaultVisualizerTypes).slice(0); + this._visualizersCallback = defaultValue(visualizersCallback, createDefaultVisualizers); - for ( var i = 0, len = dataSourceCollection.getLength(); i < len; i++) { + for (var i = 0, len = dataSourceCollection.getLength(); i < len; i++) { this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i)); } }; @@ -105,14 +94,6 @@ define([ return this._scene; }; - /** - * Gets the types of visualizers being used for display. - * @returns {Array} A copy of the visualizer types being used for display. - */ - DataSourceDisplay.prototype.getVisualizerTypes = function() { - return this._visualizersTypes.slice(0); - }; - /** * Gets the collection of data sources to be displayed. * @returns {DataSourceCollection} The collection of data sources. @@ -156,7 +137,7 @@ define([ this._eventHelper.removeAll(); var dataSourceCollection = this._dataSourceCollection; - for ( var i = 0, length = dataSourceCollection.getLength(); i < length; ++i) { + for (var i = 0, length = dataSourceCollection.getLength(); i < length; ++i) { this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i)); } @@ -177,34 +158,36 @@ define([ } //>>includeEnd('debug'); - var timeVaryingSources = this._timeVaryingSources; var i; + var x; + var visualizers; + var vLength; + + var timeVaryingSources = this._timeVaryingSources; var length = timeVaryingSources.length; for (i = 0; i < length; i++) { - timeVaryingSources[i]._visualizerCollection.update(time); + visualizers = timeVaryingSources[i]._visualizers; + vLength = visualizers.length; + for (x = 0; x < vLength; x++) { + visualizers[x].update(time); + } } var staticSourcesToUpdate = this._staticSourcesToUpdate; length = staticSourcesToUpdate.length; - if (length > 0) { - for (i = 0; i < length; i++) { - staticSourcesToUpdate[i]._visualizerCollection.update(time); + for (i = 0; i < length; i++) { + visualizers = staticSourcesToUpdate[i]._visualizers; + vLength = visualizers.length; + for (x = 0; x < vLength; x++) { + visualizers[x].update(time); } - staticSourcesToUpdate.length = 0; } + staticSourcesToUpdate.length = 0; }; DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) { - var visualizerTypes = this._visualizersTypes; - var length = visualizerTypes.length; - var visualizers = new Array(length); - var scene = this._scene; - for ( var i = 0; i < length; i++) { - visualizers[i] = visualizerTypes[i](scene); - } - - var vCollection = new VisualizerCollection(visualizers, dataSource.getDynamicObjectCollection()); - dataSource._visualizerCollection = vCollection; + var visualizers = this._visualizersCallback(this._scene, dataSource); + dataSource._visualizers = visualizers; dataSource.getChangedEvent().addEventListener(this._onDataSourceChanged, this); this._onDataSourceChanged(dataSource); }; @@ -222,8 +205,12 @@ define([ this._staticSourcesToUpdate.splice(staticIndex, 1); } - dataSource._visualizerCollection.destroy(); - dataSource._visualizerCollection = undefined; + var visualizers = dataSource._visualizers; + var length = visualizers.length; + for (var i = 0; i < length; i++) { + visualizers[i].destroy(); + dataSource._visualizers = undefined; + } }; DataSourceDisplay.prototype._onDataSourceChanged = function(dataSource) { diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index 32eabc11c171..69ddfe4bc653 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -54,7 +54,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index 9d2b8112e9bc..ceb2bea50a74 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -90,7 +90,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicLabelVisualizer diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index baacbfa3734b..76ff5883bf7c 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -37,7 +37,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 46e46e031ef5..d1755c620df9 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -392,7 +392,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index dcb4e6bc6684..75309d8b563b 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -31,7 +31,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index cbaa6eadb9f7..f8a857c286fc 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -43,7 +43,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index 195470722e95..1d5ca9d2baac 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -31,7 +31,6 @@ define([ * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection - * @see VisualizerCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer * @see DynamicConeVisualizerUsingCustomSensorr diff --git a/Source/DynamicScene/VisualizerCollection.js b/Source/DynamicScene/VisualizerCollection.js deleted file mode 100644 index 39f9492cf751..000000000000 --- a/Source/DynamicScene/VisualizerCollection.js +++ /dev/null @@ -1,157 +0,0 @@ -/*global define*/ -define([ - '../Core/defaultValue', - '../Core/defined', - '../Core/destroyObject' - ], function( - defaultValue, - defined, - destroyObject) { - "use strict"; - - /** - * A collection of visualizers which makes it easy to manage and - * update them in unison. - * @alias VisualizerCollection - * @constructor - * - * @param {Object} The array of visualizers to use. - * @param {DynamicObjectCollection} The objects to be visualized. - */ - var VisualizerCollection = function(visualizers, dynamicObjectCollection) { - this._visualizers = defined(visualizers) ? visualizers : []; - this._dynamicObjectCollection = undefined; - this.setDynamicObjectCollection(dynamicObjectCollection); - }; - - /** - * Gets a copy of the array of visualizers in the collection. - * @returns {Array} the array of visualizers in the collection. - */ - VisualizerCollection.prototype.getVisualizers = function() { - return this._visualizers.slice(0); - }; - - /** - * Sets the array of visualizers in the collection. - * - * @param {Array} visualizers The new array of visualizers. This array can partially overlap with visualizers currently in the collection. - * @param {Boolean} destroyOldVisualizers If true, visualizers no longer in the collection will be destroyed. - */ - VisualizerCollection.prototype.setVisualizers = function(visualizers, destroyOldVisualizers) { - destroyOldVisualizers = defaultValue(destroyOldVisualizers, true); - - var i; - var thisVisualizers = this._visualizers; - if (destroyOldVisualizers) { - for (i = thisVisualizers.length - 1; i > -1; i--) { - var visualizer = thisVisualizers[i]; - if (visualizers.indexOf(visualizer) === -1) { - visualizer.destroy(); - } - } - } - - if (!defined(visualizers)) { - visualizers = []; - } - this._visualizers = visualizers; - var dynamicObjectCollection = this._dynamicObjectCollection; - for (i = visualizers.length - 1; i > -1; i--) { - visualizers[i].setDynamicObjectCollection(dynamicObjectCollection); - } - }; - - /** - * Gets the DynamicObjectCollection being visualized. - * @returns the DynamicObjectCollection being visualized - */ - VisualizerCollection.prototype.getDynamicObjectCollection = function() { - return this._dynamicObjectCollection; - }; - - /** - * Sets the DynamicObjectCollection being visualized. - * @param {DynamicObjectCollection} dynamicObjectCollection the DynamicObjectCollection being visualized. - */ - VisualizerCollection.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { - var oldCollection = this._dynamicObjectCollection; - if (oldCollection !== dynamicObjectCollection) { - this._dynamicObjectCollection = dynamicObjectCollection; - var visualizers = this._visualizers; - for ( var i = visualizers.length - 1; i > -1; i--) { - visualizers[i].setDynamicObjectCollection(dynamicObjectCollection); - } - } - }; - - /** - * Updates all visualizers to the provided time. - * @param {JulianDate} time The time to updated to. - */ - VisualizerCollection.prototype.update = function(time) { - var visualizers = this._visualizers; - for ( var i = visualizers.length - 1; i > -1; i--) { - visualizers[i].update(time); - } - }; - - /** - * Removes all primitives from visualization. - */ - VisualizerCollection.prototype.removeAllPrimitives = function() { - var visualizers = this._visualizers; - for ( var i = visualizers.length - 1; i > -1; i--) { - visualizers[i].removeAllPrimitives(); - } - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - *

- * If this object was destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. - * - * @memberof VisualizerCollection - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see VisualizerCollection#destroy - */ - VisualizerCollection.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - *

- * Once an object is destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (undefined) to the object as done in the example. - * - * @memberof VisualizerCollection - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see VisualizerCollection#isDestroyed - * - * @example - * visualizerCollection = visualizerCollection && visualizerCollection.destroy(); - */ - VisualizerCollection.prototype.destroy = function(destroyVisualizers) { - destroyVisualizers = defaultValue(destroyVisualizers, true); - this.removeAllPrimitives(); - if (destroyVisualizers) { - var visualizers = this._visualizers; - for ( var i = visualizers.length - 1; i > -1; i--) { - visualizers[i].destroy(); - } - } - return destroyObject(this); - }; - - return VisualizerCollection; -}); \ No newline at end of file diff --git a/Specs/DynamicScene/DataSourceDisplaySpec.js b/Specs/DynamicScene/DataSourceDisplaySpec.js index 3aa28ea3a565..03099612d6e4 100644 --- a/Specs/DynamicScene/DataSourceDisplaySpec.js +++ b/Specs/DynamicScene/DataSourceDisplaySpec.js @@ -65,14 +65,13 @@ defineSuite([ this.destroyed = true; }; - var visualizerTypes = [function() { - return new MockVisualizer(); - }]; + var visualizerCallback = function() { + return [new MockVisualizer()]; + }; it('constructor sets expected values', function() { - var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerCallback); expect(display.getScene()).toBe(scene); - expect(display.getVisualizerTypes()).toEqual(visualizerTypes); expect(display.getDataSources()).toBe(dataSourceCollection); expect(display.isDestroyed()).toEqual(false); display.destroy(); @@ -97,14 +96,14 @@ defineSuite([ var dynamicSource = new MockDataSource(); dynamicSource.isTimeVarying = true; - var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerCallback); dataSourceCollection.add(staticSource); dataSourceCollection.add(dynamicSource); - var staticSourceVisualizer = staticSource._visualizerCollection.getVisualizers()[0]; + var staticSourceVisualizer = staticSource._visualizers[0]; expect(staticSourceVisualizer).toBeInstanceOf(MockVisualizer); - var dynamicSourceVisualizer = dynamicSource._visualizerCollection.getVisualizers()[0]; + var dynamicSourceVisualizer = dynamicSource._visualizers[0]; expect(dynamicSourceVisualizer).toBeInstanceOf(MockVisualizer); //Nothing should have happened yet because we haven't called update. @@ -142,9 +141,9 @@ defineSuite([ var source = new MockDataSource(); dataSourceCollection.add(source); - var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerCallback); - var sourceVisualizer = source._visualizerCollection.getVisualizers()[0]; + var sourceVisualizer = source._visualizers[0]; expect(sourceVisualizer).toBeInstanceOf(MockVisualizer); //Nothing should have happened yet because we haven't called update. diff --git a/Specs/DynamicScene/VisualizerCollectionSpec.js b/Specs/DynamicScene/VisualizerCollectionSpec.js deleted file mode 100644 index 63ea3fb3ef42..000000000000 --- a/Specs/DynamicScene/VisualizerCollectionSpec.js +++ /dev/null @@ -1,139 +0,0 @@ -/*global defineSuite*/ -defineSuite([ - 'DynamicScene/VisualizerCollection', - 'Core/JulianDate' - ], function( - VisualizerCollection, - JulianDate) { - "use strict"; - /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ - - function MockVisualizer() { - this.updateTime = undefined; - this.isDestroyed = false; - this.removeAllPrimitivesCalled = false; - } - - MockVisualizer.prototype.setDynamicObjectCollection = function(dynamicObjectCollection) { - this.mockCollection = dynamicObjectCollection; - }; - - MockVisualizer.prototype.update = function(time) { - this.updateTime = time; - }; - - MockVisualizer.prototype.removeAllPrimitives = function() { - this.removeAllPrimitivesCalled = true; - }; - - MockVisualizer.prototype.destroy = function() { - this.isDestroyed = true; - }; - - function MockDynamicObjectCollection() { - } - - it('Default constructor creates expected default properties', function() { - var visualizers = new VisualizerCollection(); - expect(visualizers.getVisualizers().length).toEqual(0); - expect(visualizers.getDynamicObjectCollection()).toBeUndefined(); - expect(visualizers.isDestroyed()).toEqual(false); - }); - - it('Constructor assigns expected paramters to properies', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - expect(visualizers.getVisualizers().length).toEqual(1); - expect(visualizers.getDynamicObjectCollection()).toEqual(mockCollection); - expect(mockVisualizer.mockCollection).toEqual(mockCollection); - }); - - it('Constructor assigns expected paramters to properies', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - expect(visualizers.getVisualizers().length).toEqual(1); - expect(visualizers.getDynamicObjectCollection()).toEqual(mockCollection); - expect(mockVisualizer.mockCollection).toEqual(mockCollection); - }); - - it('setVisualizers destroys old visualizers by default', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - visualizers.setVisualizers([]); - expect(mockVisualizer.isDestroyed).toEqual(true); - }); - - it('setVisualizers does not destroys old visualizers if told', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - visualizers.setVisualizers([], false); - expect(mockVisualizer.isDestroyed).toEqual(false); - }); - - it('setVisualizers does not destroys visualizers that is in new list', function() { - var mockVisualizer = new MockVisualizer(); - var mockVisualizer2 = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer, mockVisualizer2], mockCollection); - visualizers.setVisualizers([mockVisualizer]); - expect(mockVisualizer.isDestroyed).toEqual(false); - expect(mockVisualizer2.isDestroyed).toEqual(true); - }); - - it('destroy destroys old visualizers by default', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - visualizers.destroy(); - expect(visualizers.isDestroyed()).toEqual(true); - expect(mockVisualizer.isDestroyed).toEqual(true); - }); - - it('destroy does not destroy old visualizers if told', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - visualizers.destroy(false); - expect(visualizers.isDestroyed()).toEqual(true); - expect(mockVisualizer.isDestroyed).toEqual(false); - }); - - it('setDynamicObjectCollection calls setDynamicObjectCollection on underlying visualizers', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer]); - visualizers.setDynamicObjectCollection(mockCollection); - expect(mockVisualizer.mockCollection).toEqual(mockCollection); - }); - - it('update calls update on underlying visualizers', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - var updateTime = new JulianDate(); - visualizers.update(updateTime); - expect(mockVisualizer.updateTime).toEqual(updateTime); - }); - - it('removeAllPrimitives calls removeAllPrimitives on underlying visualizers', function() { - var mockVisualizer = new MockVisualizer(); - var mockCollection = new MockDynamicObjectCollection(); - - var visualizers = new VisualizerCollection([mockVisualizer], mockCollection); - visualizers.removeAllPrimitives(); - expect(mockVisualizer.removeAllPrimitivesCalled).toEqual(true); - }); -}); \ No newline at end of file From 34b04d1bda879ace162570a1c4383f72ecf8a661 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 12:03:38 -0500 Subject: [PATCH 56/81] Cleanup more documentation. --- Source/DynamicScene/DataSourceDisplay.js | 25 +++++++++---------- .../DynamicBillboardVisualizer.js | 1 - .../DynamicConeVisualizerUsingCustomSensor.js | 1 - Source/DynamicScene/DynamicPathVisualizer.js | 2 -- .../DynamicScene/DynamicPyramidVisualizer.js | 2 -- .../DynamicScene/DynamicVectorVisualizer.js | 2 -- Source/DynamicScene/GridMaterialProperty.js | 8 +++--- Source/DynamicScene/ImageMaterialProperty.js | 4 +-- Source/DynamicScene/MaterialProperty.js | 2 +- .../PolylineOutlineMaterialProperty.js | 6 ++--- Source/DynamicScene/ReferenceProperty.js | 10 ++++++++ 11 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 29c870d3ad78..375198be35a4 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -1,22 +1,21 @@ /*global define*/ -define([ - '../Core/defaultValue', +define(['../Core/defaultValue', '../Core/defined', '../Core/destroyObject', '../Core/DeveloperError', '../Core/EventHelper', './DynamicBillboardVisualizer', - './EllipseGeometryUpdater', - './EllipsoidGeometryUpdater', './DynamicConeVisualizerUsingCustomSensor', './DynamicLabelVisualizer', './DynamicPathVisualizer', './DynamicPointVisualizer', - './PolygonGeometryUpdater', - './PolylineGeometryUpdater', './DynamicPyramidVisualizer', './DynamicVectorVisualizer', - './GeometryVisualizer' + './EllipseGeometryUpdater', + './EllipsoidGeometryUpdater', + './GeometryVisualizer', + './PolygonGeometryUpdater', + './PolylineGeometryUpdater' ], function( defaultValue, defined, @@ -24,17 +23,17 @@ define([ DeveloperError, EventHelper, DynamicBillboardVisualizer, - EllipseGeometryUpdater, - EllipsoidGeometryUpdater, DynamicConeVisualizerUsingCustomSensor, DynamicLabelVisualizer, DynamicPathVisualizer, DynamicPointVisualizer, - PolygonGeometryUpdater, - PolylineGeometryUpdater, DynamicPyramidVisualizer, DynamicVectorVisualizer, - GeometryVisualizer) { + EllipseGeometryUpdater, + EllipsoidGeometryUpdater, + GeometryVisualizer, + PolygonGeometryUpdater, + PolylineGeometryUpdater) { "use strict"; var createDefaultVisualizers = function(scene, dataSource) { @@ -59,7 +58,7 @@ define([ * * @param {Scene} scene The scene in which to display the data. * @param {DataSourceCollection} dataSourceCollection The data sources to display. - * @param {Array} [visualizersCallback] A function which takes a scene and returns the array of visualizers to be used for the display. + * @param {Visaulizer[]} [visualizersCallback] A function which takes a scene and dataSource and returns the array of visualizers used for visualization. If left undefined, all standard visualizers are used. */ var DataSourceDisplay = function(scene, dataSourceCollection, visualizersCallback) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index 69ddfe4bc653..60535ce3cd45 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -50,7 +50,6 @@ define([ * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. * * @see DynamicBillboard - * @see Scene * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index ceb2bea50a74..20b4baff7bfe 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -86,7 +86,6 @@ define([ * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. * * @see DynamicCone - * @see Scene * @see DynamicObject * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index d1755c620df9..6cb165885e73 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -388,9 +388,7 @@ define([ * * @see DynamicPath * @see Polyline - * @see Scene * @see DynamicObject - * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index f8a857c286fc..a7f0dc0026f7 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -39,9 +39,7 @@ define([ * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. * * @see DynamicPyramid - * @see Scene * @see DynamicObject - * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index 1d5ca9d2baac..499f81b8e574 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -27,9 +27,7 @@ define([ * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. * * @see DynamicPolyline - * @see Scene * @see DynamicObject - * @see DynamicObjectCollection * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer diff --git a/Source/DynamicScene/GridMaterialProperty.js b/Source/DynamicScene/GridMaterialProperty.js index f136c0786b17..359d6cf5ee53 100644 --- a/Source/DynamicScene/GridMaterialProperty.js +++ b/Source/DynamicScene/GridMaterialProperty.js @@ -66,7 +66,7 @@ define(['../Core/Cartesian2', } }, /** - * A {@link Color} {@link Property} which determines the grid's color. + * Gets or sets the {@link Color} property which determines the grid's color. * @memberof GridMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.WHITE) @@ -90,7 +90,7 @@ define(['../Core/Cartesian2', } }, /** - * A numeric {@link Property} which determines the grid cells alpha value, when combined with the color alpha. + * Gets or sets the numeric property which determines the grid cells alpha value, when combined with the color alpha. * @type {Property} * @default new ConstantProperty(0.1) */ @@ -113,7 +113,7 @@ define(['../Core/Cartesian2', } }, /** - * A {@link Cartesian2} {@link Property} which determines the number of rows and columns in the grid. + * Gets or sets the {@link Cartesian2} property which determines the number of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(8, 8)) */ @@ -136,7 +136,7 @@ define(['../Core/Cartesian2', } }, /** - * A {@link Cartesian2} {@link Property} which determines the thickness of rows and columns in the grid. + * Gets or sets the {@link Cartesian2} property which determines the thickness of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(1.0, 1.0)) */ diff --git a/Source/DynamicScene/ImageMaterialProperty.js b/Source/DynamicScene/ImageMaterialProperty.js index 8b699c38e14b..12f86df17bd6 100644 --- a/Source/DynamicScene/ImageMaterialProperty.js +++ b/Source/DynamicScene/ImageMaterialProperty.js @@ -54,7 +54,7 @@ define([ } }, /** - * A string {@link Property} which is the url of the desired image. + * Gets or sets the string property which is the url of the desired image. * @memberof ImageMaterialProperty.prototype * @type {Property} */ @@ -77,7 +77,7 @@ define([ } }, /** - * A {@link Cartesian2} {@link Property} which determines the number of times the image repeats in each direction. + * Gets or sets the {@link Cartesian2} property which determines the number of times the image repeats in each direction. * @memberof ImageMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(new Cartesian2(1, 1)) diff --git a/Source/DynamicScene/MaterialProperty.js b/Source/DynamicScene/MaterialProperty.js index 99fc1173bbb7..9673052f4246 100644 --- a/Source/DynamicScene/MaterialProperty.js +++ b/Source/DynamicScene/MaterialProperty.js @@ -11,7 +11,7 @@ define(['../Core/defined', "use strict"; /** - * The interface for all {@link MaterialProperty} objects that represent {@link Material} uniforms. + * The interface for all {@link Property} objects that represent {@link Material} uniforms. * This type defines an interface and cannot be instantiated directly. * * @alias MaterialProperty diff --git a/Source/DynamicScene/PolylineOutlineMaterialProperty.js b/Source/DynamicScene/PolylineOutlineMaterialProperty.js index 67139816142a..272d875f7485 100644 --- a/Source/DynamicScene/PolylineOutlineMaterialProperty.js +++ b/Source/DynamicScene/PolylineOutlineMaterialProperty.js @@ -59,7 +59,7 @@ define(['../Core/Color', } }, /** - * A {@link Color} {@link Property} which determines the polyline's color. + * Gets or sets {@link Color} property which determines the polyline's color. * @memberof PolylineOutlineMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.WHITE) @@ -83,7 +83,7 @@ define(['../Core/Color', } }, /** - * A {@link Color} {@link Property} which determines the polyline's outline color. + * Gets or sets the {@link Color} property which determines the polyline's outline color. * @memberof PolylineOutlineMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.BLACK) @@ -107,7 +107,7 @@ define(['../Core/Color', } }, /** - * A Number {@link Property} which determines the polyline's outline width. + * Gets or sets the numberic property which determines the polyline's outline width. * @type {Property} * @default new ConstantProperty(0) */ diff --git a/Source/DynamicScene/ReferenceProperty.js b/Source/DynamicScene/ReferenceProperty.js index a93e44d0182a..09130b02304c 100644 --- a/Source/DynamicScene/ReferenceProperty.js +++ b/Source/DynamicScene/ReferenceProperty.js @@ -138,6 +138,16 @@ define([ return defined(targetProperty) && this._targetObject.isAvailable(time) ? targetProperty.getValue(time, result) : undefined; }; + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * This method is only valid if the property being referenced is a {@link PositionProperty}. + * @memberof ReferenceProperty + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ ReferenceProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { From cead80d8c2779db314d20d31830fc4f4b46d3c1f Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 13:37:14 -0500 Subject: [PATCH 57/81] Clean up material properties and specs. --- Source/DynamicScene/ColorMaterialProperty.js | 23 +----- Source/DynamicScene/GridMaterialProperty.js | 78 ++----------------- Source/DynamicScene/ImageMaterialProperty.js | 40 +--------- .../PolylineOutlineMaterialProperty.js | 59 ++------------ .../DynamicScene/ColorMaterialPropertySpec.js | 7 +- .../DynamicScene/GridMaterialPropertySpec.js | 20 +++-- .../DynamicScene/ImageMaterialPropertySpec.js | 10 ++- .../PolylineOutlineMaterialPropertySpec.js | 15 ++-- 8 files changed, 50 insertions(+), 202 deletions(-) diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index e2d285886686..2353e807abb8 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -5,6 +5,7 @@ define(['../Core/Color', '../Core/defineProperties', '../Core/DeveloperError', '../Core/Event', + './createDynamicPropertyDescriptor', './ConstantProperty', './Property' ], function( @@ -14,6 +15,7 @@ define(['../Core/Color', defineProperties, DeveloperError, Event, + createDynamicPropertyDescriptor, ConstantProperty, Property) { "use strict"; @@ -30,7 +32,7 @@ define(['../Core/Color', this._definitionChanged = new Event(); this._color = undefined; this._colorSubscription = undefined; - this.color = colorProperty; + this.color = defaultValue(colorProperty, new ConstantProperty(Color.WHITE)); }; /** @@ -77,24 +79,7 @@ define(['../Core/Color', * @memberof ColorMaterialProperty.prototype * @type {Property} */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (defined(this._colorSubscription)) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(ColorMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } + color : createDynamicPropertyDescriptor('color') }); /** diff --git a/Source/DynamicScene/GridMaterialProperty.js b/Source/DynamicScene/GridMaterialProperty.js index 359d6cf5ee53..6f1e9728675e 100644 --- a/Source/DynamicScene/GridMaterialProperty.js +++ b/Source/DynamicScene/GridMaterialProperty.js @@ -4,6 +4,7 @@ define(['../Core/Cartesian2', '../Core/defined', '../Core/defineProperties', '../Core/Event', + './createDynamicPropertyDescriptor', './ConstantProperty', './Property' ], function( @@ -12,6 +13,7 @@ define(['../Core/Cartesian2', defined, defineProperties, Event, + createDynamicPropertyDescriptor, ConstantProperty, Property) { "use strict"; @@ -71,93 +73,25 @@ define(['../Core/Cartesian2', * @type {Property} * @default new ConstantProperty(Color.WHITE) */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (defined(this._colorSubscription)) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the numeric property which determines the grid cells alpha value, when combined with the color alpha. * @type {Property} * @default new ConstantProperty(0.1) */ - cellAlpha : { - get : function() { - return this._cellAlpha; - }, - set : function(value) { - if (this._cellAlpha !== value) { - if (this._cellAlphaSubscription) { - this._cellAlphaSubscription(); - this._cellAlphaSubscription = undefined; - } - this._cellAlpha = value; - if (defined(value)) { - this._cellAlphaSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + cellAlpha : createDynamicPropertyDescriptor('cellAlpha'), /** * Gets or sets the {@link Cartesian2} property which determines the number of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(8, 8)) */ - lineCount : { - get : function() { - return this._lineCount; - }, - set : function(value) { - if (this._lineCount !== value) { - if (this._lineCountSubscription) { - this._lineCountSubscription(); - this._lineCountSubscription = undefined; - } - this._lineCount = value; - if (defined(value)) { - this._lineCountSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + lineCount : createDynamicPropertyDescriptor('lineCount'), /** * Gets or sets the {@link Cartesian2} property which determines the thickness of rows and columns in the grid. * @type {Property} * @default new ConstantProperty(new Cartesian2(1.0, 1.0)) */ - lineThickness : { - get : function() { - return this._lineThickness; - }, - set : function(value) { - if (this._lineThickness !== value) { - if (this._lineThicknessSubscription) { - this._lineThicknessSubscription(); - this._lineThicknessSubscription = undefined; - } - this._lineThickness = value; - if (defined(value)) { - this._lineThicknessSubscription = value.definitionChanged.addEventListener(GridMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } + lineThickness : createDynamicPropertyDescriptor('lineThickness') }); /** diff --git a/Source/DynamicScene/ImageMaterialProperty.js b/Source/DynamicScene/ImageMaterialProperty.js index 12f86df17bd6..f2109ab2377f 100644 --- a/Source/DynamicScene/ImageMaterialProperty.js +++ b/Source/DynamicScene/ImageMaterialProperty.js @@ -4,6 +4,7 @@ define([ '../Core/defined', '../Core/defineProperties', '../Core/Event', + './createDynamicPropertyDescriptor', './ConstantProperty', './Property' ], function( @@ -11,6 +12,7 @@ define([ defined, defineProperties, Event, + createDynamicPropertyDescriptor, ConstantProperty, Property) { "use strict"; @@ -58,48 +60,14 @@ define([ * @memberof ImageMaterialProperty.prototype * @type {Property} */ - image : { - get : function() { - return this._image; - }, - set : function(value) { - if (this._image !== value) { - if (this._imageSubscription) { - this._imageSubscription(); - this._imageSubscription = undefined; - } - this._image = value; - if (defined(value)) { - this._imageSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + image : createDynamicPropertyDescriptor('image'), /** * Gets or sets the {@link Cartesian2} property which determines the number of times the image repeats in each direction. * @memberof ImageMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(new Cartesian2(1, 1)) */ - repeat : { - get : function() { - return this._repeat; - }, - set : function(value) { - if (this._repeat !== value) { - if (this._repeatSubscription) { - this._repeatSubscription(); - this._repeatSubscription = undefined; - } - this._repeat = value; - if (defined(value)) { - this._repeatSubscription = value.definitionChanged.addEventListener(ImageMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } + repeat : createDynamicPropertyDescriptor('repeat') }); /** diff --git a/Source/DynamicScene/PolylineOutlineMaterialProperty.js b/Source/DynamicScene/PolylineOutlineMaterialProperty.js index 272d875f7485..a80225b7811d 100644 --- a/Source/DynamicScene/PolylineOutlineMaterialProperty.js +++ b/Source/DynamicScene/PolylineOutlineMaterialProperty.js @@ -3,6 +3,7 @@ define(['../Core/Color', '../Core/defined', '../Core/defineProperties', '../Core/Event', + './createDynamicPropertyDescriptor', './ConstantProperty', './Property' ], function( @@ -10,6 +11,7 @@ define(['../Core/Color', defined, defineProperties, Event, + createDynamicPropertyDescriptor, ConstantProperty, Property) { "use strict"; @@ -64,71 +66,20 @@ define(['../Core/Color', * @type {Property} * @default new ConstantProperty(Color.WHITE) */ - color : { - get : function() { - return this._color; - }, - set : function(value) { - if (this._color !== value) { - if (defined(this._colorSubscription)) { - this._colorSubscription(); - this._colorSubscription = undefined; - } - this._color = value; - if (defined(value)) { - this._colorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + color : createDynamicPropertyDescriptor('color'), /** * Gets or sets the {@link Color} property which determines the polyline's outline color. * @memberof PolylineOutlineMaterialProperty.prototype * @type {Property} * @default new ConstantProperty(Color.BLACK) */ - outlineColor : { - get : function() { - return this._outlineColor; - }, - set : function(value) { - if (this._outlineColor !== value) { - if (this._outlineColorSubscription) { - this._outlineColorSubscription(); - this._outlineColorSubscription = undefined; - } - this._outlineColor = value; - if (defined(value)) { - this._outlineColorSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, + outlineColor : createDynamicPropertyDescriptor('outlineColor'), /** * Gets or sets the numberic property which determines the polyline's outline width. * @type {Property} * @default new ConstantProperty(0) */ - outlineWidth : { - get : function() { - return this._outlineWidth; - }, - set : function(value) { - if (this._outlineWidth !== value) { - if (this._outlineWidthSubscription) { - this._outlineWidthSubscription(); - this._outlineWidthSubscription = undefined; - } - this._outlineWidth = value; - if (defined(value)) { - this._outlineWidthSubscription = value.definitionChanged.addEventListener(PolylineOutlineMaterialProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } + outlineWidth : createDynamicPropertyDescriptor('outlineWidth') }); /** diff --git a/Specs/DynamicScene/ColorMaterialPropertySpec.js b/Specs/DynamicScene/ColorMaterialPropertySpec.js index 058353ea13e2..b08f77699e3f 100644 --- a/Specs/DynamicScene/ColorMaterialPropertySpec.js +++ b/Specs/DynamicScene/ColorMaterialPropertySpec.js @@ -17,7 +17,7 @@ defineSuite(['DynamicScene/ColorMaterialProperty', it('constructor provides the expected defaults', function() { var property = new ColorMaterialProperty(); - expect(property.color).toBeUndefined(); + expect(property.color).toEqual(new ConstantProperty(Color.WHITE)); expect(property.getType()).toEqual('Color'); expect(property.isConstant).toBe(true); @@ -92,12 +92,13 @@ defineSuite(['DynamicScene/ColorMaterialProperty', var listener = jasmine.createSpy('listener'); property.definitionChanged.addEventListener(listener); + var oldValue = property.color; property.color = new ConstantProperty(Color.WHITE); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, oldValue); listener.reset(); property.color.setValue(Color.BLACK); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, property.color); listener.reset(); property.color = property.color; diff --git a/Specs/DynamicScene/GridMaterialPropertySpec.js b/Specs/DynamicScene/GridMaterialPropertySpec.js index bb55ec192b79..4411e42500f8 100644 --- a/Specs/DynamicScene/GridMaterialPropertySpec.js +++ b/Specs/DynamicScene/GridMaterialPropertySpec.js @@ -143,48 +143,52 @@ defineSuite(['DynamicScene/GridMaterialProperty', var listener = jasmine.createSpy('listener'); property.definitionChanged.addEventListener(listener); + var oldValue = property.color; property.color = new ConstantProperty(Color.WHITE); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, oldValue); listener.reset(); property.color.setValue(Color.BLACK); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, property.color); listener.reset(); property.color = property.color; expect(listener.callCount).toEqual(0); listener.reset(); + oldValue = property.cellAlpha; property.cellAlpha = new ConstantProperty(0.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'cellAlpha', property.cellAlpha, oldValue); listener.reset(); property.cellAlpha.setValue(1.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'cellAlpha', property.cellAlpha, property.cellAlpha); listener.reset(); property.cellAlpha = property.cellAlpha; expect(listener.callCount).toEqual(0); listener.reset(); + oldValue = property.lineCount; property.lineCount = new ConstantProperty(5.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'lineCount', property.lineCount, oldValue); listener.reset(); property.lineCount.setValue(10.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'lineCount', property.lineCount, property.lineCount); listener.reset(); property.lineCount = property.lineCount; expect(listener.callCount).toEqual(0); listener.reset(); + oldValue = property.lineThickness; property.lineThickness = new ConstantProperty(5.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'lineThickness', property.lineThickness, oldValue); listener.reset(); property.lineThickness.setValue(10.0); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'lineThickness', property.lineThickness, property.lineThickness); listener.reset(); property.lineThickness = property.lineThickness; diff --git a/Specs/DynamicScene/ImageMaterialPropertySpec.js b/Specs/DynamicScene/ImageMaterialPropertySpec.js index daae72415ac7..c504b4be342d 100644 --- a/Specs/DynamicScene/ImageMaterialPropertySpec.js +++ b/Specs/DynamicScene/ImageMaterialPropertySpec.js @@ -101,24 +101,26 @@ defineSuite([ var listener = jasmine.createSpy('listener'); property.definitionChanged.addEventListener(listener); + var oldValue = property.image; property.image = new ConstantProperty('http://test.invalid/image.png'); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'image', property.image, oldValue); listener.reset(); property.image.setValue('http://test.invalid/image2.png'); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'image', property.image, property.image); listener.reset(); property.image = property.image; expect(listener.callCount).toEqual(0); listener.reset(); + oldValue = property.repeat; property.repeat = new ConstantProperty(new Cartesian2(1.5, 1.5)); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'repeat', property.repeat, oldValue); listener.reset(); property.repeat.setValue(new Cartesian2(1.0, 1.0)); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'repeat', property.repeat, property.repeat); listener.reset(); property.repeat = property.repeat; diff --git a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js index 9ccb767040e9..9619bd7777f8 100644 --- a/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js +++ b/Specs/DynamicScene/PolylineOutlineMaterialPropertySpec.js @@ -106,35 +106,38 @@ defineSuite(['DynamicScene/PolylineOutlineMaterialProperty', var listener = jasmine.createSpy('listener'); property.definitionChanged.addEventListener(listener); + var oldValue = property.color; property.color = new ConstantProperty(Color.RED); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, oldValue); listener.reset(); property.color.setValue(Color.YELLOW); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'color', property.color, property.color); listener.reset(); property.color = property.color; expect(listener.callCount).toEqual(0); listener.reset(); + oldValue = property.outlineColor; property.outlineColor = new ConstantProperty(Color.BLUE); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'outlineColor', property.outlineColor, oldValue); listener.reset(); property.outlineColor.setValue(Color.GREEN); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'outlineColor', property.outlineColor, property.outlineColor); listener.reset(); property.outlineColor = property.outlineColor; expect(listener.callCount).toEqual(0); + oldValue = property.outlineWidth; property.outlineWidth = new ConstantProperty(2.5); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'outlineWidth', property.outlineWidth, oldValue); listener.reset(); property.outlineWidth.setValue(1.5); - expect(listener).toHaveBeenCalledWith(property); + expect(listener).toHaveBeenCalledWith(property, 'outlineWidth', property.outlineWidth, property.outlineWidth); listener.reset(); property.outlineWidth = property.outlineWidth; From efb2f2d0af6566b1c4264d9dbe17ce3d034cba31 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 15:56:43 -0500 Subject: [PATCH 58/81] Optimize EllipsoidGeometryUpder when dealing with dynamic radii Rather than recompute an ellipsoid primitive every frame, we simple scale the modelMatrix. --- .../DynamicScene/EllipsoidGeometryUpdater.js | 130 ++++++++++++------ 1 file changed, 91 insertions(+), 39 deletions(-) diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 0bff875de088..5cb2e5bc727e 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -1,5 +1,6 @@ /*global define*/ -define(['../Core/Color', +define(['../Core/Cartesian3', + '../Core/Color', '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', @@ -21,6 +22,7 @@ define(['../Core/Color', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive' ], function( + Cartesian3, Color, ColorGeometryInstanceAttribute, defaultValue, @@ -52,6 +54,8 @@ define(['../Core/Color', var positionScratch; var orientationScratch; + var radiiScratch; + var matrix3Scratch; var GeometryOptions = function(dynamicObject) { this.id = dynamicObject; @@ -334,11 +338,17 @@ define(['../Core/Color', * @private */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { + this._dynamicObject = geometryUpdater._dynamicObject; this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; this._geometryUpdater = geometryUpdater; this._options = new GeometryOptions(geometryUpdater._dynamicObject); + this._options.radii = new Cartesian3(1, 1, 1); + this._modelMatrix = new Matrix4(); + this._material = undefined; + this._attributes = undefined; + this._outlineAttributes = undefined; }; DynamicGeometryUpdater.prototype.update = function(time) { @@ -346,45 +356,50 @@ define(['../Core/Color', throw new DeveloperError(); } - var geometryUpdater = this._geometryUpdater; - - if (defined(this._primitive)) { - this._primitives.remove(this._primitive); - } - - if (defined(this._outlinePrimitive)) { - this._primitives.remove(this._outlinePrimitive); - } - - var dynamicObject = geometryUpdater._dynamicObject; + var dynamicObject = this._dynamicObject; var ellipsoid = dynamicObject.ellipsoid; var show = ellipsoid.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + if (defined(this._primitive)) { + this._primitive.show = false; + } + + if (defined(this._outlinePrimitive)) { + this._outlinePrimitive.show = false; + } return; } - var options = this._options; - var position = dynamicObject.position; - var orientation = dynamicObject.orientation; - var radii = ellipsoid.radii; - var stackPartitions = ellipsoid.stackPartitions; - var slicePartitions = ellipsoid.slicePartitions; - var subdivisions = ellipsoid.subdivisions; - - positionScratch = position.getValue(time, positionScratch); - orientationScratch = orientation.getValue(time, orientationScratch); - var modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch); + //Compute attributes and material. + var appearance; + var showFill = !defined(ellipsoid.fill) || ellipsoid.fill.getValue(time); + var showOutline = defined(ellipsoid.outline) && ellipsoid.outline.getValue(time); + var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; + var material = MaterialProperty.getValue(time, defaultValue(ellipsoid.material, defaultMaterial), this._material); + this._material = material; + + // Check properties that could trigger a primitive rebuild. + var stackPartitionsProperty = ellipsoid.stackPartitions; + var slicePartitionsProperty = ellipsoid.slicePartitions; + var subdivisionsProperty = ellipsoid.subdivisions; + var stackPartitions = defined(stackPartitionsProperty) ? stackPartitionsProperty.getValue(time) : undefined; + var slicePartitions = defined(slicePartitionsProperty) ? slicePartitionsProperty.getValue(time) : undefined; + var subdivisions = defined(subdivisionsProperty) ? subdivisionsProperty.getValue(time) : undefined; - options.radii = radii.getValue(time, options.radii); - options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(time, options) : undefined; - options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(time, options) : undefined; - options.subdivisions = defined(subdivisions) ? subdivisions.getValue(time) : undefined; + var options = this._options; - if (!defined(ellipsoid.fill) || ellipsoid.fill.getValue(time)) { - this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - var material = this._material; - var appearance = new MaterialAppearance({ + //We only rebuild the primitive if something other than the radii has changed + //For the radii, we use unit sphere and then deform it with a scale matrix. + var rebuildPrimitives = !defined(this._primitive) || options.stackPartitions !== stackPartitions || options.slicePartitions !== slicePartitions || options.subdivisions !== subdivisions; + if (rebuildPrimitives) { + options.stackPartitions = stackPartitions; + options.slicePartitions = slicePartitions; + options.subdivisions = subdivisions; + + this._material = material; + material = this._material; + appearance = new MaterialAppearance({ material : material, faceForward : true, translucent : material.isTranslucent(), @@ -395,25 +410,23 @@ define(['../Core/Color', this._primitive = new Primitive({ geometryInstances : new GeometryInstance({ id : dynamicObject, - geometry : new EllipsoidGeometry(options), - modelMatrix : modelMatrix + geometry : new EllipsoidGeometry(options) }), appearance : appearance, - asynchronous : false + asynchronous : false, + attributes : { + show : new ShowGeometryInstanceAttribute(showFill) + } }); this._primitives.add(this._primitive); - } - if (defined(ellipsoid.outline) && ellipsoid.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - - var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ geometryInstances : new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidOutlineGeometry(options), - modelMatrix : modelMatrix, attributes : { + show : new ShowGeometryInstanceAttribute(showOutline), color : ColorGeometryInstanceAttribute.fromColor(outlineColor) } }), @@ -424,7 +437,46 @@ define(['../Core/Color', asynchronous : false }); this._primitives.add(this._outlinePrimitive); + + } else { + //Update attributes only. + var primitive = this._primitive; + appearance = primitive.appearance; + appearance.material = material; + + var attributes = this._attributes; + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + this._attributes = attributes; + } + attributes.show = ShowGeometryInstanceAttribute.toValue(showFill, attributes.show); + + var outlinePrimitive = this._outlinePrimitive; + + var outlineAttributes = this._outlineAttributes; + if (!defined(outlineAttributes)) { + outlineAttributes = outlinePrimitive.getGeometryInstanceAttributes(dynamicObject); + this._outlineAttributes = outlineAttributes; + } + outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(showOutline, outlineAttributes.show); + outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(outlineColor, outlineAttributes.color); } + + //Finally, compute and set the model matrices + var positionProperty = dynamicObject.position; + var orientationProperty = dynamicObject.orientation; + var radiiProperty = ellipsoid.radii; + + positionScratch = positionProperty.getValue(time, positionScratch); + orientationScratch = orientationProperty.getValue(time, orientationScratch); + matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); + radiiScratch = radiiProperty.getValue(time, radiiScratch); + + var modelMatrix = this._modelMatrix; + modelMatrix = Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch, modelMatrix); + modelMatrix = Matrix4.multiplyByScale(modelMatrix, radiiScratch, modelMatrix); + this._primitive.modelMatrix = modelMatrix; + this._outlinePrimitive.modelMatrix = modelMatrix; }; DynamicGeometryUpdater.prototype.isDestroyed = function() { From 437f6c8f054eb5116e1f095bd9a771784925f74a Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 16:32:42 -0500 Subject: [PATCH 59/81] Clean up exception handling And more doc cleanup as well. --- Source/DynamicScene/EllipseGeometryUpdater.js | 20 ++++++++++++++----- .../DynamicScene/EllipsoidGeometryUpdater.js | 20 ++++++++++++++----- Source/DynamicScene/GeometryUpdater.js | 15 ++++++++++---- Source/DynamicScene/GeometryVisualizer.js | 2 +- Source/DynamicScene/PolygonGeometryUpdater.js | 20 ++++++++++++++----- .../DynamicScene/PolylineGeometryUpdater.js | 15 ++++++++++---- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index c7458896105b..07286f71e07f 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -61,9 +61,11 @@ define(['../Core/Color', }; var EllipseGeometryUpdater = function(dynamicObject) { + //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { throw new DeveloperError('dynamicObject is required'); } + //>>includeEnd('debug'); this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); @@ -155,13 +157,15 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._fillEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent a filled geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -194,13 +198,15 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._outlineEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent an outlined geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -323,6 +329,7 @@ define(['../Core/Color', }; EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } @@ -330,6 +337,7 @@ define(['../Core/Color', if (!defined(primitives)) { throw new DeveloperError('primitives is required.'); } + //>>includeEnd('debug'); return new DynamicGeometryUpdater(primitives, this); }; @@ -346,9 +354,11 @@ define(['../Core/Color', }; DynamicGeometryUpdater.prototype.update = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } + //>>includeEnd('debug'); var geometryUpdater = this._geometryUpdater; diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 5cb2e5bc727e..c66fe8c4053c 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -67,9 +67,11 @@ define(['../Core/Cartesian3', }; var EllipsoidGeometryUpdater = function(dynamicObject) { + //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { throw new DeveloperError('dynamicObject is required'); } + //>>includeEnd('debug'); this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); @@ -160,13 +162,15 @@ define(['../Core/Cartesian3', }; EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._fillEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent a filled geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -203,13 +207,15 @@ define(['../Core/Cartesian3', }; EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._outlineEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent an outlined geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -323,6 +329,7 @@ define(['../Core/Cartesian3', }; EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } @@ -330,6 +337,7 @@ define(['../Core/Cartesian3', if (!defined(primitives)) { throw new DeveloperError('primitives is required.'); } + //>>includeEnd('debug'); return new DynamicGeometryUpdater(primitives, this); }; @@ -352,9 +360,11 @@ define(['../Core/Cartesian3', }; DynamicGeometryUpdater.prototype.update = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var ellipsoid = dynamicObject.ellipsoid; diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js index b3637c84d8a6..464e9e2cd3a4 100644 --- a/Source/DynamicScene/GeometryUpdater.js +++ b/Source/DynamicScene/GeometryUpdater.js @@ -9,15 +9,14 @@ define(['../Core/defineProperties', /** * Defines the interface for a geometry updater. A GeometryUpdater maps * geometry defined as part of a {@link DynamicObject} into {@link Geometry} - * and {@link Appearance} instances. These instances are then visualized by - * {@link GeometryVisualizer}. + * instances. These instances are then visualized by {@link GeometryVisualizer}. * * This type defines an interface and cannot be instantiated directly. * * @alias GeometryUpdater * @constructor * - * @param {DynamicObject} dynamicObject The instance containing the geometry to be visualized. + * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. * * @see EllipseGeometryUpdater * @see EllipsoidGeometryUpdater @@ -30,7 +29,7 @@ define(['../Core/defineProperties', defineProperties(GeometryUpdater, { /** - * Gets the type of Appearance to use for simple color-based material geometry. + * Gets the type of Appearance to use for simple color-based geometry. * @memberof GeometryUpdater * @type {Appearance} */ @@ -117,6 +116,7 @@ define(['../Core/defineProperties', }, /** * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. * @memberof GeometryUpdater.prototype * @type {Boolean} */ @@ -137,6 +137,7 @@ define(['../Core/defineProperties', /** * Checks if the geometry is outlined at the provided time. * @memberof GeometryUpdater + * @function * * @param {JulianDate} time The time for which to retrieve visibility. * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. @@ -146,6 +147,7 @@ define(['../Core/defineProperties', /** * Checks if the geometry is filled at the provided time. * @memberof GeometryUpdater + * @function * * @param {JulianDate} time The time for which to retrieve visibility. * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. @@ -155,6 +157,7 @@ define(['../Core/defineProperties', /** * Creates the geometry instance which represents the fill of the geometry. * @memberof GeometryUpdater + * @function * * @param {JulianDate} time The time to use when retrieving initial attribute values. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. @@ -166,6 +169,7 @@ define(['../Core/defineProperties', /** * Creates the geometry instance which represents the outline of the geometry. * @memberof GeometryUpdater + * @function * * @param {JulianDate} time The time to use when retrieving initial attribute values. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. @@ -177,6 +181,7 @@ define(['../Core/defineProperties', /** * Returns true if this object was destroyed; otherwise, false. * @memberof GeometryUpdater + * @function * * @returns {Boolean} True if this object was destroyed; otherwise, false. */ @@ -185,6 +190,7 @@ define(['../Core/defineProperties', /** * Destroys and resources used by the object. Once an object is destroyed, it should not be used. * @memberof GeometryUpdater + * @function * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ @@ -193,6 +199,7 @@ define(['../Core/defineProperties', /** * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. * @memberof GeometryUpdater + * @function * * @param {CompositePrimitive} primitives The primitive collection to use. * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 600e0dd1e198..926d3a37241c 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -64,7 +64,7 @@ define(['../Core/defined', }; /** - * A general purpose visualizer for all graphics which can be represented by {@link Primitive} instances. + * A general purpose visualizer for all graphics that can be represented by {@link Primitive} instances. * @alias GeometryVisualizer * @constructor * diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index fe19f757ec6e..7aef5e73a61a 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -60,9 +60,11 @@ define(['../Core/Color', }; var PolygonGeometryUpdater = function(dynamicObject) { + //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { throw new DeveloperError('dynamicObject is required'); } + //>>includeEnd('debug'); this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); @@ -154,13 +156,15 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._fillEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent a filled geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -193,13 +197,15 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._outlineEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent an outlined geometry.'); } + //>>includeEnd('debug'); var dynamicObject = this._dynamicObject; var isAvailable = dynamicObject.isAvailable(time); @@ -313,6 +319,7 @@ define(['../Core/Color', }; PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } @@ -320,6 +327,7 @@ define(['../Core/Color', if (!defined(primitives)) { throw new DeveloperError('primitives is required.'); } + //>>includeEnd('debug'); return new DynamicGeometryUpdater(primitives, this); }; @@ -336,9 +344,11 @@ define(['../Core/Color', }; DynamicGeometryUpdater.prototype.update = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } + //>>includeEnd('debug'); var geometryUpdater = this._geometryUpdater; diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 579eb0fc6d42..7a5edd1c3fd9 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -40,7 +40,6 @@ define(['../Core/Color', var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); var GeometryOptions = function(dynamicObject) { this.id = dynamicObject; @@ -50,9 +49,11 @@ define(['../Core/Color', }; var PolylineGeometryUpdater = function(dynamicObject) { + //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { throw new DeveloperError('dynamicObject is required'); } + //>>includeEnd('debug'); this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); @@ -134,13 +135,15 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError(); + throw new DeveloperError('time is required.'); } if (!this._fillEnabled) { - throw new DeveloperError(); + throw new DeveloperError('This instance does not represent a filled geometry.'); } + //>>includeEnd('debug'); var color; var attributes; @@ -172,7 +175,9 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - throw new DeveloperError(); + //>>includeStart('debug', pragmas.debug); + throw new DeveloperError('This instance does not represent an outlined geometry.'); + //>>includeEnd('debug'); }; PolylineGeometryUpdater.prototype.isDestroyed = function() { @@ -247,6 +252,7 @@ define(['../Core/Color', }; PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { throw new DeveloperError('This instance does not represent dynamic geometry.'); } @@ -254,6 +260,7 @@ define(['../Core/Color', if (!defined(primitives)) { throw new DeveloperError('primitives is required.'); } + //>>includeEnd('debug'); return new DynamicGeometryUpdater(primitives, this); }; From 6bf3b99c5765a45c0d121519bae01172a37acb19 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 17:11:59 -0500 Subject: [PATCH 60/81] Fix bug in StaticGeometryPerMaterialBatch --- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 93868dbe9403..3bfd3c653f9f 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -38,7 +38,7 @@ define(['../Core/defined', Batch.prototype.isMaterial = function(updater) { var material = this.materialProperty; - var updaterMaterial = updater.materialProperty; + var updaterMaterial = updater.fillMaterialProperty; if (updaterMaterial === material) { return true; } From 355b7c4de03c624b4639ce9c67527c2d9094b86b Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Tue, 18 Feb 2014 22:50:32 -0500 Subject: [PATCH 61/81] Mostly finish up documentation. --- Source/DynamicScene/EllipseGeometryUpdater.js | 148 ++++++++++++++++- .../DynamicScene/EllipsoidGeometryUpdater.js | 150 +++++++++++++++++- Source/DynamicScene/PolygonGeometryUpdater.js | 148 ++++++++++++++++- .../DynamicScene/PolylineGeometryUpdater.js | 148 ++++++++++++++++- 4 files changed, 581 insertions(+), 13 deletions(-) diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 07286f71e07f..16da1547c8c7 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -60,6 +60,14 @@ define(['../Core/Color', this.numberOfVerticalLines = undefined; }; + /** + * A {@link GeometryUpdater} for ellipses. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * @alias EllipseGeometryUpdater + * @constructor + * + * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + */ var EllipseGeometryUpdater = function(dynamicObject) { //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { @@ -83,21 +91,55 @@ define(['../Core/Color', this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipse', dynamicObject.ellipse, undefined); }; - EllipseGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; - - EllipseGeometryUpdater.MaterialAppearanceType = MaterialAppearance; + defineProperties(EllipseGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof EllipseGeometryUpdater + * @type {Appearance} + */ + PerInstanceColorAppearanceType : { + get : function() { + return PerInstanceColorAppearance; + } + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof EllipseGeometryUpdater + * @type {Appearance} + */ + MaterialAppearanceType : { + get : function() { + return MaterialAppearance; + } + } + }); defineProperties(EllipseGeometryUpdater.prototype, { + /** + * Gets the object associated with this geometry. + * @memberof EllipseGeometryUpdater.prototype + * @type {DynamicObject} + */ dynamicObject :{ get : function() { return this._dynamicObject; } }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ fillEnabled : { get : function() { return this._fillEnabled; } }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantFill : { get : function() { return !this._fillEnabled || @@ -106,16 +148,31 @@ define(['../Core/Color', (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, + /** + * Gets the material property used to fill the geometry. + * @memberof EllipseGeometryUpdater.prototype + * @type {MaterialProperty} + */ fillMaterialProperty : { get : function() { return this._materialProperty; } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ outlineEnabled : { get : function() { return this._outlineEnabled; } }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantOutline : { get : function() { return !this._outlineEnabled || @@ -124,21 +181,46 @@ define(['../Core/Color', (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof EllipseGeometryUpdater.prototype + * @type {Property} + */ outlineColorProperty : { get : function() { return this._outlineColorProperty; } }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ isDynamic : { get : function() { return this._dynamic; } }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ isClosed : { get : function() { return this._isClosed; } }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof EllipseGeometryUpdater.prototype + * @type {Boolean} + */ geometryChanged : { get : function() { return this._geometryChanged; @@ -146,16 +228,42 @@ define(['../Core/Color', } }); + /** + * Checks if the geometry is outlined at the provided time. + * @memberof EllipseGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ EllipseGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; + /** + * Checks if the geometry is filled at the provided time. + * @memberof EllipseGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ EllipseGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; + /** + * Creates the geometry instance which represents the fill of the geometry. + * @memberof EllipseGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ EllipseGeometryUpdater.prototype.createFillGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -197,6 +305,16 @@ define(['../Core/Color', }); }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * @memberof EllipseGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -221,10 +339,24 @@ define(['../Core/Color', }); }; + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof EllipseGeometryUpdater + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ EllipseGeometryUpdater.prototype.isDestroyed = function() { return false; }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof EllipseGeometryUpdater + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ EllipseGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -328,6 +460,16 @@ define(['../Core/Color', } }; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @memberof EllipseGeometryUpdater + * @function + * + * @param {CompositePrimitive} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index c66fe8c4053c..eddbf3b793fa 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -66,6 +66,14 @@ define(['../Core/Cartesian3', this.subdivisions = undefined; }; + /** + * A {@link GeometryUpdater} for ellipsoids. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * @alias EllipsoidGeometryUpdater + * @constructor + * + * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + */ var EllipsoidGeometryUpdater = function(dynamicObject) { //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { @@ -88,21 +96,55 @@ define(['../Core/Cartesian3', this._onDynamicObjectPropertyChanged(dynamicObject, 'ellipsoid', dynamicObject.ellipsoid, undefined); }; - EllipsoidGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; - - EllipsoidGeometryUpdater.MaterialAppearanceType = MaterialAppearance; + defineProperties(EllipsoidGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof EllipsoidGeometryUpdater + * @type {Appearance} + */ + PerInstanceColorAppearanceType : { + get : function() { + return PerInstanceColorAppearance; + } + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof EllipsoidGeometryUpdater + * @type {Appearance} + */ + MaterialAppearanceType : { + get : function() { + return MaterialAppearance; + } + } + }); defineProperties(EllipsoidGeometryUpdater.prototype, { - dynamicObject :{ + /** + * Gets the object associated with this geometry. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {DynamicObject} + */ + dynamicObject : { get : function() { return this._dynamicObject; } }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ fillEnabled : { get : function() { return this._fillEnabled; } }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantFill : { get : function() { return !this._fillEnabled || @@ -111,16 +153,31 @@ define(['../Core/Cartesian3', (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, + /** + * Gets the material property used to fill the geometry. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {MaterialProperty} + */ fillMaterialProperty : { get : function() { return this._materialProperty; } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ outlineEnabled : { get : function() { return this._outlineEnabled; } }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantOutline : { get : function() { return !this._outlineEnabled || @@ -129,21 +186,46 @@ define(['../Core/Cartesian3', (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Property} + */ outlineColorProperty : { get : function() { return this._outlineColorProperty; } }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ isDynamic : { get : function() { return this._dynamic; } }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ isClosed : { get : function() { return true; } }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof EllipsoidGeometryUpdater.prototype + * @type {Boolean} + */ geometryChanged : { get : function() { return this._geometryChanged; @@ -151,16 +233,42 @@ define(['../Core/Cartesian3', } }); + /** + * Checks if the geometry is outlined at the provided time. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ EllipsoidGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; + /** + * Checks if the geometry is filled at the provided time. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ EllipsoidGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; + /** + * Creates the geometry instance which represents the fill of the geometry. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -206,6 +314,16 @@ define(['../Core/Cartesian3', }); }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -234,10 +352,24 @@ define(['../Core/Cartesian3', }); }; + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ EllipsoidGeometryUpdater.prototype.isDestroyed = function() { return false; }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ EllipsoidGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -328,6 +460,16 @@ define(['../Core/Cartesian3', } }; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @memberof EllipsoidGeometryUpdater + * @function + * + * @param {CompositePrimitive} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 7aef5e73a61a..69a388059f48 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -59,6 +59,14 @@ define(['../Core/Color', this.stRotation = undefined; }; + /** + * A {@link GeometryUpdater} for polygons. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * @alias PolygonGeometryUpdater + * @constructor + * + * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + */ var PolygonGeometryUpdater = function(dynamicObject) { //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { @@ -82,21 +90,55 @@ define(['../Core/Color', this._onDynamicObjectPropertyChanged(dynamicObject, 'polygon', dynamicObject.polygon, undefined); }; - PolygonGeometryUpdater.PerInstanceColorAppearanceType = PerInstanceColorAppearance; - - PolygonGeometryUpdater.MaterialAppearanceType = MaterialAppearance; + defineProperties(PolygonGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof PolygonGeometryUpdater + * @type {Appearance} + */ + PerInstanceColorAppearanceType : { + get : function() { + return PerInstanceColorAppearance; + } + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof PolygonGeometryUpdater + * @type {Appearance} + */ + MaterialAppearanceType : { + get : function() { + return MaterialAppearance; + } + } + }); defineProperties(PolygonGeometryUpdater.prototype, { + /** + * Gets the object associated with this geometry. + * @memberof PolygonGeometryUpdater.prototype + * @type {DynamicObject} + */ dynamicObject :{ get : function() { return this._dynamicObject; } }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ fillEnabled : { get : function() { return this._fillEnabled; } }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantFill : { get : function() { return !this._fillEnabled || @@ -105,16 +147,31 @@ define(['../Core/Color', (!defined(this._fillProperty) || this._fillProperty.isConstant)); } }, + /** + * Gets the material property used to fill the geometry. + * @memberof PolygonGeometryUpdater.prototype + * @type {MaterialProperty} + */ fillMaterialProperty : { get : function() { return this._materialProperty; } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ outlineEnabled : { get : function() { return this._outlineEnabled; } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantOutline : { get : function() { return !this._outlineEnabled || @@ -123,21 +180,46 @@ define(['../Core/Color', (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); } }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof PolygonGeometryUpdater.prototype + * @type {Property} + */ outlineColorProperty : { get : function() { return this._outlineColorProperty; } }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ isDynamic : { get : function() { return this._dynamic; } }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ isClosed : { get : function() { return this._isClosed; } }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PolygonGeometryUpdater.prototype + * @type {Boolean} + */ geometryChanged : { get : function() { return this._geometryChanged; @@ -145,16 +227,42 @@ define(['../Core/Color', } }); + /** + * Checks if the geometry is outlined at the provided time. + * @memberof PolygonGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ PolygonGeometryUpdater.prototype.isOutlineVisible = function(time) { var dynamicObject = this._dynamicObject; return this._outlineEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; + /** + * Checks if the geometry is filled at the provided time. + * @memberof PolygonGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ PolygonGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; + /** + * Creates the geometry instance which represents the fill of the geometry. + * @memberof PolygonGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ PolygonGeometryUpdater.prototype.createFillGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -196,6 +304,16 @@ define(['../Core/Color', }); }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * @memberof PolygonGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -220,10 +338,24 @@ define(['../Core/Color', }); }; + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof PolygonGeometryUpdater + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ PolygonGeometryUpdater.prototype.isDestroyed = function() { return false; }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof PolygonGeometryUpdater + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ PolygonGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -318,6 +450,16 @@ define(['../Core/Color', } }; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @memberof PolygonGeometryUpdater + * @function + * + * @param {CompositePrimitive} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 7a5edd1c3fd9..d1c5cdfd21df 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -48,6 +48,14 @@ define(['../Core/Color', this.width = undefined; }; + /** + * A {@link GeometryUpdater} for polylines. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * @alias PolygonGeometryUpdater + * @constructor + * + * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + */ var PolylineGeometryUpdater = function(dynamicObject) { //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { @@ -66,21 +74,55 @@ define(['../Core/Color', this._onDynamicObjectPropertyChanged(dynamicObject, 'polyline', dynamicObject.polyline, undefined); }; - PolylineGeometryUpdater.PerInstanceColorAppearanceType = PolylineColorAppearance; - - PolylineGeometryUpdater.MaterialAppearanceType = PolylineMaterialAppearance; + defineProperties(PolylineGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof PolylineGeometryUpdater + * @type {Appearance} + */ + PerInstanceColorAppearanceType : { + get : function() { + return PolylineColorAppearance; + } + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof PolylineGeometryUpdater + * @type {Appearance} + */ + MaterialAppearanceType : { + get : function() { + return PolylineMaterialAppearance; + } + } + }); defineProperties(PolylineGeometryUpdater.prototype, { + /** + * Gets the object associated with this geometry. + * @memberof PolylineGeometryUpdater.prototype + * @type {DynamicObject} + */ dynamicObject :{ get : function() { return this._dynamicObject; } }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ fillEnabled : { get : function() { return this._fillEnabled; } }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantFill : { get : function() { return !this._fillEnabled || @@ -88,36 +130,76 @@ define(['../Core/Color', (!defined(this._showProperty) || this._showProperty.isConstant)); } }, + /** + * Gets the material property used to fill the geometry. + * @memberof PolylineGeometryUpdater.prototype + * @type {MaterialProperty} + */ fillMaterialProperty : { get : function() { return this._materialProperty; } }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ outlineEnabled : { get : function() { return false; } }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ hasConstantOutline : { get : function() { return true; } }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof PolylineGeometryUpdater.prototype + * @type {Property} + */ outlineColorProperty : { get : function() { return undefined; } }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ isDynamic : { get : function() { return this._dynamic; } }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ isClosed : { get : function() { return false; } }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PolylineGeometryUpdater.prototype + * @type {Boolean} + */ geometryChanged : { get : function() { return this._geometryChanged; @@ -125,15 +207,41 @@ define(['../Core/Color', } }); + /** + * Checks if the geometry is outlined at the provided time. + * @memberof PolylineGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ PolylineGeometryUpdater.prototype.isOutlineVisible = function(time) { return false; }; + /** + * Checks if the geometry is filled at the provided time. + * @memberof PolylineGeometryUpdater + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ PolylineGeometryUpdater.prototype.isFilled = function(time) { var dynamicObject = this._dynamicObject; return this._fillEnabled && dynamicObject.isAvailable(time) && this._showProperty.getValue(time); }; + /** + * Creates the geometry instance which represents the fill of the geometry. + * @memberof PolylineGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ PolylineGeometryUpdater.prototype.createFillGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { @@ -174,16 +282,40 @@ define(['../Core/Color', }); }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * @memberof PolylineGeometryUpdater + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { //>>includeStart('debug', pragmas.debug); throw new DeveloperError('This instance does not represent an outlined geometry.'); //>>includeEnd('debug'); }; + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof PolylineGeometryUpdater + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ PolylineGeometryUpdater.prototype.isDestroyed = function() { return false; }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof PolylineGeometryUpdater + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ PolylineGeometryUpdater.prototype.destroy = function() { this._dynamicObjectSubscription(); destroyObject(this); @@ -251,6 +383,16 @@ define(['../Core/Color', } }; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @memberof PolylineGeometryUpdater + * @function + * + * @param {CompositePrimitive} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { //>>includeStart('debug', pragmas.debug); if (!this._dynamic) { From 1d68c96ec136819a702a944598cfdab0e30467ca Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 09:46:36 -0500 Subject: [PATCH 62/81] Update CHANGES --- CHANGES.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 4d2bc1e183d9..7747b8515ea4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,13 @@ Beta Releases * `getEllipsoid` -> `ellipsoid` * `getCameraPosition`, `setCameraPosition` -> `cameraPosition` * Removed `Scene.getUniformState()`. Use `scene.context.getUniformState()` + * Visualizers no longer create a `dynamicObject` property on the primitives they create. Instead, they set the `id` property that is standard for all primitives. + * The `propertyChanged` on DynamicScene objects has been renamed to `definitionChanged`. Also, the event is now raised in the case of an existing property being modified as well as having a new property assigned (previously only property assignment would raise the event). + * The `visualizerTypes` parameter to the `DataSouceDisplay` has been changed to a callback function that creates an array of visualizer instances. + * `DynamicDirectionsProperty` and `DynamicVertexPositionsProperty` were both removed, they have been superseded by `PropertyArray` and `PropertyPositionArray`, which make it easy for DataSource implementations to create time-dynamic arrays. + * `VisualizerCollection` has been removed. It is superseded by `DataSourceDisplay`. + * `DynamicEllipsoidVisualizer`, `DynamicPolygonVisualizer`, and `DynamicPolylineVisualizer` have been removed. They are superseded by `GeometryVisualizer` and corresponding `GeometryUpdater` implementations; `EllipsoidGeometryUpdater`, `PolygonGeometryUpdater`, `PolylineGeometryUpdater`. +* DynamicScene now makes use of Geoemtry and Appearances, which provides a tremendous improvements to DataSource visualization (CZML, GeoJSON, etc..). Extruded geometries are now supported and in many use cases performance is now GPU bound. * Added new `SelectionIndicator` and `InfoBox` widgets to `Viewer`, activated by `viewerDynamicObjectMixin`. * Fix developer error when zooming in 2D. If the zoom would create an invalid frustum, nothing is done. [#1432](https://github.com/AnalyticalGraphicsInc/cesium/issues/1432) * `OpenStreetMapImageryProvider` now supports imagery with a minimum level. @@ -50,6 +57,12 @@ Beta Releases * `RequestErrorEvent` now includes the headers that were returned with the error response. * Added `CesiumInspector` widget for graphics debugging. In Cesium Viewer, it is enabled by using the query parameter `inspector=true`. * Fixed `WallGeometry` bug that failed by removing positions that were less close together by less than 6 decimal places. [#1483](https://github.com/AnalyticalGraphicsInc/cesium/pull/1483) +* `DynamicEllipse`, `DynamicPolygon`, and `DynamicEllipsoid` now have properties matching their geometry counterpart, i.e. `EllipseGeometry`, `EllipseOutlineGeometry`, etc. These properties are also available in CZML. +* Added a `definitionChanged` event to the `Property` interface as well as most `DynamicScene` objects. This makes it easy for a client to observe when new data is loaded into a property or object. +* Added an `isConstant` property to the `Property` interface. Constant properties do not change in regards to simulation time, i.e. `Property.getValue` will always return the same result for all times. +* `ConstantProperty` is now mutable; it's value can be updated via `ConstantProperty.setValue`. +* Added AssociativeArray, which is a helper class for maintaining a hash of objects that also needs to be iterated often. +* Added `TimeIntervalCollection.getChangedEvent` which returns an event that will be raised whenever intervals are updated. ### b25 - 2014-02-03 From bd1ceae5bb022536de5359b74506a86adef0c915 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 13:44:54 -0500 Subject: [PATCH 63/81] More specs for GeometryVisualizer. These found and fixed a bug in the StaticGeometryPerMaterialBatch as well. --- .../StaticGeometryPerMaterialBatch.js | 5 +- Specs/DynamicScene/GeometryVisualizerSpec.js | 307 ++++++++++++++++-- 2 files changed, 278 insertions(+), 34 deletions(-) diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 3bfd3c653f9f..6de25c2d9790 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -124,10 +124,11 @@ define(['../Core/defined', /** * @private */ - var StaticGeometryPerMaterialBatch = function(primitives, appearanceType) { + var StaticGeometryPerMaterialBatch = function(primitives, appearanceType, closed) { this._items = []; this._primitives = primitives; this._appearanceType = appearanceType; + this._closed = closed; }; StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) { @@ -140,7 +141,7 @@ define(['../Core/defined', return; } } - var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty); + var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed); batch.add(time, updater); items.push(batch); }; diff --git a/Specs/DynamicScene/GeometryVisualizerSpec.js b/Specs/DynamicScene/GeometryVisualizerSpec.js index d4bedc60f9f3..9c2978a5c4d7 100644 --- a/Specs/DynamicScene/GeometryVisualizerSpec.js +++ b/Specs/DynamicScene/GeometryVisualizerSpec.js @@ -8,11 +8,13 @@ defineSuite(['DynamicScene/GeometryVisualizer', 'DynamicScene/ConstantPositionProperty', 'DynamicScene/DynamicObject', 'DynamicScene/GridMaterialProperty', + 'DynamicScene/SampledProperty', 'Core/Cartesian3', 'Core/Color', 'Core/ColorGeometryInstanceAttribute', 'Core/ShowGeometryInstanceAttribute', 'Core/JulianDate', + 'Scene/PrimitiveState', 'Specs/createScene', 'Specs/destroyScene' ], function( @@ -25,11 +27,13 @@ defineSuite(['DynamicScene/GeometryVisualizer', ConstantPositionProperty, DynamicObject, GridMaterialProperty, + SampledProperty, Cartesian3, Color, ColorGeometryInstanceAttribute, ShowGeometryInstanceAttribute, JulianDate, + PrimitiveState, createScene, destroyScene) { "use strict"; @@ -64,74 +68,306 @@ defineSuite(['DynamicScene/GeometryVisualizer', visualizer.destroy(); }); - it('Creates and removes static color primitives', function() { + it('Creates and removes static color open geometry', function() { var objects = new DynamicObjectCollection(); var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); var ellipse = new DynamicEllipse(); ellipse.semiMajorAxis = new ConstantProperty(2); ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new ColorMaterialProperty(); var dynamicObject = new DynamicObject(); dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); dynamicObject.ellipse = ellipse; objects.add(dynamicObject); - scene.initializeFrame(); - visualizer.update(time); - scene.render(time); + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); - expect(scene.primitives.length).toBe(1); + runs(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance.closed).toBe(false); - var primitive = scene.primitives.get(0); - var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); - expect(attributes).toBeDefined(); - expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); - expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); - objects.remove(dynamicObject); - scene.initializeFrame(); - visualizer.update(time); - scene.render(time); + expect(scene.primitives.length).toBe(0); - expect(scene.primitives.length).toBe(0); + visualizer.destroy(); + }); + }); - visualizer.destroy(); + it('Creates and removes static material open geometry', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new GridMaterialProperty(); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + runs(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(primitive.appearance.closed).toBe(false); + + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.primitives.length).toBe(0); + + visualizer.destroy(); + }); }); + it('Creates and removes static color closed geometry', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new ColorMaterialProperty(); + ellipse.extrudedHeight = new ConstantProperty(1000); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + runs(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance.closed).toBe(true); + + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.primitives.length).toBe(0); + + visualizer.destroy(); + }); + }); - it('Correctly handles changing appearance type', function() { + it('Creates and removes static material closed geometry', function() { var objects = new DynamicObjectCollection(); var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); var ellipse = new DynamicEllipse(); ellipse.semiMajorAxis = new ConstantProperty(2); ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new GridMaterialProperty(); + ellipse.extrudedHeight = new ConstantProperty(1000); var dynamicObject = new DynamicObject(); dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); dynamicObject.ellipse = ellipse; objects.add(dynamicObject); - scene.initializeFrame(); - visualizer.update(time); - scene.render(time); + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); - dynamicObject.ellipse.material = new GridMaterialProperty(); + runs(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(primitive.appearance.closed).toBe(true); - scene.initializeFrame(); - visualizer.update(time); - scene.render(time); + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); - var primitive = scene.primitives.get(0); - var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); - expect(attributes).toBeDefined(); - expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); - expect(attributes.color).toBeUndefined(); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(scene.primitives.length).toBe(0); + + visualizer.destroy(); + }); + }); + + it('Creates and removes static outline geometry', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.outline = new ConstantProperty(true); + ellipse.outlineColor = new ConstantProperty(Color.BLUE); + ellipse.fill = new ConstantProperty(false); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + runs(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.BLUE)); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.primitives.length).toBe(0); + + visualizer.destroy(); + }); + }); + + it('Correctly handles geometry changing batches', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new ConstantProperty(2); + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new ColorMaterialProperty(); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + var primitive; + var attributes; + + runs(function() { + primitive = scene.primitives.get(0); + attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + + ellipse.material = new GridMaterialProperty(); + }); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + runs(function() { + primitive = scene.primitives.get(0); + attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + + expect(scene.primitives.length).toBe(0); + + visualizer.destroy(); + }); - visualizer.destroy(); + }); + + it('Creates and removes dynamic geometry', function() { + var objects = new DynamicObjectCollection(); + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); + + var ellipse = new DynamicEllipse(); + ellipse.semiMajorAxis = new SampledProperty(Number); + ellipse.semiMajorAxis.addSample(time, 2); + ellipse.semiMinorAxis = new ConstantProperty(1); + ellipse.material = new ColorMaterialProperty(); + + var dynamicObject = new DynamicObject(); + dynamicObject.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + dynamicObject.ellipse = ellipse; + objects.add(dynamicObject); + + waitsFor(function() { + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + return scene.primitives.get(0)._state === PrimitiveState.COMPLETE; + }); + + runs(function() { + objects.remove(dynamicObject); + scene.initializeFrame(); + visualizer.update(time); + scene.render(time); + expect(scene.primitives.length).toBe(0); + visualizer.destroy(); + }); }); it('Constructor throws without type', function() { @@ -147,4 +383,11 @@ defineSuite(['DynamicScene/GeometryVisualizer', return new GeometryVisualizer(EllipseGeometryUpdater, undefined, objects); }).toThrowDeveloperError(); }); + + it('Update throws without time parameter', function() { + var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, new DynamicObjectCollection()); + expect(function() { + visualizer.update(undefined); + }).toThrowDeveloperError(); + }); }, 'WebGL'); \ No newline at end of file From b45e7948ec79cde0fac60fee2e7e6403853af874 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 14:45:32 -0500 Subject: [PATCH 64/81] Back out efb2f2d0af6566b1c4264d9dbe17ce3d034cba31 Unfortunately, `Primitive.modelMatrix` is only useful in 3d-only situations. See #1486 --- .../DynamicScene/EllipsoidGeometryUpdater.js | 132 ++++++------------ 1 file changed, 43 insertions(+), 89 deletions(-) diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index eddbf3b793fa..dc195ab782a4 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -54,7 +54,6 @@ define(['../Core/Cartesian3', var positionScratch; var orientationScratch; - var radiiScratch; var matrix3Scratch; var GeometryOptions = function(dynamicObject) { @@ -305,11 +304,12 @@ define(['../Core/Cartesian3', positionScratch = dynamicObject.position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); orientationScratch = dynamicObject.orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); + matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); return new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidGeometry(this._options), - modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch), + modelMatrix : Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch), attributes : attributes }); }; @@ -340,11 +340,12 @@ define(['../Core/Cartesian3', positionScratch = dynamicObject.position.getValue(Iso8601.MINIMUM_VALUE, positionScratch); orientationScratch = dynamicObject.orientation.getValue(Iso8601.MINIMUM_VALUE, orientationScratch); + matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); return new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidOutlineGeometry(this._options), - modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientationScratch), positionScratch), + modelMatrix : Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch), attributes : { show : new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(isAvailable ? this._outlineColorProperty.getValue(time) : Color.BLACK) @@ -488,17 +489,11 @@ define(['../Core/Cartesian3', * @private */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { - this._dynamicObject = geometryUpdater._dynamicObject; this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; this._geometryUpdater = geometryUpdater; this._options = new GeometryOptions(geometryUpdater._dynamicObject); - this._options.radii = new Cartesian3(1, 1, 1); - this._modelMatrix = new Matrix4(); - this._material = undefined; - this._attributes = undefined; - this._outlineAttributes = undefined; }; DynamicGeometryUpdater.prototype.update = function(time) { @@ -508,50 +503,46 @@ define(['../Core/Cartesian3', } //>>includeEnd('debug'); - var dynamicObject = this._dynamicObject; + var geometryUpdater = this._geometryUpdater; + + if (defined(this._primitive)) { + this._primitives.remove(this._primitive); + } + + if (defined(this._outlinePrimitive)) { + this._primitives.remove(this._outlinePrimitive); + } + + var dynamicObject = geometryUpdater._dynamicObject; var ellipsoid = dynamicObject.ellipsoid; var show = ellipsoid.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { - if (defined(this._primitive)) { - this._primitive.show = false; - } - - if (defined(this._outlinePrimitive)) { - this._outlinePrimitive.show = false; - } return; } - //Compute attributes and material. - var appearance; - var showFill = !defined(ellipsoid.fill) || ellipsoid.fill.getValue(time); - var showOutline = defined(ellipsoid.outline) && ellipsoid.outline.getValue(time); - var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; - var material = MaterialProperty.getValue(time, defaultValue(ellipsoid.material, defaultMaterial), this._material); - this._material = material; - - // Check properties that could trigger a primitive rebuild. - var stackPartitionsProperty = ellipsoid.stackPartitions; - var slicePartitionsProperty = ellipsoid.slicePartitions; - var subdivisionsProperty = ellipsoid.subdivisions; - var stackPartitions = defined(stackPartitionsProperty) ? stackPartitionsProperty.getValue(time) : undefined; - var slicePartitions = defined(slicePartitionsProperty) ? slicePartitionsProperty.getValue(time) : undefined; - var subdivisions = defined(subdivisionsProperty) ? subdivisionsProperty.getValue(time) : undefined; - var options = this._options; + var position = dynamicObject.position; + var orientation = dynamicObject.orientation; + var radii = ellipsoid.radii; + var stackPartitions = ellipsoid.stackPartitions; + var slicePartitions = ellipsoid.slicePartitions; + var subdivisions = ellipsoid.subdivisions; + + positionScratch = position.getValue(time, positionScratch); + orientationScratch = orientation.getValue(time, orientationScratch); + matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); + var modelMatrix = Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch); + + options.radii = radii.getValue(time, options.radii); + options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(time, options) : undefined; + options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(time, options) : undefined; + options.subdivisions = defined(subdivisions) ? subdivisions.getValue(time) : undefined; - //We only rebuild the primitive if something other than the radii has changed - //For the radii, we use unit sphere and then deform it with a scale matrix. - var rebuildPrimitives = !defined(this._primitive) || options.stackPartitions !== stackPartitions || options.slicePartitions !== slicePartitions || options.subdivisions !== subdivisions; - if (rebuildPrimitives) { - options.stackPartitions = stackPartitions; - options.slicePartitions = slicePartitions; - options.subdivisions = subdivisions; - - this._material = material; - material = this._material; - appearance = new MaterialAppearance({ + if (!defined(ellipsoid.fill) || ellipsoid.fill.getValue(time)) { + this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + var material = this._material; + var appearance = new MaterialAppearance({ material : material, faceForward : true, translucent : material.isTranslucent(), @@ -562,23 +553,25 @@ define(['../Core/Cartesian3', this._primitive = new Primitive({ geometryInstances : new GeometryInstance({ id : dynamicObject, - geometry : new EllipsoidGeometry(options) + geometry : new EllipsoidGeometry(options), + modelMatrix : modelMatrix }), appearance : appearance, - asynchronous : false, - attributes : { - show : new ShowGeometryInstanceAttribute(showFill) - } + asynchronous : false }); this._primitives.add(this._primitive); + } + if (defined(ellipsoid.outline) && ellipsoid.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ geometryInstances : new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidOutlineGeometry(options), + modelMatrix : modelMatrix, attributes : { - show : new ShowGeometryInstanceAttribute(showOutline), color : ColorGeometryInstanceAttribute.fromColor(outlineColor) } }), @@ -589,46 +582,7 @@ define(['../Core/Cartesian3', asynchronous : false }); this._primitives.add(this._outlinePrimitive); - - } else { - //Update attributes only. - var primitive = this._primitive; - appearance = primitive.appearance; - appearance.material = material; - - var attributes = this._attributes; - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(dynamicObject); - this._attributes = attributes; - } - attributes.show = ShowGeometryInstanceAttribute.toValue(showFill, attributes.show); - - var outlinePrimitive = this._outlinePrimitive; - - var outlineAttributes = this._outlineAttributes; - if (!defined(outlineAttributes)) { - outlineAttributes = outlinePrimitive.getGeometryInstanceAttributes(dynamicObject); - this._outlineAttributes = outlineAttributes; - } - outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(showOutline, outlineAttributes.show); - outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(outlineColor, outlineAttributes.color); } - - //Finally, compute and set the model matrices - var positionProperty = dynamicObject.position; - var orientationProperty = dynamicObject.orientation; - var radiiProperty = ellipsoid.radii; - - positionScratch = positionProperty.getValue(time, positionScratch); - orientationScratch = orientationProperty.getValue(time, orientationScratch); - matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); - radiiScratch = radiiProperty.getValue(time, radiiScratch); - - var modelMatrix = this._modelMatrix; - modelMatrix = Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch, modelMatrix); - modelMatrix = Matrix4.multiplyByScale(modelMatrix, radiiScratch, modelMatrix); - this._primitive.modelMatrix = modelMatrix; - this._outlinePrimitive.modelMatrix = modelMatrix; }; DynamicGeometryUpdater.prototype.isDestroyed = function() { From 1945e7ae3b51a7814d98e895abfd43886cd6b9ce Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 15:02:35 -0500 Subject: [PATCH 65/81] Disable asynchronous primitives in DynamicScene Due to #1487. We can revisit it in the future when performance is better. Since we create all the geometry up front anyway, this is a load time concern and should not become a usability issue. --- Source/DynamicScene/StaticGeometryColorBatch.js | 2 +- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 2 +- Source/DynamicScene/StaticOutlineGeometryBatch.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 48c3b76c763d..719ac9586057 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -61,7 +61,7 @@ define(['../Core/Color', var geometry = this.geometry.values; if (geometry.length > 0) { primitive = new Primitive({ - asynchronous : true, + asynchronous : false, geometryInstances : geometry, appearance : new this.appearanceType({ faceForward : true, diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 6de25c2d9790..69cb75538263 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -76,7 +76,7 @@ define(['../Core/defined', } if (geometries.length > 0) { primitive = new Primitive({ - asynchronous : true, + asynchronous : false, geometryInstances : geometries, appearance : new this.appearanceType({ material : MaterialProperty.getValue(time, this.materialProperty, this.material), diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 9d227257bb0f..66628217511f 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -61,7 +61,7 @@ define(['../Core/Color', var geometry = this.geometry.values; if (geometry.length > 0) { primitive = new Primitive({ - asynchronous : true, + asynchronous : false, geometryInstances : geometry, appearance : new PerInstanceColorAppearance({ flat : true, From 6d890fa676b2f65a582aa7f3211c5854d54daf75 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 15:55:53 -0500 Subject: [PATCH 66/81] Add a fast pass for dynamic ellipsoids in 3D mode. When in 3D, we scale a unit sphere rather than regenerating a primitive every frame. Once `Primitive.modelMatrix` can be used in 2D and CV modes, we can use the fast path in all cases. --- .../DynamicScene/EllipsoidGeometryUpdater.js | 155 +++++++++++++----- Source/DynamicScene/GeometryUpdater.js | 3 +- Source/DynamicScene/GeometryVisualizer.js | 2 +- .../EllipsoidGeometryUpdaterSpec.js | 61 ++++--- 4 files changed, 153 insertions(+), 68 deletions(-) diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index dc195ab782a4..2bc8f9c2f7df 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -20,7 +20,9 @@ define(['../Core/Cartesian3', '../DynamicScene/MaterialProperty', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive' + '../Scene/Primitive', + '../Scene/PrimitiveState', + '../Scene/SceneMode' ], function( Cartesian3, Color, @@ -43,7 +45,9 @@ define(['../Core/Cartesian3', MaterialProperty, MaterialAppearance, PerInstanceColorAppearance, - Primitive) { + Primitive, + PrimitiveState, + SceneMode) { "use strict"; var defaultMaterial = ColorMaterialProperty.fromColor(Color.WHITE); @@ -54,7 +58,9 @@ define(['../Core/Cartesian3', var positionScratch; var orientationScratch; + var radiiScratch; var matrix3Scratch; + var unitSphere = new Cartesian3(1, 1, 1); var GeometryOptions = function(dynamicObject) { this.id = dynamicObject; @@ -72,14 +78,19 @@ define(['../Core/Cartesian3', * @constructor * * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - var EllipsoidGeometryUpdater = function(dynamicObject) { + var EllipsoidGeometryUpdater = function(dynamicObject, scene) { //>>includeStart('debug', pragmas.debug); if (!defined(dynamicObject)) { throw new DeveloperError('dynamicObject is required'); } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } //>>includeEnd('debug'); + this._scene = scene; this._dynamicObject = dynamicObject; this._dynamicObjectSubscription = dynamicObject.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onDynamicObjectPropertyChanged, this); this._fillEnabled = false; @@ -489,11 +500,18 @@ define(['../Core/Cartesian3', * @private */ var DynamicGeometryUpdater = function(primitives, geometryUpdater) { + this._dynamicObject = geometryUpdater._dynamicObject; + this._scene = geometryUpdater._scene; this._primitives = primitives; this._primitive = undefined; this._outlinePrimitive = undefined; this._geometryUpdater = geometryUpdater; this._options = new GeometryOptions(geometryUpdater._dynamicObject); + this._modelMatrix = new Matrix4(); + this._material = undefined; + this._attributes = undefined; + this._outlineAttributes = undefined; + this._lastSceneMode = undefined; }; DynamicGeometryUpdater.prototype.update = function(time) { @@ -503,46 +521,69 @@ define(['../Core/Cartesian3', } //>>includeEnd('debug'); - var geometryUpdater = this._geometryUpdater; - - if (defined(this._primitive)) { - this._primitives.remove(this._primitive); - } - - if (defined(this._outlinePrimitive)) { - this._primitives.remove(this._outlinePrimitive); - } - - var dynamicObject = geometryUpdater._dynamicObject; + var dynamicObject = this._dynamicObject; var ellipsoid = dynamicObject.ellipsoid; var show = ellipsoid.show; if (!dynamicObject.isAvailable(time) || (defined(show) && !show.getValue(time))) { + if (defined(this._primitive)) { + this._primitive.show = false; + } + + if (defined(this._outlinePrimitive)) { + this._outlinePrimitive.show = false; + } return; } + //Compute attributes and material. + var appearance; + var showFill = !defined(ellipsoid.fill) || ellipsoid.fill.getValue(time); + var showOutline = defined(ellipsoid.outline) && ellipsoid.outline.getValue(time); + var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; + var material = MaterialProperty.getValue(time, defaultValue(ellipsoid.material, defaultMaterial), this._material); + this._material = material; + + // Check properties that could trigger a primitive rebuild. + var stackPartitionsProperty = ellipsoid.stackPartitions; + var slicePartitionsProperty = ellipsoid.slicePartitions; + var subdivisionsProperty = ellipsoid.subdivisions; + var stackPartitions = defined(stackPartitionsProperty) ? stackPartitionsProperty.getValue(time) : undefined; + var slicePartitions = defined(slicePartitionsProperty) ? slicePartitionsProperty.getValue(time) : undefined; + var subdivisions = defined(subdivisionsProperty) ? subdivisionsProperty.getValue(time) : undefined; + var options = this._options; - var position = dynamicObject.position; - var orientation = dynamicObject.orientation; - var radii = ellipsoid.radii; - var stackPartitions = ellipsoid.stackPartitions; - var slicePartitions = ellipsoid.slicePartitions; - var subdivisions = ellipsoid.subdivisions; - positionScratch = position.getValue(time, positionScratch); - orientationScratch = orientation.getValue(time, orientationScratch); + //In 3D we use a fast path by modifying Primitive.modelMatrix instead of regenerating the primitive every frame. + //Once #1486 is fixed, we can use the fast path in all cases. + var sceneMode = this._scene.mode; + var in3D = sceneMode === SceneMode.SCENE3D; + + var modelMatrix = this._modelMatrix; + var positionProperty = dynamicObject.position; + var orientationProperty = dynamicObject.orientation; + var radiiProperty = ellipsoid.radii; + positionScratch = positionProperty.getValue(time, positionScratch); + orientationScratch = orientationProperty.getValue(time, orientationScratch); matrix3Scratch = Matrix3.fromQuaternion(orientationScratch, matrix3Scratch); - var modelMatrix = Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch); - - options.radii = radii.getValue(time, options.radii); - options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(time, options) : undefined; - options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(time, options) : undefined; - options.subdivisions = defined(subdivisions) ? subdivisions.getValue(time) : undefined; - - if (!defined(ellipsoid.fill) || ellipsoid.fill.getValue(time)) { - this._material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - var material = this._material; - var appearance = new MaterialAppearance({ + radiiScratch = radiiProperty.getValue(time, radiiScratch); + modelMatrix = Matrix4.fromRotationTranslation(matrix3Scratch, positionScratch, modelMatrix); + + //We only rebuild the primitive if something other than the radii has changed + //For the radii, we use unit sphere and then deform it with a scale matrix. + var rebuildPrimitives = !in3D || this._lastSceneMode !== sceneMode || !defined(this._primitive) || options.stackPartitions !== stackPartitions || options.slicePartitions !== slicePartitions || options.subdivisions !== subdivisions; + if (rebuildPrimitives) { + this._removePrimitives(); + this._lastSceneMode = sceneMode; + + options.stackPartitions = stackPartitions; + options.slicePartitions = slicePartitions; + options.subdivisions = subdivisions; + options.radii = in3D ? unitSphere : radiiScratch; + + this._material = material; + material = this._material; + appearance = new MaterialAppearance({ material : material, faceForward : true, translucent : material.isTranslucent(), @@ -554,24 +595,24 @@ define(['../Core/Cartesian3', geometryInstances : new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidGeometry(options), - modelMatrix : modelMatrix + modelMatrix : !in3D ? modelMatrix : undefined }), appearance : appearance, - asynchronous : false + asynchronous : false, + attributes : { + show : new ShowGeometryInstanceAttribute(showFill) + } }); this._primitives.add(this._primitive); - } - if (defined(ellipsoid.outline) && ellipsoid.outline.getValue(time)) { options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - - var outlineColor = defined(ellipsoid.outlineColor) ? ellipsoid.outlineColor.getValue(time) : Color.BLACK; this._outlinePrimitive = new Primitive({ geometryInstances : new GeometryInstance({ id : dynamicObject, geometry : new EllipsoidOutlineGeometry(options), - modelMatrix : modelMatrix, + modelMatrix : !in3D ? modelMatrix : undefined, attributes : { + show : new ShowGeometryInstanceAttribute(showOutline), color : ColorGeometryInstanceAttribute.fromColor(outlineColor) } }), @@ -582,6 +623,34 @@ define(['../Core/Cartesian3', asynchronous : false }); this._primitives.add(this._outlinePrimitive); + } else if (this._primitive._state === PrimitiveState.COMPLETE) { + //Update attributes only. + var primitive = this._primitive; + appearance = primitive.appearance; + appearance.material = material; + + var attributes = this._attributes; + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(dynamicObject); + this._attributes = attributes; + } + attributes.show = ShowGeometryInstanceAttribute.toValue(showFill, attributes.show); + + var outlinePrimitive = this._outlinePrimitive; + + var outlineAttributes = this._outlineAttributes; + if (!defined(outlineAttributes)) { + outlineAttributes = outlinePrimitive.getGeometryInstanceAttributes(dynamicObject); + this._outlineAttributes = outlineAttributes; + } + outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(showOutline, outlineAttributes.show); + outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(outlineColor, outlineAttributes.color); + } + + if (in3D) { + modelMatrix = Matrix4.multiplyByScale(modelMatrix, radiiScratch, modelMatrix); + this._primitive.modelMatrix = modelMatrix; + this._outlinePrimitive.modelMatrix = modelMatrix; } }; @@ -589,7 +658,7 @@ define(['../Core/Cartesian3', return false; }; - DynamicGeometryUpdater.prototype.destroy = function() { + DynamicGeometryUpdater.prototype._removePrimitives = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); } @@ -597,6 +666,10 @@ define(['../Core/Cartesian3', if (defined(this._outlinePrimitive)) { this._primitives.remove(this._outlinePrimitive); } + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + this._removePrimitives(); destroyObject(this); }; diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js index 464e9e2cd3a4..60293035fa63 100644 --- a/Source/DynamicScene/GeometryUpdater.js +++ b/Source/DynamicScene/GeometryUpdater.js @@ -17,13 +17,14 @@ define(['../Core/defineProperties', * @constructor * * @param {DynamicObject} dynamicObject The object containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. * * @see EllipseGeometryUpdater * @see EllipsoidGeometryUpdater * @see PolygonGeometryUpdater * @see PolylineGeometryUpdater */ - var GeometryUpdater = function(dynamicObject) { + var GeometryUpdater = function(dynamicObject, scene) { DeveloperError.throwInstantiationError(); }; diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 926d3a37241c..fee5d1cd8e33 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -222,7 +222,7 @@ define(['../Core/defined', for (i = added.length - 1; i > -1; i--) { dynamicObject = added[i]; id = dynamicObject.id; - updater = new this._type(dynamicObject); + updater = new this._type(dynamicObject, this._scene); this._updaters.set(id, updater); insertUpdaterIntoBatch(this, time, updater); this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometyChanged, this)); diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index bd3f49639670..590f2f8aa362 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -17,7 +17,9 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', 'DynamicScene/SampledProperty', 'DynamicScene/SampledPositionProperty', 'DynamicScene/TimeIntervalCollectionProperty', - 'Scene/CompositePrimitive' + 'Scene/CompositePrimitive', + 'Specs/createScene', + 'Specs/destroyScene' ], function( EllipsoidGeometryUpdater, DynamicObject, @@ -37,12 +39,21 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', SampledProperty, SampledPositionProperty, TimeIntervalCollectionProperty, - CompositePrimitive) { + CompositePrimitive, + createScene, + destroyScene) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ var time = new JulianDate(); + var scene; + beforeEach(function() { + scene = createScene(); + }); + afterEach(function() { + destroyScene(scene); + }); function createBasicEllipsoid() { var ellipsoid = new DynamicEllipsoid(); ellipsoid.radii = new ConstantProperty(new Cartesian3(1, 2, 3)); @@ -56,7 +67,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('Constructor sets expected defaults', function() { var dynamicObject = new DynamicObject(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(updater.isDestroyed()).toBe(false); expect(updater.dynamicObject).toBe(dynamicObject); @@ -76,7 +87,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('No geometry available when ellipsoid is undefined ', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid = undefined; expect(updater.fillEnabled).toBe(false); @@ -86,7 +97,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('No geometry available when radii is undefined', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.radii = undefined; expect(updater.fillEnabled).toBe(false); @@ -96,7 +107,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('No geometry available when not filled or outline.', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.fill = new ConstantProperty(false); dynamicObject.ellipsoid.outline = new ConstantProperty(false); @@ -107,7 +118,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('Values correct when using default graphics', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(updater.fillEnabled).toBe(true); expect(updater.fillMaterialProperty).toEqual(ColorMaterialProperty.fromColor(Color.WHITE)); @@ -120,21 +131,21 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('Ellipsoid material is correctly exposed.', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.material = new GridMaterialProperty(Color.BLUE); expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); }); it('Ellipsoid material is correctly exposed.', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.material = new GridMaterialProperty(Color.BLUE); expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); }); it('A time-varying position causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.position = new SampledPositionProperty(); dynamicObject.position.addSample(time, Cartesian3.ZERO); expect(updater.isDynamic).toBe(true); @@ -142,7 +153,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('A time-varying radii causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.radii = new SampledProperty(Cartesian3); dynamicObject.ellipsoid.radii.addSample(time, new Cartesian3(1, 2, 3)); expect(updater.isDynamic).toBe(true); @@ -150,7 +161,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('A time-varying stackPartitions causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.stackPartitions = new SampledProperty(Number); dynamicObject.ellipsoid.stackPartitions.addSample(time, 1); expect(updater.isDynamic).toBe(true); @@ -158,7 +169,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('A time-varying slicePartitions causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.slicePartitions = new SampledProperty(Number); dynamicObject.ellipsoid.slicePartitions.addSample(time, 1); expect(updater.isDynamic).toBe(true); @@ -166,7 +177,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('A time-varying subdivisions causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); dynamicObject.ellipsoid.subdivisions = new SampledProperty(Number); dynamicObject.ellipsoid.subdivisions.addSample(time, 1); expect(updater.isDynamic).toBe(true); @@ -190,7 +201,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', ellipsoid.subdivisions = new ConstantProperty(options.subdivisions); dynamicObject.ellipsoid = ellipsoid; - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); var instance; var geometry; @@ -289,7 +300,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', dynamicObject.ellipsoid.outline = outline; dynamicObject.ellipsoid.outlineColor = outlineColor; - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); var instance = updater.createFillGeometryInstance(time2); var attributes = instance.attributes; @@ -326,7 +337,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', dynamicObject.position = makeProperty(Cartesian3.UNIT_Z, Cartesian3.UNIT_Y); dynamicObject.orientation = makeProperty(Quaternion.IDENTITY, new Quaternion(0, 1, 0, 0)); dynamicObject.ellipsoid = ellipsoid; - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); expect(dynamicUpdater.isDestroyed()).toBe(false); @@ -340,7 +351,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('geometryChanged event is raised when expected', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); var listener = jasmine.createSpy('listener'); updater.geometryChanged.addEventListener(listener); @@ -367,7 +378,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('createFillGeometryInstance throws if object is not filled', function() { var dynamicObject = new DynamicObject(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(function() { return updater.createFillGeometryInstance(time); }).toThrowDeveloperError(); @@ -375,7 +386,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('createFillGeometryInstance throws if no time provided', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(function() { return updater.createFillGeometryInstance(undefined); }).toThrowDeveloperError(); @@ -383,7 +394,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('createOutlineGeometryInstance throws if object is not outlined', function() { var dynamicObject = new DynamicObject(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(function() { return updater.createOutlineGeometryInstance(time); }).toThrowDeveloperError(); @@ -392,7 +403,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('createOutlineGeometryInstance throws if no time provided', function() { var dynamicObject = createBasicEllipsoid(); dynamicObject.ellipsoid.outline = new ConstantProperty(true); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(function() { return updater.createOutlineGeometryInstance(undefined); }).toThrowDeveloperError(); @@ -400,7 +411,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', it('createDynamicUpdater throws if not dynamic', function() { var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(function() { return updater.createDynamicUpdater(new CompositePrimitive()); }).toThrowDeveloperError(); @@ -410,7 +421,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', var dynamicObject = createBasicEllipsoid(); dynamicObject.ellipsoid.radii = new SampledProperty(Number); dynamicObject.ellipsoid.radii.addSample(time, 4); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); expect(updater.isDynamic).toBe(true); expect(function() { return updater.createDynamicUpdater(undefined); @@ -421,7 +432,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', var dynamicObject = createBasicEllipsoid(); dynamicObject.ellipsoid.radii = new SampledProperty(Number); dynamicObject.ellipsoid.radii.addSample(time, 4); - var updater = new EllipsoidGeometryUpdater(dynamicObject); + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); expect(function() { dynamicUpdater.update(undefined); From 9f775a2cf850fac7d0b94bf816b4f4d6a18c5ae3 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 17:07:50 -0500 Subject: [PATCH 67/81] More specs --- .../DynamicScene/PolylineGeometryUpdater.js | 4 + .../EllipseGeometryUpdaterSpec.js | 11 +- .../EllipsoidGeometryUpdaterSpec.js | 11 +- .../PolygonGeometryUpdaterSpec.js | 444 ++++++++++++++++++ 4 files changed, 460 insertions(+), 10 deletions(-) create mode 100644 Specs/DynamicScene/PolygonGeometryUpdaterSpec.js diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index d1c5cdfd21df..dd01896706f1 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -468,6 +468,10 @@ define(['../Core/Color', this._primitives.add(this._primitive); }; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + DynamicGeometryUpdater.prototype.destroy = function() { if (defined(this._primitive)) { this._primitives.remove(this._primitive); diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 819e7490a62f..4cf7f6767e7d 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -390,15 +390,16 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', dynamicObject.availability.addInterval(new TimeInterval(time1, time3, true, false)); dynamicObject.position = makeProperty(Cartesian3.UNIT_Z, Cartesian3.UNIT_Y); dynamicObject.ellipse = ellipse; + var updater = new EllipseGeometryUpdater(dynamicObject); - var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + var primitives = new CompositePrimitive(); + var dynamicUpdater = updater.createDynamicUpdater(primitives); expect(dynamicUpdater.isDestroyed()).toBe(false); - + expect(primitives.length).toBe(0); dynamicUpdater.update(time1); - dynamicUpdater.update(time2); - dynamicUpdater.update(time3); - + expect(primitives.length).toBe(1); dynamicUpdater.destroy(); + expect(primitives.length).toBe(0); updater.destroy(); }); diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index 590f2f8aa362..fad256ad629b 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -337,15 +337,16 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', dynamicObject.position = makeProperty(Cartesian3.UNIT_Z, Cartesian3.UNIT_Y); dynamicObject.orientation = makeProperty(Quaternion.IDENTITY, new Quaternion(0, 1, 0, 0)); dynamicObject.ellipsoid = ellipsoid; + var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); - var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + var primitives = new CompositePrimitive(); + var dynamicUpdater = updater.createDynamicUpdater(primitives); expect(dynamicUpdater.isDestroyed()).toBe(false); - + expect(primitives.length).toBe(0); dynamicUpdater.update(time1); - dynamicUpdater.update(time2); - dynamicUpdater.update(time3); - + expect(primitives.length).toBe(1); dynamicUpdater.destroy(); + expect(primitives.length).toBe(0); updater.destroy(); }); diff --git a/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js b/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js new file mode 100644 index 000000000000..8e2ff8eb2b95 --- /dev/null +++ b/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js @@ -0,0 +1,444 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/PolygonGeometryUpdater', + 'DynamicScene/DynamicObject', + 'DynamicScene/DynamicPolygon', + 'Core/Cartesian3', + 'Core/Cartographic', + 'Core/Color', + 'Core/Ellipsoid', + 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection', + 'Core/ColorGeometryInstanceAttribute', + 'Core/ShowGeometryInstanceAttribute', + 'DynamicScene/ColorMaterialProperty', + 'DynamicScene/ConstantProperty', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/GridMaterialProperty', + 'DynamicScene/PropertyArray', + 'DynamicScene/SampledProperty', + 'DynamicScene/SampledPositionProperty', + 'DynamicScene/TimeIntervalCollectionProperty', + 'Scene/CompositePrimitive' + ], function( + PolygonGeometryUpdater, + DynamicObject, + DynamicPolygon, + Cartesian3, + Cartographic, + Color, + Ellipsoid, + JulianDate, + TimeInterval, + TimeIntervalCollection, + ColorGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + ConstantPositionProperty, + GridMaterialProperty, + PropertyArray, + SampledProperty, + SampledPositionProperty, + TimeIntervalCollectionProperty, + CompositePrimitive) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + function createBasicPolygon() { + var polygon = new DynamicPolygon(); + var dynamicObject = new DynamicObject(); + dynamicObject.vertexPositions = new ConstantProperty(Ellipsoid.WGS84.cartographicArrayToCartesianArray([new Cartographic(0, 0, 0), new Cartographic(1, 0, 0), new Cartographic(1, 1, 0), new Cartographic(0, 1, 0)])); + dynamicObject.polygon = polygon; + return dynamicObject; + } + + it('Constructor sets expected defaults', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolygonGeometryUpdater(dynamicObject); + + expect(updater.isDestroyed()).toBe(false); + expect(updater.dynamicObject).toBe(dynamicObject); + expect(updater.isClosed).toBe(false); + expect(updater.fillEnabled).toBe(false); + expect(updater.fillMaterialProperty).toBe(undefined); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + expect(updater.isOutlineVisible(time)).toBe(false); + expect(updater.isFilled(time)).toBe(false); + updater.destroy(); + expect(updater.isDestroyed()).toBe(true); + }); + + it('No geometry available when polygon is undefined ', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon = undefined; + + 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 dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.fill = new ConstantProperty(false); + dynamicObject.polygon.outline = new ConstantProperty(false); + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('Values correct when using default graphics', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + + expect(updater.isClosed).toBe(false); + expect(updater.fillEnabled).toBe(true); + expect(updater.fillMaterialProperty).toEqual(ColorMaterialProperty.fromColor(Color.WHITE)); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + }); + + it('Polygon material is correctly exposed.', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.polygon.material); + }); + + it('Settings extrudedHeight causes geometry to be closed.', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.extrudedHeight = new ConstantProperty(1000); + expect(updater.isClosed).toBe(true); + }); + + it('Polygon material is correctly exposed.', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.material = new GridMaterialProperty(Color.BLUE); + expect(updater.fillMaterialProperty).toBe(dynamicObject.polygon.material); + }); + + it('A time-varying vertexPositions causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + var point1 = new SampledPositionProperty(); + point1.addSample(time, new Cartesian3()); + var point2 = new SampledPositionProperty(); + point2.addSample(time, new Cartesian3()); + var point3 = new SampledPositionProperty(); + point3.addSample(time, new Cartesian3()); + + dynamicObject.vertexPositions = new PropertyArray(); + dynamicObject.vertexPositions.setValue([point1, point2, point3]); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying height causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.height = new SampledProperty(Number); + dynamicObject.polygon.height.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying extrudedHeight causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.extrudedHeight = new SampledProperty(Number); + dynamicObject.polygon.extrudedHeight.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying granularity causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.granularity = new SampledProperty(Number); + dynamicObject.polygon.granularity.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying stRotation causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.stRotation = new SampledProperty(Number); + dynamicObject.polygon.stRotation.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying perPositionHeight causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + dynamicObject.polygon.perPositionHeight = new SampledProperty(Number); + dynamicObject.polygon.perPositionHeight.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + function validateGeometryInstance(options) { + var dynamicObject = createBasicPolygon(); + + var polygon = dynamicObject.polygon; + polygon.show = new ConstantProperty(options.show); + polygon.fill = new ConstantProperty(options.fill); + polygon.material = options.material; + polygon.outline = new ConstantProperty(options.outline); + polygon.outlineColor = new ConstantProperty(options.outlineColor); + polygon.perPositionHeight = new ConstantProperty(options.perPositionHeight); + + polygon.stRotation = new ConstantProperty(options.stRotation); + polygon.height = new ConstantProperty(options.height); + polygon.extrudedHeight = new ConstantProperty(options.extrudedHeight); + polygon.granularity = new ConstantProperty(options.granularity); + + var updater = new PolygonGeometryUpdater(dynamicObject); + + var instance; + var geometry; + var attributes; + if (options.fill) { + instance = updater.createFillGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._stRotation).toEqual(options.stRotation); + expect(geometry._height).toEqual(options.height); + expect(geometry._granularity).toEqual(options.granularity); + expect(geometry._extrudedHeight).toEqual(options.extrudedHeight); + + 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(options.fill)); + } + + if (options.outline) { + instance = updater.createOutlineGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._height).toEqual(options.height); + expect(geometry._granularity).toEqual(options.granularity); + expect(geometry._extrudedHeight).toEqual(options.extrudedHeight); + expect(geometry._perPositionHeight).toEqual(options.perPositionHeight); + + attributes = instance.attributes; + expect(attributes.color.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.outlineColor)); + expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(options.fill)); + } + } + + it('Creates expected per-color geometry', function() { + validateGeometryInstance({ + show : true, + material : ColorMaterialProperty.fromColor(Color.RED), + height : 431, + extrudedHeight : 123, + granularity : 0.97, + stRotation : 12, + fill : true, + outline : true, + outlineColor : Color.BLUE, + perPositionHeight : true + }); + }); + + it('Creates expected per-material geometry', function() { + validateGeometryInstance({ + show : true, + material : new GridMaterialProperty(), + height : 431, + extrudedHeight : 123, + granularity : 0.97, + stRotation : 12, + fill : true, + outline : true, + outlineColor : Color.BLUE, + perPositionHeight : false + }); + }); + + 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(time1, time2, true, true, false)); + fill.intervals.addInterval(new TimeInterval(time2, time3, false, true, 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(time1, time2, true, true, false)); + outline.intervals.addInterval(new TimeInterval(time2, time3, false, true, true)); + + var outlineColor = new SampledProperty(Color); + outlineColor.addSample(time, Color.BLUE); + outlineColor.addSample(time2, Color.RED); + outlineColor.addSample(time3, Color.YELLOW); + + var dynamicObject = createBasicPolygon(); + dynamicObject.polygon.fill = fill; + dynamicObject.polygon.material = colorMaterial; + dynamicObject.polygon.outline = outline; + dynamicObject.polygon.outlineColor = outlineColor; + + var updater = new PolygonGeometryUpdater(dynamicObject); + + 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('dynamic updater sets properties', function() { + //Finish this test + var time1 = new JulianDate(0, 0); + var time2 = new JulianDate(1, 0); + var time3 = new JulianDate(2, 0); + + function makeProperty(value1, value2) { + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(new TimeInterval(time1, time2, true, false, value1)); + property.intervals.addInterval(new TimeInterval(time2, time3, true, false, value2)); + return property; + } + + var dynamicObject = createBasicPolygon(); + + var polygon = dynamicObject.polygon; + polygon.height = makeProperty(2, 12); + polygon.extrudedHeight = makeProperty(1, 11); + polygon.outline = makeProperty(true, false); + polygon.fill = makeProperty(false, true); + + dynamicObject.availability = new TimeIntervalCollection(); + dynamicObject.availability.addInterval(new TimeInterval(time1, time3, true, false)); + + var updater = new PolygonGeometryUpdater(dynamicObject); + var primitives = new CompositePrimitive(); + var dynamicUpdater = updater.createDynamicUpdater(primitives); + expect(dynamicUpdater.isDestroyed()).toBe(false); + expect(primitives.length).toBe(0); + dynamicUpdater.update(time1); + expect(primitives.length).toBe(1); + dynamicUpdater.destroy(); + expect(primitives.length).toBe(0); + updater.destroy(); + }); + + it('geometryChanged event is raised when expected', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + var listener = jasmine.createSpy('listener'); + updater.geometryChanged.addEventListener(listener); + + dynamicObject.vertexPositions = new ConstantProperty([]); + expect(listener.callCount).toEqual(1); + + dynamicObject.polygon.height = new ConstantProperty(82); + expect(listener.callCount).toEqual(2); + + dynamicObject.availability = new TimeIntervalCollection(); + expect(listener.callCount).toEqual(3); + + dynamicObject.vertexPositions = undefined; + expect(listener.callCount).toEqual(4); + + //Since there's no valid geometry, changing another property should not raise the event. + dynamicObject.polygon.height = undefined; + + //Modifying an unrelated property should not have any effect. + dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); + expect(listener.callCount).toEqual(4); + }); + + it('createFillGeometryInstance throws if object is not filled', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(function() { + return updater.createFillGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createFillGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(function() { + return updater.createFillGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if object is not outlined', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicPolygon(); + dynamicObject.polygon.outline = new ConstantProperty(true); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if not dynamic', function() { + var dynamicObject = createBasicPolygon(); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(function() { + return updater.createDynamicUpdater(new CompositePrimitive()); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if primitives undefined', function() { + var dynamicObject = createBasicPolygon(); + dynamicObject.polygon.height = new SampledProperty(Number); + dynamicObject.polygon.height.addSample(time, 4); + var updater = new PolygonGeometryUpdater(dynamicObject); + expect(updater.isDynamic).toBe(true); + expect(function() { + return updater.createDynamicUpdater(undefined); + }).toThrowDeveloperError(); + }); + + it('dynamicUpdater.update throws if no time specified', function() { + var dynamicObject = createBasicPolygon(); + dynamicObject.polygon.height = new SampledProperty(Number); + dynamicObject.polygon.height.addSample(time, 4); + var updater = new PolygonGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(function() { + dynamicUpdater.update(undefined); + }).toThrowDeveloperError(); + }); + + it('Constructor throws if no DynamicObject supplied', function() { + expect(function() { + return new PolygonGeometryUpdater(undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file From 6fbe899d9a11e96be03ae99550e1716d3adf0794 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 17:25:39 -0500 Subject: [PATCH 68/81] Spec cleanup. --- .../EllipseGeometryUpdaterSpec.js | 9 +- .../EllipsoidGeometryUpdaterSpec.js | 9 +- .../PolygonGeometryUpdaterSpec.js | 9 +- .../PolylineGeometryUpdaterSpec.js | 331 ++++++++++++++++++ 4 files changed, 334 insertions(+), 24 deletions(-) create mode 100644 Specs/DynamicScene/PolylineGeometryUpdaterSpec.js diff --git a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js index 4cf7f6767e7d..34d948f5bc69 100644 --- a/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipseGeometryUpdaterSpec.js @@ -141,13 +141,6 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', expect(updater.isClosed).toBe(true); }); - it('Ellipse material is correctly exposed.', function() { - var dynamicObject = createBasicEllipse(); - var updater = new EllipseGeometryUpdater(dynamicObject); - dynamicObject.ellipse.material = new GridMaterialProperty(Color.BLUE); - expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipse.material); - }); - it('A time-varying position causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipse(); var updater = new EllipseGeometryUpdater(dynamicObject); @@ -367,7 +360,7 @@ defineSuite(['DynamicScene/EllipseGeometryUpdater', }); it('dynamic updater sets properties', function() { - //Finish this test + //This test is mostly a smoke screen for now. var time1 = new JulianDate(0, 0); var time2 = new JulianDate(1, 0); var time3 = new JulianDate(2, 0); diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index fad256ad629b..82baa54aafb9 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -136,13 +136,6 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); }); - it('Ellipsoid material is correctly exposed.', function() { - var dynamicObject = createBasicEllipsoid(); - var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); - dynamicObject.ellipsoid.material = new GridMaterialProperty(Color.BLUE); - expect(updater.fillMaterialProperty).toBe(dynamicObject.ellipsoid.material); - }); - it('A time-varying position causes geometry to be dynamic', function() { var dynamicObject = createBasicEllipsoid(); var updater = new EllipsoidGeometryUpdater(dynamicObject, scene); @@ -314,7 +307,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', }); it('dynamic updater sets properties', function() { - //Finish this test + //This test is mostly a smoke screen for now. var time1 = new JulianDate(0, 0); var time2 = new JulianDate(1, 0); var time3 = new JulianDate(2, 0); diff --git a/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js b/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js index 8e2ff8eb2b95..21912eaa2c08 100644 --- a/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/PolygonGeometryUpdaterSpec.js @@ -124,13 +124,6 @@ defineSuite(['DynamicScene/PolygonGeometryUpdater', expect(updater.isClosed).toBe(true); }); - it('Polygon material is correctly exposed.', function() { - var dynamicObject = createBasicPolygon(); - var updater = new PolygonGeometryUpdater(dynamicObject); - dynamicObject.polygon.material = new GridMaterialProperty(Color.BLUE); - expect(updater.fillMaterialProperty).toBe(dynamicObject.polygon.material); - }); - it('A time-varying vertexPositions causes geometry to be dynamic', function() { var dynamicObject = createBasicPolygon(); var updater = new PolygonGeometryUpdater(dynamicObject); @@ -312,7 +305,7 @@ defineSuite(['DynamicScene/PolygonGeometryUpdater', }); it('dynamic updater sets properties', function() { - //Finish this test + //This test is mostly a smoke screen for now. var time1 = new JulianDate(0, 0); var time2 = new JulianDate(1, 0); var time3 = new JulianDate(2, 0); diff --git a/Specs/DynamicScene/PolylineGeometryUpdaterSpec.js b/Specs/DynamicScene/PolylineGeometryUpdaterSpec.js new file mode 100644 index 000000000000..9827cc64fb22 --- /dev/null +++ b/Specs/DynamicScene/PolylineGeometryUpdaterSpec.js @@ -0,0 +1,331 @@ +/*global defineSuite*/ +defineSuite(['DynamicScene/PolylineGeometryUpdater', + 'DynamicScene/DynamicObject', + 'DynamicScene/DynamicPolyline', + 'Core/Cartesian3', + 'Core/Cartographic', + 'Core/Color', + 'Core/Ellipsoid', + 'Core/JulianDate', + 'Core/TimeInterval', + 'Core/TimeIntervalCollection', + 'Core/ColorGeometryInstanceAttribute', + 'Core/ShowGeometryInstanceAttribute', + 'DynamicScene/ColorMaterialProperty', + 'DynamicScene/ConstantProperty', + 'DynamicScene/ConstantPositionProperty', + 'DynamicScene/GridMaterialProperty', + 'DynamicScene/PropertyArray', + 'DynamicScene/SampledProperty', + 'DynamicScene/SampledPositionProperty', + 'DynamicScene/TimeIntervalCollectionProperty', + 'Scene/CompositePrimitive' + ], function( + PolylineGeometryUpdater, + DynamicObject, + DynamicPolyline, + Cartesian3, + Cartographic, + Color, + Ellipsoid, + JulianDate, + TimeInterval, + TimeIntervalCollection, + ColorGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + ColorMaterialProperty, + ConstantProperty, + ConstantPositionProperty, + GridMaterialProperty, + PropertyArray, + SampledProperty, + SampledPositionProperty, + TimeIntervalCollectionProperty, + CompositePrimitive) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var time = new JulianDate(); + + function createBasicPolyline() { + var polyline = new DynamicPolyline(); + var dynamicObject = new DynamicObject(); + dynamicObject.vertexPositions = new ConstantProperty(Ellipsoid.WGS84.cartographicArrayToCartesianArray([new Cartographic(0, 0, 0), new Cartographic(1, 0, 0), new Cartographic(1, 1, 0), new Cartographic(0, 1, 0)])); + dynamicObject.polyline = polyline; + return dynamicObject; + } + + it('Constructor sets expected defaults', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolylineGeometryUpdater(dynamicObject); + + expect(updater.isDestroyed()).toBe(false); + expect(updater.dynamicObject).toBe(dynamicObject); + expect(updater.isClosed).toBe(false); + expect(updater.fillEnabled).toBe(false); + expect(updater.fillMaterialProperty).toBe(undefined); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + expect(updater.isOutlineVisible(time)).toBe(false); + expect(updater.isFilled(time)).toBe(false); + updater.destroy(); + expect(updater.isDestroyed()).toBe(true); + }); + + it('No geometry available when polyline is undefined ', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + dynamicObject.polyline = undefined; + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('No geometry available when not shown.', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + dynamicObject.polyline.show = new ConstantProperty(false); + + expect(updater.fillEnabled).toBe(false); + expect(updater.outlineEnabled).toBe(false); + expect(updater.isDynamic).toBe(false); + }); + + it('Values correct when using default graphics', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + + expect(updater.isClosed).toBe(false); + expect(updater.fillEnabled).toBe(true); + expect(updater.fillMaterialProperty).toEqual(ColorMaterialProperty.fromColor(Color.WHITE)); + expect(updater.outlineEnabled).toBe(false); + expect(updater.hasConstantFill).toBe(true); + expect(updater.hasConstantOutline).toBe(true); + expect(updater.outlineColorProperty).toBe(undefined); + expect(updater.isDynamic).toBe(false); + }); + + it('Polyline material is correctly exposed.', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + dynamicObject.polyline.material = new ColorMaterialProperty(); + expect(updater.fillMaterialProperty).toBe(dynamicObject.polyline.material); + }); + + it('A time-varying vertexPositions causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + var point1 = new SampledPositionProperty(); + point1.addSample(time, new Cartesian3()); + var point2 = new SampledPositionProperty(); + point2.addSample(time, new Cartesian3()); + var point3 = new SampledPositionProperty(); + point3.addSample(time, new Cartesian3()); + + dynamicObject.vertexPositions = new PropertyArray(); + dynamicObject.vertexPositions.setValue([point1, point2, point3]); + expect(updater.isDynamic).toBe(true); + }); + + it('A time-varying width causes geometry to be dynamic', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + dynamicObject.polyline.width = new SampledProperty(Number); + dynamicObject.polyline.width.addSample(time, 1); + expect(updater.isDynamic).toBe(true); + }); + + function validateGeometryInstance(options) { + var dynamicObject = createBasicPolyline(); + + var polyline = dynamicObject.polyline; + polyline.show = new ConstantProperty(options.show); + polyline.material = options.material; + + polyline.width = new ConstantProperty(options.width); + + var updater = new PolylineGeometryUpdater(dynamicObject); + + var instance; + var geometry; + var attributes; + instance = updater.createFillGeometryInstance(time); + geometry = instance.geometry; + expect(geometry._width).toEqual(options.width); + + 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(options.show)); + } + + it('Creates expected per-color geometry', function() { + validateGeometryInstance({ + show : true, + material : ColorMaterialProperty.fromColor(Color.RED), + width : 3 + }); + }); + + it('Creates expected per-material geometry', function() { + validateGeometryInstance({ + show : true, + material : new GridMaterialProperty(), + width : 4 + }); + }); + + 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 show = new TimeIntervalCollectionProperty(); + show.intervals.addInterval(new TimeInterval(time1, time2, true, true, false)); + show.intervals.addInterval(new TimeInterval(time2, time3, false, true, 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 dynamicObject = createBasicPolyline(); + dynamicObject.polyline.show = show; + dynamicObject.polyline.material = colorMaterial; + + var updater = new PolylineGeometryUpdater(dynamicObject); + + 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(show.getValue(time2))); + }); + + it('dynamic updater sets properties', function() { + //This test is mostly a smoke screen for now. + var time1 = new JulianDate(0, 0); + var time2 = new JulianDate(1, 0); + var time3 = new JulianDate(2, 0); + + function makeProperty(value1, value2) { + var property = new TimeIntervalCollectionProperty(); + property.intervals.addInterval(new TimeInterval(time1, time2, true, false, value1)); + property.intervals.addInterval(new TimeInterval(time2, time3, true, false, value2)); + return property; + } + + var dynamicObject = createBasicPolyline(); + + var polyline = dynamicObject.polyline; + polyline.width = makeProperty(2, 12); + polyline.show = makeProperty(true, false); + + dynamicObject.availability = new TimeIntervalCollection(); + dynamicObject.availability.addInterval(new TimeInterval(time1, time3, true, false)); + + var updater = new PolylineGeometryUpdater(dynamicObject); + var primitives = new CompositePrimitive(); + var dynamicUpdater = updater.createDynamicUpdater(primitives); + expect(dynamicUpdater.isDestroyed()).toBe(false); + expect(primitives.length).toBe(0); + dynamicUpdater.update(time1); + expect(primitives.length).toBe(1); + dynamicUpdater.destroy(); + expect(primitives.length).toBe(0); + updater.destroy(); + }); + + it('geometryChanged event is raised when expected', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + var listener = jasmine.createSpy('listener'); + updater.geometryChanged.addEventListener(listener); + + dynamicObject.vertexPositions = new ConstantProperty(Ellipsoid.WGS84.cartographicArrayToCartesianArray([new Cartographic(0, 0, 0), new Cartographic(1, 0, 0)])); + expect(listener.callCount).toEqual(1); + + dynamicObject.polyline.width = new ConstantProperty(82); + expect(listener.callCount).toEqual(2); + + dynamicObject.availability = new TimeIntervalCollection(); + expect(listener.callCount).toEqual(3); + + dynamicObject.vertexPositions = undefined; + expect(listener.callCount).toEqual(4); + + //Since there's no valid geometry, changing another property should not raise the event. + dynamicObject.polyline.width = undefined; + + //Modifying an unrelated property should not have any effect. + dynamicObject.viewFrom = new ConstantProperty(Cartesian3.UNIT_X); + expect(listener.callCount).toEqual(4); + }); + + it('createFillGeometryInstance throws if object is not shown', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolylineGeometryUpdater(dynamicObject); + expect(function() { + return updater.createFillGeometryInstance(time); + }).toThrowDeveloperError(); + }); + + it('createFillGeometryInstance throws if no time provided', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + expect(function() { + return updater.createFillGeometryInstance(undefined); + }).toThrowDeveloperError(); + }); + + it('createOutlineGeometryInstance throws', function() { + var dynamicObject = new DynamicObject(); + var updater = new PolylineGeometryUpdater(dynamicObject); + expect(function() { + return updater.createOutlineGeometryInstance(); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if not dynamic', function() { + var dynamicObject = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(dynamicObject); + expect(function() { + return updater.createDynamicUpdater(new CompositePrimitive()); + }).toThrowDeveloperError(); + }); + + it('createDynamicUpdater throws if primitives undefined', function() { + var dynamicObject = createBasicPolyline(); + dynamicObject.polyline.width = new SampledProperty(Number); + dynamicObject.polyline.width.addSample(time, 4); + var updater = new PolylineGeometryUpdater(dynamicObject); + expect(updater.isDynamic).toBe(true); + expect(function() { + return updater.createDynamicUpdater(undefined); + }).toThrowDeveloperError(); + }); + + it('dynamicUpdater.update throws if no time specified', function() { + var dynamicObject = createBasicPolyline(); + dynamicObject.polyline.width = new SampledProperty(Number); + dynamicObject.polyline.width.addSample(time, 4); + var updater = new PolylineGeometryUpdater(dynamicObject); + var dynamicUpdater = updater.createDynamicUpdater(new CompositePrimitive()); + expect(function() { + dynamicUpdater.update(undefined); + }).toThrowDeveloperError(); + }); + + it('Constructor throws if no DynamicObject supplied', function() { + expect(function() { + return new PolylineGeometryUpdater(undefined); + }).toThrowDeveloperError(); + }); +}); \ No newline at end of file From ec520cd1692891a89d624400656159f3e2deef0c Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Feb 2014 17:30:26 -0500 Subject: [PATCH 69/81] Fix test --- Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js index 82baa54aafb9..33e934f1fdec 100644 --- a/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js +++ b/Specs/DynamicScene/EllipsoidGeometryUpdaterSpec.js @@ -337,7 +337,7 @@ defineSuite(['DynamicScene/EllipsoidGeometryUpdater', expect(dynamicUpdater.isDestroyed()).toBe(false); expect(primitives.length).toBe(0); dynamicUpdater.update(time1); - expect(primitives.length).toBe(1); + expect(primitives.length).toBe(2); //Ellipsoid always has both fill and outline primitives. dynamicUpdater.destroy(); expect(primitives.length).toBe(0); updater.destroy(); From f6cbd8a16b20cd78faea94328d276445136e3e56 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 11:31:22 -0500 Subject: [PATCH 70/81] Address review comments 1. Fix typos 2. Use create `createDynamicPropertyDescriptor` in `Cartesian2WrapperProperty` 3. Run formatter on `CzmlDataSource.js` --- CHANGES.md | 2 +- Source/DynamicScene/CzmlDataSource.js | 76 ++++++------------- Source/DynamicScene/DataSourceDisplay.js | 2 +- Source/DynamicScene/DynamicGeometryUpdater.js | 2 +- 4 files changed, 25 insertions(+), 57 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7747b8515ea4..b20caecbbcef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -42,7 +42,7 @@ Beta Releases * `DynamicDirectionsProperty` and `DynamicVertexPositionsProperty` were both removed, they have been superseded by `PropertyArray` and `PropertyPositionArray`, which make it easy for DataSource implementations to create time-dynamic arrays. * `VisualizerCollection` has been removed. It is superseded by `DataSourceDisplay`. * `DynamicEllipsoidVisualizer`, `DynamicPolygonVisualizer`, and `DynamicPolylineVisualizer` have been removed. They are superseded by `GeometryVisualizer` and corresponding `GeometryUpdater` implementations; `EllipsoidGeometryUpdater`, `PolygonGeometryUpdater`, `PolylineGeometryUpdater`. -* DynamicScene now makes use of Geoemtry and Appearances, which provides a tremendous improvements to DataSource visualization (CZML, GeoJSON, etc..). Extruded geometries are now supported and in many use cases performance is now GPU bound. +* DynamicScene now makes use of Geometry and Appearances, which provides a tremendous improvements to DataSource visualization (CZML, GeoJSON, etc..). Extruded geometries are now supported and in many use cases performance is now GPU bound. * Added new `SelectionIndicator` and `InfoBox` widgets to `Viewer`, activated by `viewerDynamicObjectMixin`. * Fix developer error when zooming in 2D. If the zoom would create an invalid frustum, nothing is done. [#1432](https://github.com/AnalyticalGraphicsInc/cesium/issues/1432) * `OpenStreetMapImageryProvider` now supports imagery with a minimum level. diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 35b2614b99a8..2457f3c6e4b3 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -34,6 +34,7 @@ define(['../Core/Cartesian2', './CompositeProperty', './ConstantPositionProperty', './ConstantProperty', + './createDynamicPropertyDescriptor', './DynamicBillboard', './DynamicClock', './ColorMaterialProperty', @@ -96,6 +97,7 @@ define(['../Core/Cartesian2', CompositeProperty, ConstantPositionProperty, ConstantProperty, + createDynamicPropertyDescriptor, DynamicBillboard, DynamicClock, ColorMaterialProperty, @@ -147,42 +149,8 @@ define(['../Core/Cartesian2', return this._definitionChanged; } }, - x : { - get : function() { - return this._x; - }, - set : function(value) { - if (this._x !== value) { - if (this._xSubscription) { - this._xSubscription(); - this._xSubscription = undefined; - } - this._x = value; - if (defined(value)) { - this._xSubscription = value.definitionChanged.addEventListener(Cartesian2WrapperProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - }, - y : { - get : function() { - return this._y; - }, - set : function(value) { - if (this._y !== value) { - if (this._ySubscription) { - this._ySubscription(); - this._ySubscription = undefined; - } - this._y = value; - if (defined(value)) { - this._ySubscription = value.definitionChanged.addEventListener(Cartesian2WrapperProperty.prototype._raiseDefinitionChanged, this); - } - this._raiseDefinitionChanged(this); - } - } - } + x : createDynamicPropertyDescriptor('x'), + y : createDynamicPropertyDescriptor('y') }); Cartesian2WrapperProperty.prototype.getValue = function(time, result) { @@ -231,7 +199,7 @@ define(['../Core/Cartesian2', var len = rgba.length; rgbaf = new Array(len); - for ( var i = 0; i < len; i += 5) { + for (var i = 0; i < len; i += 5) { rgbaf[i] = rgba[i]; rgbaf[i + 1] = Color.byteToFloat(rgba[i + 1]); rgbaf[i + 2] = Color.byteToFloat(rgba[i + 2]); @@ -555,7 +523,7 @@ define(['../Core/Cartesian2', } if (Array.isArray(packetData)) { - for ( var i = 0, len = packetData.length; i < len; i++) { + for (var i = 0, len = packetData.length; i < len; i++) { processProperty(type, object, propertyName, packetData[i], interval, sourceUri); } } else { @@ -697,7 +665,7 @@ define(['../Core/Cartesian2', } if (Array.isArray(packetData)) { - for ( var i = 0, len = packetData.length; i < len; i++) { + for (var i = 0, len = packetData.length; i < len; i++) { processPositionProperty(object, propertyName, packetData[i], interval, sourceUri); } } else { @@ -723,20 +691,20 @@ define(['../Core/Cartesian2', if (defined(combinedInterval)) { if (!(property instanceof CompositeMaterialProperty)) { - property = new CompositeMaterialProperty(); - object[propertyName] = property; - //See if we already have data at that interval. - var thisIntervals = property.intervals; + property = new CompositeMaterialProperty(); + object[propertyName] = property; + //See if we already have data at that interval. + var thisIntervals = property.intervals; existingInterval = thisIntervals.findInterval(combinedInterval.start, combinedInterval.stop); - if (defined(existingInterval)) { - //We have an interval, but we need to make sure the - //new data is the same type of material as the old data. - existingMaterial = existingInterval.data; - } else { - //If not, create it. - existingInterval = combinedInterval.clone(); - thisIntervals.addInterval(existingInterval); - } + if (defined(existingInterval)) { + //We have an interval, but we need to make sure the + //new data is the same type of material as the old data. + existingMaterial = existingInterval.data; + } else { + //If not, create it. + existingInterval = combinedInterval.clone(); + thisIntervals.addInterval(existingInterval); + } } } else { existingMaterial = property; @@ -780,7 +748,7 @@ define(['../Core/Cartesian2', } if (Array.isArray(packetData)) { - for ( var i = 0, len = packetData.length; i < len; i++) { + for (var i = 0, len = packetData.length; i < len; i++) { processMaterialProperty(object, propertyName, packetData[i], interval, sourceUri); } } else { @@ -1601,7 +1569,7 @@ define(['../Core/Cartesian2', updaterFunctions = defined(updaterFunctions) ? updaterFunctions : CzmlDataSource.updaters; if (Array.isArray(czml)) { - for ( var i = 0, len = czml.length; i < len; i++) { + for (var i = 0, len = czml.length; i < len; i++) { processCzmlPacket(czml[i], dynamicObjectCollection, updaterFunctions, sourceUri, dataSource); } } else { diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 375198be35a4..08cb0e5f4eab 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -58,7 +58,7 @@ define(['../Core/defaultValue', * * @param {Scene} scene The scene in which to display the data. * @param {DataSourceCollection} dataSourceCollection The data sources to display. - * @param {Visaulizer[]} [visualizersCallback] A function which takes a scene and dataSource and returns the array of visualizers used for visualization. If left undefined, all standard visualizers are used. + * @param {Visualizer[]} [visualizersCallback] A function which takes a scene and dataSource and returns the array of visualizers used for visualization. If left undefined, all standard visualizers are used. */ var DataSourceDisplay = function(scene, dataSourceCollection, visualizersCallback) { //>>includeStart('debug', pragmas.debug); diff --git a/Source/DynamicScene/DynamicGeometryUpdater.js b/Source/DynamicScene/DynamicGeometryUpdater.js index 850c9a94e9f1..6b3d456498c9 100644 --- a/Source/DynamicScene/DynamicGeometryUpdater.js +++ b/Source/DynamicScene/DynamicGeometryUpdater.js @@ -8,7 +8,7 @@ define(['../Core/DeveloperError' * Defines the interface for a dynamic geometry updater. A DynamicGeometryUpdater * is responsible for handling visualization of a specific type of geometry * that needs to be recomputed based on simulation time. - * This classes is never used directly by client code, but is instead created by + * This object is never used directly by client code, but is instead created by * {@link GeometryUpdater} implementations which contain dynamic geometry. * * This type defines an interface and cannot be instantiated directly. From be622ae128c70ea16f68421c7afc741d09891cc4 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 12:08:04 -0500 Subject: [PATCH 71/81] Address additional review comments Fix a few typos and change casing on `PerInstanceColorAppearanceType` and `MaterialAppearanceType` --- Source/DynamicScene/DynamicLabelVisualizer.js | 2 +- Source/DynamicScene/DynamicPathVisualizer.js | 2 +- Source/DynamicScene/DynamicPointVisualizer.js | 2 +- Source/DynamicScene/DynamicPyramidVisualizer.js | 2 +- Source/DynamicScene/DynamicVectorVisualizer.js | 2 +- Source/DynamicScene/EllipseGeometryUpdater.js | 6 +++--- Source/DynamicScene/EllipsoidGeometryUpdater.js | 6 +++--- Source/DynamicScene/GeometryUpdater.js | 4 ++-- Source/DynamicScene/GeometryVisualizer.js | 8 ++++---- Source/DynamicScene/PolygonGeometryUpdater.js | 6 +++--- Source/DynamicScene/PolylineGeometryUpdater.js | 6 +++--- Specs/DynamicScene/GeometryVisualizerSpec.js | 14 +++++++------- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index 76ff5883bf7c..c1bf340e3943 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -39,7 +39,7 @@ define([ * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicPointVisualizer * @see DynamicPyramidVisualizer */ diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 6cb165885e73..ab5e7bc80282 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -392,7 +392,7 @@ define([ * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPointVisualizer * @see DynamicPyramidVisualizer diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index 75309d8b563b..3a6eb3554a8a 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -33,7 +33,7 @@ define([ * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPyramidVisualizer */ diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index a7f0dc0026f7..9ec22059bc65 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -43,7 +43,7 @@ define([ * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPointVisualizer */ diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index 499f81b8e574..85a895f59a0f 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -31,7 +31,7 @@ define([ * @see CompositeDynamicObjectCollection * @see DynamicBillboardVisualizer * @see DynamicConeVisualizer - * @see DynamicConeVisualizerUsingCustomSensorr + * @see DynamicConeVisualizerUsingCustomSensor * @see DynamicLabelVisualizer * @see DynamicPointVisualizer * @see DynamicPyramidVisualizer diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 16da1547c8c7..530d7f5e1a75 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -62,7 +62,7 @@ define(['../Core/Color', /** * A {@link GeometryUpdater} for ellipses. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. * @alias EllipseGeometryUpdater * @constructor * @@ -97,7 +97,7 @@ define(['../Core/Color', * @memberof EllipseGeometryUpdater * @type {Appearance} */ - PerInstanceColorAppearanceType : { + perInstanceColorAppearanceType : { get : function() { return PerInstanceColorAppearance; } @@ -107,7 +107,7 @@ define(['../Core/Color', * @memberof EllipseGeometryUpdater * @type {Appearance} */ - MaterialAppearanceType : { + materialAppearanceType : { get : function() { return MaterialAppearance; } diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 2bc8f9c2f7df..1c05f465e6ea 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -73,7 +73,7 @@ define(['../Core/Cartesian3', /** * A {@link GeometryUpdater} for ellipsoids. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. * @alias EllipsoidGeometryUpdater * @constructor * @@ -112,7 +112,7 @@ define(['../Core/Cartesian3', * @memberof EllipsoidGeometryUpdater * @type {Appearance} */ - PerInstanceColorAppearanceType : { + perInstanceColorAppearanceType : { get : function() { return PerInstanceColorAppearance; } @@ -122,7 +122,7 @@ define(['../Core/Cartesian3', * @memberof EllipsoidGeometryUpdater * @type {Appearance} */ - MaterialAppearanceType : { + materialAppearanceType : { get : function() { return MaterialAppearance; } diff --git a/Source/DynamicScene/GeometryUpdater.js b/Source/DynamicScene/GeometryUpdater.js index 60293035fa63..7974989110bf 100644 --- a/Source/DynamicScene/GeometryUpdater.js +++ b/Source/DynamicScene/GeometryUpdater.js @@ -34,7 +34,7 @@ define(['../Core/defineProperties', * @memberof GeometryUpdater * @type {Appearance} */ - PerInstanceColorAppearanceType : { + perInstanceColorAppearanceType : { get : DeveloperError.throwInstantiationError }, /** @@ -42,7 +42,7 @@ define(['../Core/defineProperties', * @memberof GeometryUpdater * @type {Appearance} */ - MaterialAppearanceType : { + materialAppearanceType : { get : DeveloperError.throwInstantiationError } }); diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index fee5d1cd8e33..c692e484dbf5 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -92,10 +92,10 @@ define(['../Core/defined', this._changedObjects = new DynamicObjectCollection(); this._outlineBatch = new StaticOutlineGeometryBatch(primitives); - this._closedColorBatch = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, true); - this._closedMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, true); - this._openColorBatch = new StaticGeometryColorBatch(primitives, type.PerInstanceColorAppearanceType, false); - this._openMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.MaterialAppearanceType, false); + this._closedColorBatch = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, true); + this._closedMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, true); + this._openColorBatch = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, false); + this._openMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, false); this._dynamicBatch = new DynamicGeometryBatch(primitives); this._subscriptions = new AssociativeArray(); diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 69a388059f48..7575a835103d 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -61,7 +61,7 @@ define(['../Core/Color', /** * A {@link GeometryUpdater} for polygons. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. * @alias PolygonGeometryUpdater * @constructor * @@ -96,7 +96,7 @@ define(['../Core/Color', * @memberof PolygonGeometryUpdater * @type {Appearance} */ - PerInstanceColorAppearanceType : { + perInstanceColorAppearanceType : { get : function() { return PerInstanceColorAppearance; } @@ -106,7 +106,7 @@ define(['../Core/Color', * @memberof PolygonGeometryUpdater * @type {Appearance} */ - MaterialAppearanceType : { + materialAppearanceType : { get : function() { return MaterialAppearance; } diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index dd01896706f1..c2c7cb54592a 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -50,7 +50,7 @@ define(['../Core/Color', /** * A {@link GeometryUpdater} for polylines. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDsplay}. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. * @alias PolygonGeometryUpdater * @constructor * @@ -80,7 +80,7 @@ define(['../Core/Color', * @memberof PolylineGeometryUpdater * @type {Appearance} */ - PerInstanceColorAppearanceType : { + perInstanceColorAppearanceType : { get : function() { return PolylineColorAppearance; } @@ -90,7 +90,7 @@ define(['../Core/Color', * @memberof PolylineGeometryUpdater * @type {Appearance} */ - MaterialAppearanceType : { + materialAppearanceType : { get : function() { return PolylineMaterialAppearance; } diff --git a/Specs/DynamicScene/GeometryVisualizerSpec.js b/Specs/DynamicScene/GeometryVisualizerSpec.js index 9c2978a5c4d7..2e60d3e70d99 100644 --- a/Specs/DynamicScene/GeometryVisualizerSpec.js +++ b/Specs/DynamicScene/GeometryVisualizerSpec.js @@ -95,7 +95,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.perInstanceColorAppearanceType); expect(primitive.appearance.closed).toBe(false); objects.remove(dynamicObject); @@ -136,7 +136,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toBeUndefined(); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.materialAppearanceType); expect(primitive.appearance.closed).toBe(false); objects.remove(dynamicObject); @@ -178,7 +178,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.perInstanceColorAppearanceType); expect(primitive.appearance.closed).toBe(true); objects.remove(dynamicObject); @@ -220,7 +220,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toBeUndefined(); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.materialAppearanceType); expect(primitive.appearance.closed).toBe(true); objects.remove(dynamicObject); @@ -263,7 +263,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.BLUE)); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.perInstanceColorAppearanceType); objects.remove(dynamicObject); scene.initializeFrame(); @@ -306,7 +306,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.PerInstanceColorAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.perInstanceColorAppearanceType); ellipse.material = new GridMaterialProperty(); }); @@ -324,7 +324,7 @@ defineSuite(['DynamicScene/GeometryVisualizer', expect(attributes).toBeDefined(); expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); expect(attributes.color).toBeUndefined(); - expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.MaterialAppearanceType); + expect(primitive.appearance).toBeInstanceOf(EllipseGeometryUpdater.materialAppearanceType); objects.remove(dynamicObject); scene.initializeFrame(); From 319cf6bfe87d308643210672434ab59654df0efd Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 13:18:59 -0500 Subject: [PATCH 72/81] Add missing pragma --- Source/DynamicScene/GeometryVisualizer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index c692e484dbf5..756f3a735440 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -73,13 +73,14 @@ define(['../Core/defined', * @param {DynamicObjectCollection} [dynamicObjectCollection] The dynamicObjectCollection to visualize. */ var GeometryVisualizer = function(type, scene, dynamicObjectCollection) { + //>>includeStart('debug', pragmas.debug); if (!defined(type)) { throw new DeveloperError('type is required.'); } - if (!defined(scene)) { throw new DeveloperError('scene is required.'); } + //>>includeEnd('debug'); this._type = type; From 0dd05c7e503debd00f0b5ecc925b65740a0e8cdc Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 14:20:32 -0500 Subject: [PATCH 73/81] More updates after review. --- Source/DynamicScene/ConstantProperty.js | 4 +- Source/DynamicScene/EllipseGeometryUpdater.js | 10 ++--- .../DynamicScene/EllipsoidGeometryUpdater.js | 14 ++---- Source/DynamicScene/GeometryVisualizer.js | 43 ++++++++++--------- Source/DynamicScene/PolygonGeometryUpdater.js | 10 ++--- .../DynamicScene/PolylineGeometryUpdater.js | 26 +++-------- 6 files changed, 40 insertions(+), 67 deletions(-) diff --git a/Source/DynamicScene/ConstantProperty.js b/Source/DynamicScene/ConstantProperty.js index ce02ebfea1a3..55ebc06cb3e9 100644 --- a/Source/DynamicScene/ConstantProperty.js +++ b/Source/DynamicScene/ConstantProperty.js @@ -43,9 +43,7 @@ define(['../Core/defaultValue', * @type {Boolean} */ isConstant : { - get : function() { - return true; - } + value : true }, /** * Gets the event that is raised whenever the definition of this property changes. diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index 530d7f5e1a75..e50e10b73200 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -98,9 +98,7 @@ define(['../Core/Color', * @type {Appearance} */ perInstanceColorAppearanceType : { - get : function() { - return PerInstanceColorAppearance; - } + value : PerInstanceColorAppearance }, /** * Gets the type of Appearance to use for material-based geometry. @@ -108,9 +106,7 @@ define(['../Core/Color', * @type {Appearance} */ materialAppearanceType : { - get : function() { - return MaterialAppearance; - } + value : MaterialAppearance } }); @@ -284,7 +280,7 @@ define(['../Core/Color', var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); if (this._materialProperty instanceof ColorMaterialProperty) { var currentColor = Color.WHITE; - if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { currentColor = this._materialProperty.color.getValue(time); } color = ColorGeometryInstanceAttribute.fromColor(currentColor); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 1c05f465e6ea..7f1bbd7de815 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -113,9 +113,7 @@ define(['../Core/Cartesian3', * @type {Appearance} */ perInstanceColorAppearanceType : { - get : function() { - return PerInstanceColorAppearance; - } + value : PerInstanceColorAppearance }, /** * Gets the type of Appearance to use for material-based geometry. @@ -123,9 +121,7 @@ define(['../Core/Cartesian3', * @type {Appearance} */ materialAppearanceType : { - get : function() { - return MaterialAppearance; - } + value : MaterialAppearance } }); @@ -226,9 +222,7 @@ define(['../Core/Cartesian3', * @type {Boolean} */ isClosed : { - get : function() { - return true; - } + value : true }, /** * Gets an event that is raised whenever the public properties @@ -299,7 +293,7 @@ define(['../Core/Cartesian3', var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); if (this._materialProperty instanceof ColorMaterialProperty) { var currentColor = Color.WHITE; - if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { currentColor = this._materialProperty.color.getValue(time); } color = ColorGeometryInstanceAttribute.fromColor(currentColor); diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 756f3a735440..7c96d28ae13c 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -1,28 +1,26 @@ /*global define*/ -define(['../Core/defined', +define(['../Core/AssociativeArray', + '../Core/defined', '../Core/DeveloperError', '../Core/destroyObject', - '../Core/AssociativeArray', '../Scene/PerInstanceColorAppearance', '../Scene/PolylineColorAppearance', '../Scene/MaterialAppearance', '../Scene/PolylineMaterialAppearance', './ColorMaterialProperty', - './DynamicObjectCollection', './StaticGeometryColorBatch', './StaticGeometryPerMaterialBatch', './StaticOutlineGeometryBatch' ], function( + AssociativeArray, defined, DeveloperError, destroyObject, - AssociativeArray, PerInstanceColorAppearance, PolylineColorAppearance, MaterialAppearance, PolylineMaterialAppearance, ColorMaterialProperty, - DynamicObjectCollection, StaticGeometryColorBatch, StaticGeometryPerMaterialBatch, StaticOutlineGeometryBatch) { @@ -88,9 +86,9 @@ define(['../Core/defined', this._scene = scene; this._primitives = primitives; this._dynamicObjectCollection = undefined; - this._addedObjects = new DynamicObjectCollection(); - this._removedObjects = new DynamicObjectCollection(); - this._changedObjects = new DynamicObjectCollection(); + this._addedObjects = new AssociativeArray(); + this._removedObjects = new AssociativeArray(); + this._changedObjects = new AssociativeArray(); this._outlineBatch = new StaticOutlineGeometryBatch(primitives); this._closedColorBatch = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, true); @@ -196,11 +194,11 @@ define(['../Core/defined', } var addedObjects = this._addedObjects; - var added = addedObjects.getObjects(); + var added = addedObjects.values; var removedObjects = this._removedObjects; - var removed = removedObjects.getObjects(); + var removed = removedObjects.values; var changedObjects = this._changedObjects; - var changed = changedObjects.getObjects(); + var changed = changedObjects.values; var i; var g; @@ -226,7 +224,7 @@ define(['../Core/defined', updater = new this._type(dynamicObject, this._scene); this._updaters.set(id, updater); insertUpdaterIntoBatch(this, time, updater); - this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometyChanged, this)); + this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometryChanged, this)); } for (i = changed.length - 1; i > -1; i--) { @@ -304,15 +302,15 @@ define(['../Core/defined', /** * @private */ - GeometryVisualizer._onGeometyChanged = function(updater) { + GeometryVisualizer._onGeometryChanged = function(updater) { var removedObjects = this._removedObjects; var changedObjects = this._changedObjects; var dynamicObject = updater.dynamicObject; var id = dynamicObject.id; - if (!defined(removedObjects.getById(id)) && !defined(this._changedObjects.getById(id))) { - this._changedObjects.add(dynamicObject); + if (!defined(removedObjects.get(id)) && !defined(this._changedObjects.get(id))) { + this._changedObjects.set(id, dynamicObject); } }; @@ -325,21 +323,24 @@ define(['../Core/defined', var changedObjects = this._changedObjects; var i; + var id; var dynamicObject; for (i = removed.length - 1; i > -1; i--) { dynamicObject = removed[i]; - if (!addedObjects.remove(dynamicObject)) { - removedObjects.add(dynamicObject); - changedObjects.remove(dynamicObject); + id = dynamicObject.id; + if (!addedObjects.remove(id)) { + removedObjects.set(id, dynamicObject); + changedObjects.remove(id); } } for (i = added.length - 1; i > -1; i--) { dynamicObject = added[i]; - if (removedObjects.remove(dynamicObject)) { - changedObjects.add(dynamicObject); + id = dynamicObject.id; + if (removedObjects.remove(id)) { + changedObjects.set(id, dynamicObject); } else { - addedObjects.add(dynamicObject); + addedObjects.set(id, dynamicObject); } } }; diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index 7575a835103d..ee7bbcbb0a9b 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -97,9 +97,7 @@ define(['../Core/Color', * @type {Appearance} */ perInstanceColorAppearanceType : { - get : function() { - return PerInstanceColorAppearance; - } + value : PerInstanceColorAppearance }, /** * Gets the type of Appearance to use for material-based geometry. @@ -107,9 +105,7 @@ define(['../Core/Color', * @type {Appearance} */ materialAppearanceType : { - get : function() { - return MaterialAppearance; - } + value : MaterialAppearance } }); @@ -283,7 +279,7 @@ define(['../Core/Color', var show = new ShowGeometryInstanceAttribute(isAvailable && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); if (this._materialProperty instanceof ColorMaterialProperty) { var currentColor = Color.WHITE; - if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { currentColor = this._materialProperty.color.getValue(time); } color = ColorGeometryInstanceAttribute.fromColor(currentColor); diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index c2c7cb54592a..8636fbcf096b 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -81,9 +81,7 @@ define(['../Core/Color', * @type {Appearance} */ perInstanceColorAppearanceType : { - get : function() { - return PolylineColorAppearance; - } + value : PolylineColorAppearance }, /** * Gets the type of Appearance to use for material-based geometry. @@ -91,9 +89,7 @@ define(['../Core/Color', * @type {Appearance} */ materialAppearanceType : { - get : function() { - return PolylineMaterialAppearance; - } + value : PolylineMaterialAppearance } }); @@ -146,9 +142,7 @@ define(['../Core/Color', * @type {Boolean} */ outlineEnabled : { - get : function() { - return false; - } + value : false }, /** * Gets a value indicating if outline visibility varies with simulation time. @@ -156,9 +150,7 @@ define(['../Core/Color', * @type {Boolean} */ hasConstantOutline : { - get : function() { - return true; - } + value : true }, /** * Gets the {@link Color} property for the geometry outline. @@ -166,9 +158,7 @@ define(['../Core/Color', * @type {Property} */ outlineColorProperty : { - get : function() { - return undefined; - } + value : undefined }, /** * Gets a value indicating if the geometry is time-varying. @@ -190,9 +180,7 @@ define(['../Core/Color', * @type {Boolean} */ isClosed : { - get : function() { - return false; - } + value : false }, /** * Gets an event that is raised whenever the public properties @@ -261,7 +249,7 @@ define(['../Core/Color', if (this._materialProperty instanceof ColorMaterialProperty) { var currentColor = Color.WHITE; - if (defined(defined(this._materialProperty.color)) && (this._materialProperty.color.isConstant || isAvailable)) { + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { currentColor = this._materialProperty.color.getValue(time); } color = ColorGeometryInstanceAttribute.fromColor(currentColor); From f5b01a97f1e664fa5e06d54e6316c6c9f0f2146a Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 15:32:25 -0500 Subject: [PATCH 74/81] Extract out Property.isConstant helper function. --- Source/DynamicScene/ColorMaterialProperty.js | 2 +- Source/DynamicScene/EllipseGeometryUpdater.js | 22 ++++++++++--------- .../DynamicScene/EllipsoidGeometryUpdater.js | 16 ++++++++------ Source/DynamicScene/GridMaterialProperty.js | 8 +++---- Source/DynamicScene/ImageMaterialProperty.js | 2 +- Source/DynamicScene/PolygonGeometryUpdater.js | 20 +++++++++-------- .../DynamicScene/PolylineGeometryUpdater.js | 8 +++---- .../PolylineOutlineMaterialProperty.js | 4 +--- Source/DynamicScene/PositionPropertyArray.js | 3 +-- Source/DynamicScene/Property.js | 7 ++++++ Source/DynamicScene/PropertyArray.js | 6 ++--- Source/DynamicScene/ReferenceProperty.js | 9 ++++---- 12 files changed, 58 insertions(+), 49 deletions(-) diff --git a/Source/DynamicScene/ColorMaterialProperty.js b/Source/DynamicScene/ColorMaterialProperty.js index 2353e807abb8..facf3c9dd69d 100644 --- a/Source/DynamicScene/ColorMaterialProperty.js +++ b/Source/DynamicScene/ColorMaterialProperty.js @@ -59,7 +59,7 @@ define(['../Core/Color', */ isConstant : { get : function() { - return !defined(this._color) || this._color.isConstant; + return Property.isConstant(this._color); } }, /** diff --git a/Source/DynamicScene/EllipseGeometryUpdater.js b/Source/DynamicScene/EllipseGeometryUpdater.js index e50e10b73200..4473adcb319e 100644 --- a/Source/DynamicScene/EllipseGeometryUpdater.js +++ b/Source/DynamicScene/EllipseGeometryUpdater.js @@ -15,6 +15,7 @@ define(['../Core/Color', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', '../DynamicScene/MaterialProperty', + '../DynamicScene/Property', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive' @@ -35,6 +36,7 @@ define(['../Core/Color', ColorMaterialProperty, ConstantProperty, MaterialProperty, + Property, MaterialAppearance, PerInstanceColorAppearance, Primitive) { @@ -140,8 +142,8 @@ define(['../Core/Color', get : function() { return !this._fillEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._fillProperty) || this._fillProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, /** @@ -173,8 +175,8 @@ define(['../Core/Color', get : function() { return !this._outlineEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, /** @@ -429,12 +431,12 @@ define(['../Core/Color', if (!position.isConstant || // !semiMajorAxis.isConstant || // !semiMinorAxis.isConstant || // - defined(rotation) && !rotation.isConstant || // - defined(height) && !height.isConstant || // - defined(extrudedHeight) && !extrudedHeight.isConstant || // - defined(granularity) && !granularity.isConstant || // - defined(stRotation) && !stRotation.isConstant || // - defined(numberOfVerticalLines) && !numberOfVerticalLines.isConstant) { + !Property.isConstant(rotation) || // + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(stRotation) || // + !Property.isConstant(numberOfVerticalLines)) { if (!this._dynamic) { this._dynamic = true; this._geometryChanged.raiseEvent(this); diff --git a/Source/DynamicScene/EllipsoidGeometryUpdater.js b/Source/DynamicScene/EllipsoidGeometryUpdater.js index 7f1bbd7de815..5b4e7378786c 100644 --- a/Source/DynamicScene/EllipsoidGeometryUpdater.js +++ b/Source/DynamicScene/EllipsoidGeometryUpdater.js @@ -18,6 +18,7 @@ define(['../Core/Cartesian3', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', '../DynamicScene/MaterialProperty', + '../DynamicScene/Property', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive', @@ -43,6 +44,7 @@ define(['../Core/Cartesian3', ColorMaterialProperty, ConstantProperty, MaterialProperty, + Property, MaterialAppearance, PerInstanceColorAppearance, Primitive, @@ -155,8 +157,8 @@ define(['../Core/Cartesian3', get : function() { return !this._fillEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._fillProperty) || this._fillProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, /** @@ -188,8 +190,8 @@ define(['../Core/Cartesian3', get : function() { return !this._outlineEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, /** @@ -447,9 +449,9 @@ define(['../Core/Cartesian3', if (!position.isConstant || // !orientation.isConstant || // !radii.isConstant || // - defined(stackPartitions) && !stackPartitions.isConstant || // - defined(slicePartitions) && !slicePartitions.isConstant || // - defined(subdivisions) && !subdivisions.isConstant) { + !Property.isConstant(stackPartitions) || // + !Property.isConstant(slicePartitions) || // + !Property.isConstant(subdivisions)) { if (!this._dynamic) { this._dynamic = true; this._geometryChanged.raiseEvent(this); diff --git a/Source/DynamicScene/GridMaterialProperty.js b/Source/DynamicScene/GridMaterialProperty.js index 6f1e9728675e..58c2441d48f7 100644 --- a/Source/DynamicScene/GridMaterialProperty.js +++ b/Source/DynamicScene/GridMaterialProperty.js @@ -49,10 +49,10 @@ define(['../Core/Cartesian2', */ isConstant : { get : function() { - return (!defined(this._color) || this._color.isConstant) && // - (!defined(this._cellAlpha) || this._cellAlpha.isConstant) && // - (!defined(this._lineCount) || this._lineCount.isConstant) && // - (!defined(this._lineThickness) || this._lineThickness.isConstant); + return Property.isConstant(this._color) && + Property.isConstant(this._cellAlpha) && + Property.isConstant(this._lineCount) && + Property.isConstant(this._lineThickness); } }, /** diff --git a/Source/DynamicScene/ImageMaterialProperty.js b/Source/DynamicScene/ImageMaterialProperty.js index f2109ab2377f..f795fdda8c4a 100644 --- a/Source/DynamicScene/ImageMaterialProperty.js +++ b/Source/DynamicScene/ImageMaterialProperty.js @@ -40,7 +40,7 @@ define([ */ isConstant : { get : function() { - return (!defined(this._image) || this._image.isConstant) && (!defined(this._repeat) || this._repeat.isConstant); + return Property.isConstant(this._image) && Property.isConstant(this._repeat); } }, /** diff --git a/Source/DynamicScene/PolygonGeometryUpdater.js b/Source/DynamicScene/PolygonGeometryUpdater.js index ee7bbcbb0a9b..d95d410c6615 100644 --- a/Source/DynamicScene/PolygonGeometryUpdater.js +++ b/Source/DynamicScene/PolygonGeometryUpdater.js @@ -15,6 +15,7 @@ define(['../Core/Color', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', '../DynamicScene/MaterialProperty', + '../DynamicScene/Property', '../Scene/MaterialAppearance', '../Scene/PerInstanceColorAppearance', '../Scene/Primitive' @@ -35,6 +36,7 @@ define(['../Core/Color', ColorMaterialProperty, ConstantProperty, MaterialProperty, + Property, MaterialAppearance, PerInstanceColorAppearance, Primitive) { @@ -139,8 +141,8 @@ define(['../Core/Color', get : function() { return !this._fillEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._fillProperty) || this._fillProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, /** @@ -172,8 +174,8 @@ define(['../Core/Color', get : function() { return !this._outlineEnabled || (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant) && - (!defined(this._showOutlineProperty) || this._showOutlineProperty.isConstant)); + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, /** @@ -423,11 +425,11 @@ define(['../Core/Color', this._outlineEnabled = outlineEnabled; if (!vertexPositions.isConstant || // - defined(height) && !height.isConstant || // - defined(extrudedHeight) && !extrudedHeight.isConstant || // - defined(granularity) && !granularity.isConstant || // - defined(stRotation) && !stRotation.isConstant || // - defined(perPositionHeight) && !perPositionHeight.isConstant) { + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(stRotation) || // + !Property.isConstant(perPositionHeight)) { if (!this._dynamic) { this._dynamic = true; this._geometryChanged.raiseEvent(this); diff --git a/Source/DynamicScene/PolylineGeometryUpdater.js b/Source/DynamicScene/PolylineGeometryUpdater.js index 8636fbcf096b..ab6b0c3c88ad 100644 --- a/Source/DynamicScene/PolylineGeometryUpdater.js +++ b/Source/DynamicScene/PolylineGeometryUpdater.js @@ -14,6 +14,7 @@ define(['../Core/Color', '../DynamicScene/ColorMaterialProperty', '../DynamicScene/ConstantProperty', '../DynamicScene/MaterialProperty', + '../DynamicScene/Property', '../Scene/PolylineMaterialAppearance', '../Scene/PolylineColorAppearance', '../Scene/Primitive' @@ -33,6 +34,7 @@ define(['../Core/Color', ColorMaterialProperty, ConstantProperty, MaterialProperty, + Property, PolylineMaterialAppearance, PolylineColorAppearance, Primitive) { @@ -121,9 +123,7 @@ define(['../Core/Color', */ hasConstantFill : { get : function() { - return !this._fillEnabled || - (!defined(this._dynamicObject.availability) && - (!defined(this._showProperty) || this._showProperty.isConstant)); + return !this._fillEnabled || (!defined(this._dynamicObject.availability) && Property.isConstant(this._showProperty)); } }, /** @@ -344,7 +344,7 @@ define(['../Core/Color', var width = polyline.width; - if (!vertexPositions.isConstant || (defined(width) && !width.isConstant)) { + if (!vertexPositions.isConstant || !Property.isConstant(width)) { if (!this._dynamic) { this._dynamic = true; this._geometryChanged.raiseEvent(this); diff --git a/Source/DynamicScene/PolylineOutlineMaterialProperty.js b/Source/DynamicScene/PolylineOutlineMaterialProperty.js index a80225b7811d..b495aa4fe7bb 100644 --- a/Source/DynamicScene/PolylineOutlineMaterialProperty.js +++ b/Source/DynamicScene/PolylineOutlineMaterialProperty.js @@ -43,9 +43,7 @@ define(['../Core/Color', */ isConstant : { get : function() { - return (!defined(this._color) || this._color.isConstant) && - (!defined(this._outlineColor) || this._outlineColor.isConstant) && - (!defined(this._outlineWidth) || this._outlineWidth.isConstant); + return Property.isConstant(this._color) && Property.isConstant(this._outlineColor) && Property.isConstant(this._outlineWidth); } }, /** diff --git a/Source/DynamicScene/PositionPropertyArray.js b/Source/DynamicScene/PositionPropertyArray.js index c9fcaa5604ed..6eb1c30c59b9 100644 --- a/Source/DynamicScene/PositionPropertyArray.js +++ b/Source/DynamicScene/PositionPropertyArray.js @@ -50,8 +50,7 @@ define(['../Core/defaultValue', var length = this._length; var value = this._value; for (var i = 0; i < length; i++) { - var property = value[i]; - if (defined(property) && !property.isConstant) { + if (!Property.isConstant(value[i])) { return false; } } diff --git a/Source/DynamicScene/Property.js b/Source/DynamicScene/Property.js index 620be17a5bd2..42987206adbc 100644 --- a/Source/DynamicScene/Property.js +++ b/Source/DynamicScene/Property.js @@ -90,5 +90,12 @@ define(['../Core/defined', return true; }; + /** + * @private + */ + Property.isConstant = function(property) { + return !defined(property) || property.isConstant; + }; + return Property; }); diff --git a/Source/DynamicScene/PropertyArray.js b/Source/DynamicScene/PropertyArray.js index df9548f42eec..1f85036441f8 100644 --- a/Source/DynamicScene/PropertyArray.js +++ b/Source/DynamicScene/PropertyArray.js @@ -47,11 +47,9 @@ define(['../Core/defaultValue', var length = this._length; var value = this._value; for (var i = 0; i < length; i++) { - var property = value[i]; - if (defined(property) && !property.isConstant) { + if (!Property.isConstant(value[i])) { return false; - } - } + } } return true; } }, diff --git a/Source/DynamicScene/ReferenceProperty.js b/Source/DynamicScene/ReferenceProperty.js index 09130b02304c..719ff883a3fa 100644 --- a/Source/DynamicScene/ReferenceProperty.js +++ b/Source/DynamicScene/ReferenceProperty.js @@ -4,13 +4,15 @@ define([ '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Event' + '../Core/Event', + '../DynamicScene/Property' ], function( defaultValue, defined, defineProperties, DeveloperError, - Event) { + Event, + Property) { "use strict"; function resolve(referenceProperty) { @@ -67,8 +69,7 @@ define([ */ isConstant : { get : function() { - var targetProperty = resolve(this); - return !defined(targetProperty) || targetProperty.isConstant; + return Property.isConstant(resolve(this)); } }, /** From e05b0ec4f4d05b4ea36cfd85b47e7efb56f7dbbe Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 15:45:03 -0500 Subject: [PATCH 75/81] Clean up PropertyArray & PositionPropertyArray. --- Source/DynamicScene/PositionPropertyArray.js | 27 ++++++++++--------- Source/DynamicScene/Property.js | 6 +++++ Source/DynamicScene/PropertyArray.js | 25 ++++++++--------- .../DynamicScene/PositionPropertyArraySepc.js | 4 +++ Specs/DynamicScene/PropertyArraySpec.js | 4 +++ 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/Source/DynamicScene/PositionPropertyArray.js b/Source/DynamicScene/PositionPropertyArray.js index 6eb1c30c59b9..897386139ee6 100644 --- a/Source/DynamicScene/PositionPropertyArray.js +++ b/Source/DynamicScene/PositionPropertyArray.js @@ -31,7 +31,6 @@ define(['../Core/defaultValue', */ var PositionPropertyArray = function(value, referenceFrame) { this._value = undefined; - this._length = 0; this._definitionChanged = new Event(); this._eventHelper = new EventHelper(); this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); @@ -47,8 +46,12 @@ define(['../Core/defaultValue', */ isConstant : { get : function() { - var length = this._length; var value = this._value; + if (!defined(value)) { + return true; + } + + var length = value.length; for (var i = 0; i < length; i++) { if (!Property.isConstant(value[i])) { return false; @@ -113,21 +116,22 @@ define(['../Core/defaultValue', } //>>includeEnd('debug'); - if (!defined(this._value)) { + var value = this._value; + if (!defined(value)) { return undefined; } - var length = this._length; + var length = value.length; if (!defined(result)) { result = new Array(length); } var i = 0; var x = 0; while (i < length) { - var property = this._value[i]; - var value = property.getValueInReferenceFrame(time, referenceFrame, result[i]); - if (defined(value)) { - result[x] = value; + var property = value[i]; + var itemValue = property.getValueInReferenceFrame(time, referenceFrame, result[i]); + if (defined(itemValue)) { + result[x] = itemValue; x++; } i++; @@ -150,8 +154,6 @@ define(['../Core/defaultValue', if (defined(value)) { this._value = value.slice(); var length = value.length; - this._length = length; - for (var i = 0; i < length; i++) { var property = value[i]; if (defined(property)) { @@ -160,7 +162,6 @@ define(['../Core/defaultValue', } } else { this._value = undefined; - this._length = 0; } this._definitionChanged.raiseEvent(this); }; @@ -176,8 +177,8 @@ define(['../Core/defaultValue', PositionPropertyArray.prototype.equals = function(other) { return this === other || // (other instanceof PositionPropertyArray && // - this._referenceFrame === other._referenceFrame && - (this._length === other._length && Property.arrayEquals(this._value, other._value))); + this._referenceFrame === other._referenceFrame && // + Property.arrayEquals(this._value, other._value)); }; PositionPropertyArray.prototype._raiseDefinitionChanged = function() { diff --git a/Source/DynamicScene/Property.js b/Source/DynamicScene/Property.js index 42987206adbc..8befdb972010 100644 --- a/Source/DynamicScene/Property.js +++ b/Source/DynamicScene/Property.js @@ -81,6 +81,12 @@ define(['../Core/defined', * @private */ Property.arrayEquals = function(left, right) { + if (left === right) { + return true; + } + if ((!defined(left) || !defined(right)) || (left.length !== right.length)) { + return false; + } var length = left.length; for (var i = 0; i < length; i++) { if (!Property.equals(left[i], right[i])) { diff --git a/Source/DynamicScene/PropertyArray.js b/Source/DynamicScene/PropertyArray.js index 1f85036441f8..04356d557c99 100644 --- a/Source/DynamicScene/PropertyArray.js +++ b/Source/DynamicScene/PropertyArray.js @@ -29,7 +29,6 @@ define(['../Core/defaultValue', */ var PropertyArray = function(value) { this._value = undefined; - this._length = 0; this._definitionChanged = new Event(); this._eventHelper = new EventHelper(); this.setValue(value); @@ -44,12 +43,16 @@ define(['../Core/defaultValue', */ isConstant : { get : function() { - var length = this._length; var value = this._value; + if (!defined(value)) { + return true; + } + var length = value.length; for (var i = 0; i < length; i++) { if (!Property.isConstant(value[i])) { return false; - } } + } + } return true; } }, @@ -82,11 +85,12 @@ define(['../Core/defaultValue', } //>>includeEnd('debug'); - if (!defined(this._value)) { + var value = this._value; + if (!defined(value)) { return undefined; } - var length = this._length; + var length = value.length; if (!defined(result)) { result = new Array(length); } @@ -94,9 +98,9 @@ define(['../Core/defaultValue', var x = 0; while (i < length) { var property = this._value[i]; - var value = property.getValue(time, result[i]); - if (defined(value)) { - result[x] = value; + var itemValue = property.getValue(time, result[i]); + if (defined(itemValue)) { + result[x] = itemValue; x++; } i++; @@ -118,8 +122,6 @@ define(['../Core/defaultValue', if (defined(value)) { this._value = value.slice(); var length = value.length; - this._length = length; - for (var i = 0; i < length; i++) { var property = value[i]; if (defined(property)) { @@ -128,7 +130,6 @@ define(['../Core/defaultValue', } } else { this._value = undefined; - this._length = 0; } this._definitionChanged.raiseEvent(this); }; @@ -144,7 +145,7 @@ define(['../Core/defaultValue', PropertyArray.prototype.equals = function(other) { return this === other || // (other instanceof PropertyArray && // - (this._length === other._length && Property.arrayEquals(this._value, other._value))); + Property.arrayEquals(this._value, other._value)); }; PropertyArray.prototype._raiseDefinitionChanged = function() { diff --git a/Specs/DynamicScene/PositionPropertyArraySepc.js b/Specs/DynamicScene/PositionPropertyArraySepc.js index 39d6ec1ca810..add65f0fe671 100644 --- a/Specs/DynamicScene/PositionPropertyArraySepc.js +++ b/Specs/DynamicScene/PositionPropertyArraySepc.js @@ -92,6 +92,10 @@ defineSuite(['DynamicScene/PositionPropertyArray', right = new PositionPropertyArray([new ConstantPositionProperty(Cartesian3.UNIT_Z)]); expect(left.equals(right)).toEqual(false); + + left = new PositionPropertyArray(); + right = new PositionPropertyArray(); + expect(left.equals(right)).toEqual(true); }); it('isConstant is true only if all members are constant', function() { diff --git a/Specs/DynamicScene/PropertyArraySpec.js b/Specs/DynamicScene/PropertyArraySpec.js index f880f56b55df..230eeaae515d 100644 --- a/Specs/DynamicScene/PropertyArraySpec.js +++ b/Specs/DynamicScene/PropertyArraySpec.js @@ -82,6 +82,10 @@ defineSuite(['DynamicScene/PropertyArray', right = new PropertyArray([new ConstantProperty(2)]); expect(left.equals(right)).toEqual(false); + + left = new PropertyArray(); + right = new PropertyArray(); + expect(left.equals(right)).toEqual(true); }); it('isConstant is true only if all members are constant', function() { From 603484e2c7649283ec964b014d48ecd50e288bbe Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 15:49:43 -0500 Subject: [PATCH 76/81] Fix bad logic due to copy/paste error. --- Source/DynamicScene/StaticGeometryColorBatch.js | 3 +-- Source/DynamicScene/StaticGeometryPerMaterialBatch.js | 2 +- Source/DynamicScene/StaticOutlineGeometryBatch.js | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/DynamicScene/StaticGeometryColorBatch.js b/Source/DynamicScene/StaticGeometryColorBatch.js index 719ac9586057..d05b942410a9 100644 --- a/Source/DynamicScene/StaticGeometryColorBatch.js +++ b/Source/DynamicScene/StaticGeometryColorBatch.js @@ -159,7 +159,6 @@ define(['../Core/Color', itemsToRemove = this._translucentBatch.itemsToRemove; var translucentToMoveLength = itemsToRemove.length; - var removedTranslucentLength = itemsToRemove.length; if (translucentToMoveLength > 0) { for (i = 0; i < translucentToMoveLength; i++) { updater = itemsToRemove[i]; @@ -169,7 +168,7 @@ define(['../Core/Color', } //If we moved anything around, we need to re-build the primitive - if (translucentToMoveLength > 0 || removedTranslucentLength > 0) { + if (solidsToMoveLength > 0 || translucentToMoveLength > 0) { this._solidBatch.update(time); this._translucentBatch.update(time); } diff --git a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js index 69cb75538263..d3503d939ea2 100644 --- a/Source/DynamicScene/StaticGeometryPerMaterialBatch.js +++ b/Source/DynamicScene/StaticGeometryPerMaterialBatch.js @@ -190,7 +190,7 @@ define(['../Core/defined', for (var i = 0; i < length; i++) { items[i].destroy(); } - this._items = []; + this._items.length = 0; }; return StaticGeometryPerMaterialBatch; diff --git a/Source/DynamicScene/StaticOutlineGeometryBatch.js b/Source/DynamicScene/StaticOutlineGeometryBatch.js index 66628217511f..f518406a75e4 100644 --- a/Source/DynamicScene/StaticOutlineGeometryBatch.js +++ b/Source/DynamicScene/StaticOutlineGeometryBatch.js @@ -153,7 +153,6 @@ define(['../Core/Color', itemsToRemove = this._translucentBatch.itemsToRemove; var translucentToMoveLength = itemsToRemove.length; - var removedTranslucentLength = itemsToRemove.length; if (translucentToMoveLength > 0) { for (i = 0; i < translucentToMoveLength; i++) { updater = itemsToRemove[i]; @@ -163,7 +162,7 @@ define(['../Core/Color', } //If we moved anything around, we need to re-build the primitive - if (translucentToMoveLength > 0 || removedTranslucentLength > 0) { + if (solidsToMoveLength > 0 || translucentToMoveLength > 0) { this._solidBatch.update(time); this._translucentBatch.update(time); } From 09eafb0566b26ac1d63b25bf43dae805f2f2a701 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 15:59:33 -0500 Subject: [PATCH 77/81] Fix filename typo. Remove dead code. --- ...yArraySepc.js => PositionPropertyArraySpec.js} | 0 Specs/UndefinedProperty.js | 15 --------------- 2 files changed, 15 deletions(-) rename Specs/DynamicScene/{PositionPropertyArraySepc.js => PositionPropertyArraySpec.js} (100%) delete mode 100644 Specs/UndefinedProperty.js diff --git a/Specs/DynamicScene/PositionPropertyArraySepc.js b/Specs/DynamicScene/PositionPropertyArraySpec.js similarity index 100% rename from Specs/DynamicScene/PositionPropertyArraySepc.js rename to Specs/DynamicScene/PositionPropertyArraySpec.js diff --git a/Specs/UndefinedProperty.js b/Specs/UndefinedProperty.js deleted file mode 100644 index 2a525029962d..000000000000 --- a/Specs/UndefinedProperty.js +++ /dev/null @@ -1,15 +0,0 @@ -/*global define*/ -define(['../Core/defineProperties'], function(defineProperties) { - "use strict"; - - //A Property that always returns undefined. - - var UndefinedProperty = function() { - }; - - UndefinedProperty.prototype.getValue = function(time, result) { - return undefined; - }; - - return UndefinedProperty; -}); From d350459d4e5fdec45f213adab5bbc718b11964e1 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 17:20:48 -0500 Subject: [PATCH 78/81] Add isArray shim --- Source/Core/LeapSecond.js | 8 +++--- Source/Core/PolylinePipeline.js | 4 ++- Source/Core/isArray.js | 25 +++++++++++++++++++ Source/DynamicScene/ConstantProperty.js | 8 +++--- Source/DynamicScene/CzmlDataSource.js | 12 +++++---- .../TimeIntervalCollectionProperty.js | 4 ++- Source/Scene/Material.js | 4 ++- Source/Scene/Primitive.js | 10 +++++--- Source/Scene/ScreenSpaceCameraController.js | 4 ++- .../BaseLayerPickerViewModel.js | 6 +++-- 10 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 Source/Core/isArray.js diff --git a/Source/Core/LeapSecond.js b/Source/Core/LeapSecond.js index 2794c51565f1..0c5363892b5a 100644 --- a/Source/Core/LeapSecond.js +++ b/Source/Core/LeapSecond.js @@ -1,10 +1,12 @@ /*global define*/ define([ './defined', - './DeveloperError' + './DeveloperError', + './isArray' ], function( defined, - DeveloperError) { + DeveloperError, + isArray) { "use strict"; /** @@ -77,7 +79,7 @@ define([ */ LeapSecond.setLeapSeconds = function(leapSeconds) { //>>includeStart('debug', pragmas.debug); - if (!Array.isArray(leapSeconds)) { + if (!isArray(leapSeconds)) { throw new DeveloperError("leapSeconds is required and must be an array."); } //>>includeEnd('debug'); diff --git a/Source/Core/PolylinePipeline.js b/Source/Core/PolylinePipeline.js index 55eb5a629ee6..1a1d9093aed3 100644 --- a/Source/Core/PolylinePipeline.js +++ b/Source/Core/PolylinePipeline.js @@ -9,6 +9,7 @@ define([ './Ellipsoid', './EllipsoidGeodesic', './IntersectionTests', + './isArray', './Math', './Matrix4', './Plane' @@ -22,6 +23,7 @@ define([ Ellipsoid, EllipsoidGeodesic, IntersectionTests, + isArray, CesiumMath, Matrix4, Plane) { @@ -326,7 +328,7 @@ define([ } var h; - if (Array.isArray(height)) { + if (isArray(height)) { if (height.length !== length/3) { throw new DeveloperError('height.length must be equal to positions.length'); } diff --git a/Source/Core/isArray.js b/Source/Core/isArray.js new file mode 100644 index 000000000000..a84a7363c528 --- /dev/null +++ b/Source/Core/isArray.js @@ -0,0 +1,25 @@ +/*global define,performance*/ +define(['./defined' + ], function( + defined) { + "use strict"; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray; + + if (defined(Array.isArray)) { + isArray = Array.isArray; + } else { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); \ No newline at end of file diff --git a/Source/DynamicScene/ConstantProperty.js b/Source/DynamicScene/ConstantProperty.js index 55ebc06cb3e9..2001e4b3459b 100644 --- a/Source/DynamicScene/ConstantProperty.js +++ b/Source/DynamicScene/ConstantProperty.js @@ -4,14 +4,16 @@ define(['../Core/defaultValue', '../Core/defineProperties', '../Core/DeveloperError', '../Core/Enumeration', - '../Core/Event' + '../Core/Event', + '../Core/isArray' ], function( defaultValue, defined, defineProperties, DeveloperError, Enumeration, - Event) { + Event, + isArray) { "use strict"; /** @@ -85,7 +87,7 @@ define(['../Core/defaultValue', var oldValue = this._value; var simple = this._simple; if ((simple && oldValue !== value) || (!simple && !oldValue.equals(value))) { - simple = typeof value !== 'object' || Array.isArray(value) || value instanceof Enumeration; + simple = typeof value !== 'object' || isArray(value) || value instanceof Enumeration; //>>includeStart('debug', pragmas.debug); if (!simple) { diff --git a/Source/DynamicScene/CzmlDataSource.js b/Source/DynamicScene/CzmlDataSource.js index 2457f3c6e4b3..7a62920f0494 100644 --- a/Source/DynamicScene/CzmlDataSource.js +++ b/Source/DynamicScene/CzmlDataSource.js @@ -14,6 +14,7 @@ define(['../Core/Cartesian2', '../Core/Event', '../Core/getFilenameFromUri', '../Core/HermitePolynomialApproximation', + '../Core/isArray', '../Core/Iso8601', '../Core/JulianDate', '../Core/LagrangePolynomialApproximation', @@ -77,6 +78,7 @@ define(['../Core/Cartesian2', Event, getFilenameFromUri, HermitePolynomialApproximation, + isArray, Iso8601, JulianDate, LagrangePolynomialApproximation, @@ -522,7 +524,7 @@ define(['../Core/Cartesian2', return; } - if (Array.isArray(packetData)) { + if (isArray(packetData)) { for (var i = 0, len = packetData.length; i < len; i++) { processProperty(type, object, propertyName, packetData[i], interval, sourceUri); } @@ -664,7 +666,7 @@ define(['../Core/Cartesian2', return; } - if (Array.isArray(packetData)) { + if (isArray(packetData)) { for (var i = 0, len = packetData.length; i < len; i++) { processPositionProperty(object, propertyName, packetData[i], interval, sourceUri); } @@ -747,7 +749,7 @@ define(['../Core/Cartesian2', return; } - if (Array.isArray(packetData)) { + if (isArray(packetData)) { for (var i = 0, len = packetData.length; i < len; i++) { processMaterialProperty(object, propertyName, packetData[i], interval, sourceUri); } @@ -853,7 +855,7 @@ define(['../Core/Cartesian2', } var intervals; - if (Array.isArray(packetData)) { + if (isArray(packetData)) { var length = packetData.length; for (var i = 0; i < length; i++) { if (!defined(intervals)) { @@ -1568,7 +1570,7 @@ define(['../Core/Cartesian2', CzmlDataSource._processCzml = function(czml, dynamicObjectCollection, sourceUri, updaterFunctions, dataSource) { updaterFunctions = defined(updaterFunctions) ? updaterFunctions : CzmlDataSource.updaters; - if (Array.isArray(czml)) { + if (isArray(czml)) { for (var i = 0, len = czml.length; i < len; i++) { processCzmlPacket(czml[i], dynamicObjectCollection, updaterFunctions, sourceUri, dataSource); } diff --git a/Source/DynamicScene/TimeIntervalCollectionProperty.js b/Source/DynamicScene/TimeIntervalCollectionProperty.js index 92c6de5f0d90..e39bee689f11 100644 --- a/Source/DynamicScene/TimeIntervalCollectionProperty.js +++ b/Source/DynamicScene/TimeIntervalCollectionProperty.js @@ -5,6 +5,7 @@ define(['./Property', '../Core/DeveloperError', '../Core/Enumeration', '../Core/Event', + '../Core/isArray', '../Core/TimeIntervalCollection' ], function( Property, @@ -13,6 +14,7 @@ define(['./Property', DeveloperError, Enumeration, Event, + isArray, TimeIntervalCollection) { "use strict"; @@ -114,7 +116,7 @@ define(['./Property', //>>includeEnd('debug'); var value = this._intervals.findDataForIntervalContainingDate(time); - if (defined(value) && (typeof value === 'object' && !Array.isArray(value) && !(value instanceof Enumeration))) { + if (defined(value) && (typeof value === 'object' && !isArray(value) && !(value instanceof Enumeration))) { return value.clone(result); } return value; diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 87258f942c33..45bd534b2cc7 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -12,6 +12,7 @@ define([ '../Core/defineProperties', '../Core/destroyObject', '../Core/Cartesian2', + '../Core/isArray', '../Core/Matrix2', '../Core/Matrix3', '../Core/Matrix4', @@ -45,6 +46,7 @@ define([ defineProperties, destroyObject, Cartesian2, + isArray, Matrix2, Matrix3, Matrix4, @@ -867,7 +869,7 @@ define([ uniformType = 'sampler2D'; } } else if (type === 'object') { - if (Array.isArray(uniformValue)) { + if (isArray(uniformValue)) { if (uniformValue.length === 4 || uniformValue.length === 9 || uniformValue.length === 16) { uniformType = 'mat' + Math.sqrt(uniformValue.length); } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 203d14aebe5b..776b984ec3ec 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -16,6 +16,7 @@ define([ '../Core/TaskProcessor', '../Core/GeographicProjection', '../Core/clone', + '../Core/isArray', '../Renderer/BufferUsage', '../Renderer/VertexLayout', '../Renderer/DrawCommand', @@ -43,6 +44,7 @@ define([ TaskProcessor, GeographicProjection, clone, + isArray, BufferUsage, VertexLayout, DrawCommand, @@ -523,7 +525,7 @@ define([ Primitive.prototype.update = function(context, frameState, commandList) { if (!this.show || ((!defined(this.geometryInstances)) && (this._va.length === 0)) || - (defined(this.geometryInstances) && Array.isArray(this.geometryInstances) && this.geometryInstances.length === 0) || + (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length === 0) || (!defined(this.appearance)) || (frameState.mode !== SceneMode.SCENE3D && this.allow3DOnly) || (!frameState.passes.render && !frameState.passes.pick)) { @@ -554,7 +556,7 @@ define([ if (this._state === PrimitiveState.FAILED) { throw this._error; } else if (this._state === PrimitiveState.READY) { - instances = (Array.isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; + instances = (isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; length = instances.length; var promises = []; @@ -587,7 +589,7 @@ define([ that._state = PrimitiveState.FAILED; }); } else if (this._state === PrimitiveState.CREATED) { - instances = (Array.isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; + instances = (isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; clonedInstances = new Array(instances.length); geometries = this._geometries.concat(this._createdGeometries); @@ -633,7 +635,7 @@ define([ }); } } else { - instances = (Array.isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; + instances = (isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; length = instances.length; geometries = this._createdGeometries; diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index ae478d311a5f..3d20a1455547 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -11,6 +11,7 @@ define([ '../Core/KeyboardEventModifier', '../Core/FAR', '../Core/IntersectionTests', + '../Core/isArray', '../Core/Math', '../Core/Matrix4', '../Core/Ray', @@ -32,6 +33,7 @@ define([ KeyboardEventModifier, FAR, IntersectionTests, + isArray, CesiumMath, Matrix4, Ray, @@ -368,7 +370,7 @@ define([ var aggregator = controller._aggregator; - if (!Array.isArray(eventTypes)) { + if (!isArray(eventTypes)) { scratchEventTypeArray[0] = eventTypes; eventTypes = scratchEventTypeArray; } diff --git a/Source/Widgets/BaseLayerPicker/BaseLayerPickerViewModel.js b/Source/Widgets/BaseLayerPicker/BaseLayerPickerViewModel.js index bf6123b6b1bc..9ecc990bfd6f 100644 --- a/Source/Widgets/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/Source/Widgets/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -3,12 +3,14 @@ define([ '../../Core/defined', '../../Core/defineProperties', '../../Core/DeveloperError', + '../../Core/isArray', '../createCommand', '../../ThirdParty/knockout' ], function( defined, defineProperties, DeveloperError, + isArray, createCommand, knockout) { "use strict"; @@ -34,7 +36,7 @@ define([ if (!defined(imageryProviderViewModels)) { imageryProviderViewModels = []; - } else if (!Array.isArray(imageryProviderViewModels)) { + } else if (!isArray(imageryProviderViewModels)) { throw new DeveloperError('imageryProviderViewModels must be an array'); } @@ -108,7 +110,7 @@ define([ if (defined(value)) { var newProviders = value.creationCommand(); - if (Array.isArray(newProviders)) { + if (isArray(newProviders)) { var newProvidersLength = newProviders.length; for (i = newProvidersLength - 1; i >= 0; i--) { imageryLayers.addImageryProvider(newProviders[i], 0); From 40c9f855810749cd832dba195ad70a4bdbb4bab3 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 17:22:21 -0500 Subject: [PATCH 79/81] Minor tweak. --- Source/Core/isArray.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Core/isArray.js b/Source/Core/isArray.js index a84a7363c528..84918c13c27d 100644 --- a/Source/Core/isArray.js +++ b/Source/Core/isArray.js @@ -11,11 +11,8 @@ define(['./defined' * @param {Object} value The value to test. * @returns {Boolean} true if the value is an array, false otherwise. */ - var isArray; - - if (defined(Array.isArray)) { - isArray = Array.isArray; - } else { + var isArray = Array.isArray; + if (!defined(isArray)) { isArray = function(value) { return Object.prototype.toString.call(value) === '[object Array]'; }; From 1f64fde0a491d48c33d235862e2e5b59e3e340fc Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 20 Feb 2014 17:45:16 -0500 Subject: [PATCH 80/81] Fix globals. --- Source/Core/getTimestamp.js | 3 ++- Source/Core/isArray.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/getTimestamp.js b/Source/Core/getTimestamp.js index 3ab8d090ab30..58f51630983c 100644 --- a/Source/Core/getTimestamp.js +++ b/Source/Core/getTimestamp.js @@ -1,9 +1,10 @@ -/*global define,performance*/ +/*global define*/ define([ './defined' ], function( defined) { "use strict"; + /*global performance*/ /** * Gets a timestamp that can be used in measuring the time between events. Timestamps diff --git a/Source/Core/isArray.js b/Source/Core/isArray.js index 84918c13c27d..b5dc2dabd8fd 100644 --- a/Source/Core/isArray.js +++ b/Source/Core/isArray.js @@ -1,4 +1,4 @@ -/*global define,performance*/ +/*global define*/ define(['./defined' ], function( defined) { From f8e4f7037fe1e6243b1e4a5b6ff570332edaa41e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 21 Feb 2014 11:07:04 -0500 Subject: [PATCH 81/81] Add pragma, fix typos. --- Source/DynamicScene/DynamicBillboardVisualizer.js | 2 +- .../DynamicScene/DynamicConeVisualizerUsingCustomSensor.js | 2 +- Source/DynamicScene/DynamicLabelVisualizer.js | 2 +- Source/DynamicScene/DynamicPathVisualizer.js | 2 +- Source/DynamicScene/DynamicPointVisualizer.js | 2 +- Source/DynamicScene/DynamicPyramidVisualizer.js | 2 +- Source/DynamicScene/DynamicVectorVisualizer.js | 2 +- Source/DynamicScene/GeometryVisualizer.js | 5 ++++- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Source/DynamicScene/DynamicBillboardVisualizer.js b/Source/DynamicScene/DynamicBillboardVisualizer.js index 60535ce3cd45..e1b27ca10f43 100644 --- a/Source/DynamicScene/DynamicBillboardVisualizer.js +++ b/Source/DynamicScene/DynamicBillboardVisualizer.js @@ -124,7 +124,7 @@ define([ DynamicBillboardVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js index 20b4baff7bfe..2a090057f9b5 100644 --- a/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js +++ b/Source/DynamicScene/DynamicConeVisualizerUsingCustomSensor.js @@ -156,7 +156,7 @@ define([ DynamicConeVisualizerUsingCustomSensor.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicLabelVisualizer.js b/Source/DynamicScene/DynamicLabelVisualizer.js index c1bf340e3943..ea5edc73381c 100644 --- a/Source/DynamicScene/DynamicLabelVisualizer.js +++ b/Source/DynamicScene/DynamicLabelVisualizer.js @@ -105,7 +105,7 @@ define([ DynamicLabelVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index ab5e7bc80282..da5e77a16a09 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -456,7 +456,7 @@ define([ DynamicPathVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicPointVisualizer.js b/Source/DynamicScene/DynamicPointVisualizer.js index 3a6eb3554a8a..9e788032c3b2 100644 --- a/Source/DynamicScene/DynamicPointVisualizer.js +++ b/Source/DynamicScene/DynamicPointVisualizer.js @@ -101,7 +101,7 @@ define([ DynamicPointVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicPyramidVisualizer.js b/Source/DynamicScene/DynamicPyramidVisualizer.js index 9ec22059bc65..9890a7e7257d 100644 --- a/Source/DynamicScene/DynamicPyramidVisualizer.js +++ b/Source/DynamicScene/DynamicPyramidVisualizer.js @@ -108,7 +108,7 @@ define([ DynamicPyramidVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/DynamicVectorVisualizer.js b/Source/DynamicScene/DynamicVectorVisualizer.js index 85a895f59a0f..19eb8cf729a6 100644 --- a/Source/DynamicScene/DynamicVectorVisualizer.js +++ b/Source/DynamicScene/DynamicVectorVisualizer.js @@ -98,7 +98,7 @@ define([ DynamicVectorVisualizer.prototype.update = function(time) { //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } //>>includeEnd('debug'); diff --git a/Source/DynamicScene/GeometryVisualizer.js b/Source/DynamicScene/GeometryVisualizer.js index 7c96d28ae13c..0ab06db8ff1f 100644 --- a/Source/DynamicScene/GeometryVisualizer.js +++ b/Source/DynamicScene/GeometryVisualizer.js @@ -189,9 +189,12 @@ define(['../Core/AssociativeArray', * @param {JulianDate} time The time to update to. */ GeometryVisualizer.prototype.update = function(time) { + //>>includeStart('debug', pragmas.debug); if (!defined(time)) { - throw new DeveloperError('time is requied.'); + throw new DeveloperError('time is required.'); } + //>>includeEnd('debug'); + var addedObjects = this._addedObjects; var added = addedObjects.values;