import Cartesian2 from "../Core/Cartesian2.js";
|
import Cartesian3 from "../Core/Cartesian3.js";
|
import Check from "../Core/Check.js";
|
import defaultValue from "../Core/defaultValue.js";
|
import defined from "../Core/defined.js";
|
|
/**
|
* A cumulus cloud billboard positioned in the 3D scene, that is created and rendered using a {@link CloudCollection}.
|
* A cloud is created and its initial properties are set by calling {@link CloudCollection#add}.
|
* and {@link CloudCollection#remove}.
|
* <br /><br />
|
* <div align='center'>
|
* <img src='Images/CumulusCloud.png' width='400' height='300' /><br />
|
* Example cumulus clouds
|
* </div>
|
* @alias CumulusCloud
|
*
|
* @performance Similar to {@link Billboard}, reading a property, e.g., {@link CumulusCloud#show},
|
* takes constant time. Assigning to a property is constant time but results in
|
* CPU to GPU traffic when {@link CloudCollection#update} is called. The per-cloud traffic is
|
* the same regardless of how many properties were updated. If most clouds in a collection need to be
|
* updated, it may be more efficient to clear the collection with {@link CloudCollection#removeAll}
|
* and add new clouds instead of modifying each one.
|
*
|
* @see CloudCollection
|
* @see CloudCollection#add
|
*
|
* @internalConstructor
|
* @class
|
*
|
* @demo {@link https://sandcastle.cesium.com/index.html?src=Cloud%20Parameters.html|Cesium Sandcastle Cloud Parameters Demo}
|
*/
|
function CumulusCloud(options, cloudCollection) {
|
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
|
this._show = defaultValue(options.show, true);
|
|
this._position = Cartesian3.clone(
|
defaultValue(options.position, Cartesian3.ZERO)
|
);
|
|
if (!defined(options.scale) && defined(options.maximumSize)) {
|
this._maximumSize = Cartesian3.clone(options.maximumSize);
|
this._scale = new Cartesian2(this._maximumSize.x, this._maximumSize.y);
|
} else {
|
this._scale = Cartesian2.clone(
|
defaultValue(options.scale, new Cartesian2(20.0, 12.0))
|
);
|
|
var defaultMaxSize = new Cartesian3(
|
this._scale.x,
|
this._scale.y,
|
Math.min(this._scale.x, this._scale.y) / 1.5
|
);
|
this._maximumSize = Cartesian3.clone(
|
defaultValue(options.maximumSize, defaultMaxSize)
|
);
|
}
|
|
this._slice = defaultValue(options.slice, -1.0);
|
|
this._brightness = defaultValue(options.brightness, 1.0);
|
this._cloudCollection = cloudCollection;
|
this._index = -1; // Used by CloudCollection
|
}
|
|
var SHOW_INDEX = (CumulusCloud.SHOW_INDEX = 0);
|
var POSITION_INDEX = (CumulusCloud.POSITION_INDEX = 1);
|
var SCALE_INDEX = (CumulusCloud.SCALE_INDEX = 2);
|
var MAXIMUM_SIZE_INDEX = (CumulusCloud.MAXIMUM_SIZE_INDEX = 3);
|
var SLICE_INDEX = (CumulusCloud.SLICE_INDEX = 4);
|
var BRIGHTNESS_INDEX = (CumulusCloud.BRIGHTNESS_INDEX = 5);
|
CumulusCloud.NUMBER_OF_PROPERTIES = 6;
|
|
function makeDirty(cloud, propertyChanged) {
|
var cloudCollection = cloud._cloudCollection;
|
if (defined(cloudCollection)) {
|
cloudCollection._updateCloud(cloud, propertyChanged);
|
cloud._dirty = true;
|
}
|
}
|
|
Object.defineProperties(CumulusCloud.prototype, {
|
/**
|
* Determines if this cumulus cloud will be shown. Use this to hide or show a cloud, instead
|
* of removing it and re-adding it to the collection.
|
* @memberof CumulusCloud.prototype
|
* @type {Boolean}
|
* @default true
|
*/
|
show: {
|
get: function () {
|
return this._show;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug);
|
Check.typeOf.bool("value", value);
|
//>>includeEnd('debug');
|
|
if (this._show !== value) {
|
this._show = value;
|
makeDirty(this, SHOW_INDEX);
|
}
|
},
|
},
|
|
/**
|
* Gets or sets the Cartesian position of this cumulus cloud.
|
* @memberof CumulusCloud.prototype
|
* @type {Cartesian3}
|
*/
|
position: {
|
get: function () {
|
return this._position;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug)
|
Check.typeOf.object("value", value);
|
//>>includeEnd('debug');
|
|
var position = this._position;
|
if (!Cartesian3.equals(position, value)) {
|
Cartesian3.clone(value, position);
|
makeDirty(this, POSITION_INDEX);
|
}
|
},
|
},
|
|
/**
|
* <p>Gets or sets the scale of the cumulus cloud billboard in meters.
|
* The <code>scale</code> property will affect the size of the billboard,
|
* but not the cloud's actual appearance.</p>
|
* <div align='center'>
|
* <table border='0' cellpadding='5'><tr>
|
* <td align='center'>
|
* <code>cloud.scale = new Cesium.Cartesian2(12, 8);</code><br/>
|
* <img src='Images/CumulusCloud.scalex12y8.png' width='250' height='158' />
|
* </td>
|
* <td align='center'>
|
* <code>cloud.scale = new Cesium.Cartesian2(24, 10);</code><br/>
|
* <img src='Images/CumulusCloud.scalex24y10.png' width='250' height='158' />
|
* </td>
|
* </tr></table>
|
* </div>
|
*
|
* <p>To modify the cloud's appearance, modify its <code>maximumSize</code>
|
* and <code>slice</code> properties.</p>
|
* @memberof CumulusCloud.prototype
|
* @type {Cartesian2}
|
*
|
* @see CumulusCloud#maximumSize
|
* @see CumulusCloud#slice
|
*/
|
scale: {
|
get: function () {
|
return this._scale;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug)
|
Check.typeOf.object("value", value);
|
//>>includeEnd('debug');
|
|
var scale = this._scale;
|
if (!Cartesian2.equals(scale, value)) {
|
Cartesian2.clone(value, scale);
|
makeDirty(this, SCALE_INDEX);
|
}
|
},
|
},
|
|
/**
|
* <p>Gets or sets the maximum size of the cumulus cloud rendered on the billboard.
|
* This defines a maximum ellipsoid volume that the cloud can appear in.
|
* Rather than guaranteeing a specific size, this specifies a boundary for the
|
* cloud to appear in, and changing it can affect the shape of the cloud.</p>
|
* <p>Changing the z-value of <code>maximumSize</code> has the most dramatic effect
|
* on the cloud's appearance because it changes the depth of the cloud, and thus the
|
* positions at which the cloud-shaping texture is sampled.</p>
|
* <div align='center'>
|
* <table border='0' cellpadding='5'>
|
* <tr>
|
* <td align='center'>
|
* <code>cloud.maximumSize = new Cesium.Cartesian3(14, 9, 10);</code><br/>
|
* <img src='Images/CumulusCloud.maximumSizex14y9z10.png' width='250' height='158' />
|
* </td>
|
* <td align='center'>
|
* <code>cloud.maximumSize.x = 25;</code><br/>
|
* <img src='Images/CumulusCloud.maximumSizex25.png' width='250' height='158' />
|
* </td>
|
* </tr>
|
* <tr>
|
* <td align='center'>
|
* <code>cloud.maximumSize.y = 5;</code><br/>
|
* <img src='Images/CumulusCloud.maximumSizey5.png' width='250' height='158' />
|
* </td>
|
* <td align='center'>
|
* <code>cloud.maximumSize.z = 17;</code><br/>
|
* <img src='Images/CumulusCloud.maximumSizez17.png' width='250' height='158' />
|
* </td>
|
* </tr>
|
* </table>
|
* </div>
|
*
|
* <p>To modify the billboard's actual size, modify the cloud's <code>scale</code> property.</p>
|
* @memberof CumulusCloud.prototype
|
* @type {Cartesian3}
|
*
|
* @see CumulusCloud#scale
|
*/
|
maximumSize: {
|
get: function () {
|
return this._maximumSize;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug)
|
Check.typeOf.object("value", value);
|
//>>includeEnd('debug');
|
|
var maximumSize = this._maximumSize;
|
if (!Cartesian3.equals(maximumSize, value)) {
|
Cartesian3.clone(value, maximumSize);
|
makeDirty(this, MAXIMUM_SIZE_INDEX);
|
}
|
},
|
},
|
|
/**
|
* <p>Gets or sets the "slice" of the cloud that is rendered on the billboard, i.e.
|
* the specific cross-section of the cloud chosen for the billboard's appearance.
|
* Given a value between 0 and 1, the slice specifies how deeply into the cloud
|
* to intersect based on its maximum size in the z-direction.</p>
|
* <div align='center'>
|
* <table border='0' cellpadding='5'><tr>
|
* <td align='center'><code>cloud.slice = 0.32;</code><br/><img src='Images/CumulusCloud.slice0.32.png' width='250' height='158' /></td>
|
* <td align='center'><code>cloud.slice = 0.5;</code><br/><img src='Images/CumulusCloud.slice0.5.png' width='250' height='158' /></td>
|
* <td align='center'><code>cloud.slice = 0.6;</code><br/><img src='Images/CumulusCloud.slice0.6.png' width='250' height='158' /></td>
|
* </tr></table>
|
* </div>
|
*
|
* <br />
|
* <p>Due to the nature in which this slice is calculated,
|
* values below <code>0.2</code> may result in cross-sections that are too small,
|
* and the edge of the ellipsoid will be visible. Similarly, values above <code>0.7</code>
|
* will cause the cloud to appear smaller. Values outside the range <code>[0.1, 0.9]</code>
|
* should be avoided entirely because they do not produce desirable results.</p>
|
*
|
* <div align='center'>
|
* <table border='0' cellpadding='5'><tr>
|
* <td align='center'><code>cloud.slice = 0.08;</code><br/><img src='Images/CumulusCloud.slice0.08.png' width='250' height='158' /></td>
|
* <td align='center'><code>cloud.slice = 0.8;</code><br/><img src='Images/CumulusCloud.slice0.8.png' width='250' height='158' /></td>
|
* </tr></table>
|
* </div>
|
*
|
* <p>If <code>slice</code> is set to a negative number, the cloud will not render a cross-section.
|
* Instead, it will render the outside of the ellipsoid that is visible. For clouds with
|
* small values of `maximumSize.z`, this can produce good-looking results, but for larger
|
* clouds, this can result in a cloud that is undesirably warped to the ellipsoid volume.</p>
|
*
|
* <div align='center'>
|
* <table border='0' cellpadding='5'><tr>
|
* <td align='center'>
|
* <code>cloud.slice = -1.0;<br/>cloud.maximumSize.z = 18;</code><br/>
|
* <img src='Images/CumulusCloud.slice-1z18.png' width='250' height='158' />
|
* </td>
|
* <td align='center'>
|
* <code>cloud.slice = -1.0;<br/>cloud.maximumSize.z = 30;</code><br/>
|
* <img src='Images/CumulusCloud.slice-1z30.png' width='250' height='158' /></td>
|
* </tr></table>
|
* </div>
|
*
|
* @memberof CumulusCloud.prototype
|
* @type {Number}
|
* @default -1.0
|
*/
|
slice: {
|
get: function () {
|
return this._slice;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug)
|
Check.typeOf.number("value", value);
|
//>>includeEnd('debug');
|
|
var slice = this._slice;
|
if (slice !== value) {
|
this._slice = value;
|
makeDirty(this, SLICE_INDEX);
|
}
|
},
|
},
|
|
/**
|
* Gets or sets the brightness of the cloud. This can be used to give clouds
|
* a darker, grayer appearance.
|
* <br /><br />
|
* <div align='center'>
|
* <table border='0' cellpadding='5'><tr>
|
* <td align='center'><code>cloud.brightness = 1.0;</code><br/><img src='Images/CumulusCloud.brightness1.png' width='250' height='158' /></td>
|
* <td align='center'><code>cloud.brightness = 0.6;</code><br/><img src='Images/CumulusCloud.brightness0.6.png' width='250' height='158' /></td>
|
* <td align='center'><code>cloud.brightness = 0.0;</code><br/><img src='Images/CumulusCloud.brightness0.png' width='250' height='158' /></td>
|
* </tr></table>
|
* </div>
|
* @memberof CumulusCloud.prototype
|
* @type {Number}
|
* @default 1.0
|
*/
|
brightness: {
|
get: function () {
|
return this._brightness;
|
},
|
set: function (value) {
|
//>>includeStart('debug', pragmas.debug)
|
Check.typeOf.number("value", value);
|
//>>includeEnd('debug');
|
|
var brightness = this._brightness;
|
if (brightness !== value) {
|
this._brightness = value;
|
makeDirty(this, BRIGHTNESS_INDEX);
|
}
|
},
|
},
|
});
|
|
CumulusCloud.prototype._destroy = function () {
|
this._cloudCollection = undefined;
|
};
|
|
export default CumulusCloud;
|